Making a ballistic missile
- 1 Introduction
- 2 Explanation
- 3 Setting Up
- 4 Building the missile silo
- 5 Building the targeting station
- 6 Building the missile
- 7 Building the explosion actor
- 8 Wrapping up
Xanjis here this tutorial will teach you how to make a ballistic missile that can strike anywhere on the surface of an ark.(Note works badly on aberration I wonder why) The models for the missile silo and the missile itself were made by one our resident 3d modelers pleasure and you can download them at the sources part of this tutorial cheers!
This ballistic missile will have several components.
The first component is the missile silo. The silo will allow you to craft ballistic missiles and then fire them. The silo will have an inventory component where you can craft a missile and a button where you can launch the missile.
The second component is the ballistic missile. The missile will be a moving actor that allows up to four passengers and it will have a launch phase, an ascent phase, a level out phase, a descent phase, and finally a terminal phase where if the missile touches anything it explodes. The ballistic missile cannot be shot down or stopped.
The third component is a locator structure. This structure will act as a target for the ballistic missile and a tribe may only have a single one placed on the map at one time.
The final component is an explosion actor. The missile itself will be able to be seen anywhere on the map however, the destruction of structures,dinos,players,and foliage uses up large amount of processing power so we make a second local actor that manages the destruction so only near by players will have to process the damage.
This project will include many different blueprints that will work concurrently so to start with we will create all the actors and fill out their defaults and logic one at a time. To start with make a copy of the smithy and call it Structure_MissileLauncher or something similar. We also need to make a primal structure called "BallisticMissileTarget" this will be our target structure. Then create a primal inventory component called Inventory_MissileLauncher. Next create two generic actors, one called "Ballistic Missile" and the other called "ExplosionActor". Finally create a decal actor and call it "radiation decal". We also need one generic primal item that will be our actual ballistic missile and two primal item structures.
For any mod you also need primal game data which you can learn about in the ark mod community manager tutorials located in a playlist here.
Building the missile silo
Redwarf already goes over the purposes of the item settings in his tutorial here. https://wiki.arkmodding.net/index.php?title=Tutorial:_Solar_Panel#Setup_the_Primal_Items. Here are the settings I changed for reference.
The missile silo item defaults
For this part of the tutorial we will be altering the copy of the smithy that we created earlier in the tutorial.
- Static mesh: Set this to your missile silo static mesh
- Blueprint multi use entries: set this to true so that we can add custom multi use entries to this structure for our launch command
Making the Multi use entry
First go into the event graph and search for multi use in the search bar on the left. Then right click BPgetmultiuseentries and implement function then do the same for BPtry multi use. This will add the two multi use functions we will be working in.
Next go into the BPGet multi use entries graph and right click the multi use entries array output on the input of the function and promote to variable. Name the variable to local multi use. This variable will store our single multi use entry and then output it from the function. Create a make multi use entry. Set use string to "launch missile". Expand the node by clicking the down arrow and set display on inventory UI to true. This will add a button to the inventory component that lets you launch will still in the inventory. Set the use index to any number above 10,000. Keep note of this number since it will be used later. Get your local multi use variable drag off of it and make an add node then connect your make multi use node output to this add node. Link all the execution wires up together and make another get local multi use variable that connects to the output of the function.
Finally go to your BPtry multi use graph and drag off use index and create a switch on int. Make the start index for your switch the number you choose for your make multi use entry and add a single pin. Make that single pin execute your launch missile event and wire up the function. Some people like to add a force net update before the function ends to insure both the client and server are synced after the multi use is executed.
For fun make a second multi use entry called "ride missile" and have that run a add passenger event with a shooter character parameter in the ballistic missile blueprint.
Setting up the event graph
Creating the events
To begin with the event graph you need to create three custom events(search custom event in the blueprint browser) named missile slotted, missile removed, and launch missile.(Note these can be whatever you want but I'm specifying the names for consistency in the tutorial). All three events will be reliable. Missile slotted and missile removed as their names imply will handle all the changes the launcher makes when a missile is ready in the launch vs when it's not. Therefore these two events are multicast because they will be both controlling client changes like particle effects and server effects like spawning a rocket actor when a missile is slotted. Missile launch however will run lots of logic but all the client side stuff that happens like noises are going to be taken care of the rocket itself. The missile launch event will only have to deal with the logic required for a missile launch and not it's client consequence thus it is a server side only event.
Creating the variables
The next step is to create two variables that will be used in the event graph. The first variable is a boolean called "ismissileslotted?" and the second variable is a object variable of the ballistic missile we made in setting up named "Missile". The local multiuse is also a variable but it will not be used in the event graph.
We will now begin filling out the events. The first event we will fill out is the "missile removed" event. This event will be fired from the inventory component whenever there is no available missile items in the missile silo. So the event will start by setting the "missileslotted" variable to false and then get a reference to our "Missile" variable and destroying that actor. Finally set the value of "Missile" to none.
Next up is the missile slotted event. First we check if our missileslotted variable is true already and do nothing if it is. Second we set the "missileslotted" variable to true then we check if the "missile" variable is valid, if it is we already have a missile slotted thus we do nothing. If there isn't a value for "missile" or the value is broken we spawn a new missile from the launcher location + offset and set that to the new value of "missile". If we have any particle effects,sounds, or material changes for when a missile is slotted we would have those run on this event after the missile is spawned.
Before we start the final event for the missile launcher we need to add an empty event to the ballistic missile actor called launch so we can complete the launcher in one go. So when the launcher launch event is called first we triple check that there is in fact a ballistic missile in the launcher at the moment because redundancy.(Adding a "no missile available" error message would be a cool idea for the false execution pin) If there is a ballistic missile available we delay a couple seconds then tell our missile reference to run it's own launch event where the real meat of the missile will be at.
Next up we set the missile reference variable to none because after the missile is launched the missile and the launcher no longer need to care about each other. Then we get the first stack of ballistic missiles in our silo inventory and decrement it so you can't just keep shooting the same ballistic missile in the air.(All these item nodes are the biggest reason we have this event set to server only). Next we set the missile slotted boolean to true so you can't fire another missile immediately(I blew myself up alot before I added this part :( )
We delay 5 seconds next up then set the missile slotted variable to false so we can finally launch another missile. Finally we see if there is another missile available in the inventory and set the launcher to slotted if there is.
The inventory component
Red-dwarf also goes over how to set up a simple inventory component in his tutorial so I will just post the settings I used personally.
On the event added we will check if the item is our ballistic missile item and if it is just to make doubly sure we make sure the amount ballistic missiles in the inventory is greater than 0. If there are ballistic missiles in the inventory we get the owner which is just the actor that "owns" the inventory component and tell it to slot a missile.
On the event removed we will again check if the item is a ballistic missile and if it is we make sure that there isn't more then 0 ballistic missiles in the inventory and if there aren't get the owner and remove it's missile.
Now whenever we craft or add ballistic missiles the structure responds appropriately by turning on or turning off effects and adding or removing the ballistic missiles actor.
Building the targeting station
This is likely going to be the easiest part of the tutorial. By the time you get to this section of the tutorial we already have created a primal structure item and a primal structure so we will skip that part and go straight into the nitty gritty coding. I was originally going to have only one of these target structures per tribe however I thought of an even better idea only having one of these structures on the map period. I'll leave it to the imagination for what kind of sneaky things you can do with that mechanic.
Building the targeting station event graph
So for the blueprint on begin play we will have a .2 second delay to avoid a common bug that occurs when structures update too quickly after being placed. Next we check the "IsPreviewStructure" boolean to make sure this is the placed version and not the ghostly pre-placement version of the structure. Then we get all actors of class with itself being the class in this case whatever you named it. Next we do a for each loop with a break and destroy the first version of this actor that isn't itself that it can find. I would recommend instead using a reverse for each loop to get rid of all versions of this structure to take care of edge cases that may or may not exist(even if the system itself is solid other bugs in the system could somehow cause there to be more then one of this structure perhaps due to lag or clever players) but for a prototype version just getting rid of the first one it finds is enough.
Building the missile
The biggest part of this tutorial. For the missile actor itself I will be relying heavily on the timeline node which is sort of like a compact event tick that only runs on tick for a certain amount of time which is far more efficient than having an actor do something every single tick all the time. This tutorial is already extremely long so I will just link to the official documentation as timelines really haven't changed all that much between different versions of unreal 4. https://docs.unrealengine.com/en-us/Engine/Blueprints/UserGuide/Timelines
Our missile need a total of 4 components a root static mesh, a particle effect and a sound attached to the root. Then we also need a projectile movement component to handle all those nasty math equations involved in physics that we really don't want to reinvent.
The audio is just a deeper sounding flamethrower sound and with a massive attenuation so you can hear it ANYWHERE on the map when the rocket is in flight. We just set it's audio to 0 before we actually launch the rocket from the silo.
The particle effect is just the flamethrower particle effect color shifted from a orange reddish color to a nice blue green color to make it look cool. We also set its visibility to false in it's settings.
In the static mesh components we just need to set the collision to no collision(so it doesn't immediately blow up in the launcher).
Finally despite it seeming complicated we just need to jack the max speed in the projectile movement component to whatever you want the speed ceiling for the rocket to be, set the velocity to 0(the vector velocity not the float singular velocity) so it doesn't move about in the silo, and set it's projectile gravity scale to 0 for the same reasons.
- Replicates: True (So the missile exists on both the client and server)
- Prevent actor stasis: True (A just in case setting so the missile doesn't some how freeze in mid air on it's journey across the map)
- Always relevant: True(This is a very dangerous setting that disables the normal tendency for stuff like building to disappear as you get far enough from it. We can't have that on a cruise missile that will be streaking across the sky for obvious reasons)
Target Vector(Vector): The value of this variable is the location in world space of the missile target we want our missile to hit. Target Velocity(Vector): This is a temp variable that will be occasionally used in the guts of the blueprint. Is launched(Boolean): A check just to make sure the missile has actually launched if it touches something(Not really necessary at this point since I moved from using this boolean to just disabling collision entirely until the missile is in the air) Player(Shooter charector): Whoever is currently riding the missile
All these events will be reliable and multicast.
Launch, Ascend, Level out, Travel, AddPassenger, MovePlayer
We also need a function called GetNeededVelocity which will be a helper function full of fancy math that I made two weeks and now I don't even understand any more.
Our first event is the empty launch event we created earlier which we will now set to multicast and reliable. Then we get all the actors of our missile target structure class and if there is any that exist grab the first valid one and get it's location and set that as our target vector.(Now that I think about it the missile will never hit the same target due to bugs because the missile will blow up the target)
Next up is some housekeeping we set the visibility of our particle effect to true and we set the audio volume to 1 or so so that the missile looks like it's doing an ignition sequence before it launches. Then we call the ascend event(more on that soon) and wait 5 seconds before setting the collision to IgnoreOnlyPawn so it explodes when it touches stuff but it doesn't explode from touching it's passenger. We also set the gravity scale to 1 at this point although at the speeds we are going it won't matter and set is launched to true.
In our ascend event we will make a timeline called TM_Ascend(so creative right?) and have it be 5 seconds long, non looping, and have an exponential curve from 0-8000. Then we will set the velocity of our projectile movement component to the current value of the timeline. Thanks to the timeline our rockets vertical speed exponentially increases until our missile is high in the sky. Once the timeline is completed we call the level out event.
Get needed velocity function
As you can see this function is a mess that would be impossible to explain by text. Basically it's purpose is to create a velocity that takes us from point A to B but curbing the extremes so every 5000 unreal units causes the time it takes to reach the target to be 1 second longer. The outputs are the x and y velocity that we need to reach the target vector as well as the expected time it should take to reach that vector.
This events purpose is to slowly adjust our rocket from a completely vertical velocity to a horizontal one facing towards the target vector. The timeline is just a simple linear curve(a straight line) from 0 to 1 over 3 seconds. We take the value from the timeline take the value of 1 minus that number which gets us a proportion for how much influence the horizontal velocity should have on the rocket vs a vertical velocity so we gradually have that change instead of the rocket taking a massive right degree turn once it ends the ascent phase. The get needed velocity just gives us the horizontal velocity we need. Once our timeline is complete we then call the travel event.
Our missile is on it's merry way to it's target however there is a problem we don't know how long it will take to reach the target but remember our get needed velocity helper function? It gives us the predicated time to reach the target so we call that function and we can use the timeline as a component and set the timeline length to that predicted time. We also don't need to add anything at all to our timeline we can just use it as a convenient device to send an execution every tick for however long it takes to get to our target. So every tick we call our fancy get needed velocity function and just set our velocity to that. Once our timeline is finished and we are above the target remove the horizontal velocity and just give a massive negative vertical velocity so our missile dives straight towards whatever is below it. Now you may be thinking "didn't we go through a lot of trouble to make the transition from vertical to horizontal why are we just throwing that away here?". The reason being is because the level out phase in the beginning doesn't affect anything. However the descent part of the missile does because if we make the missile curve downwards instead of diving it is highly likely the missile will hit a structure or a mountain along the way. Thus I decided to sacrifice a little bit of elegance for a bit more function if you wish to make the opposite decision I'm perfectly fine with it but this is the compromise I personally made.
On component hit
Now for the explody part of our ballistic missile. First we need an on hit event to start with from our static mesh. Then we check our is launched variable and spawn the explosion actor at the current location and then destroy our ballistic missile. Pretty anticlimactic right? Actually all the pretty explody bits of our rocket is somewhere else. That brings us to the next step.
On end play
So you've likely seen the begin play event used quite a lot however many people forget about it's cousin the end play event. This event is called when the actor is about to be destroyed and we just destroyed it in the last event so it will now fire and as a bonus is will fire client as well so all our pretty effects can be seen. So off this event will play an explosion sound with a giant attenuation and then do a line trace straight down. This line trace will find the "ground" and then play a particle effect there. The reason I included this is so that the explosion particle is actually on the ground instead of in the air where the origin of the missile launcher disappeared at. We also spawn our radiation decal at this point from earlier.
Add passenger/Move Player
Now for the fun event. This just an event that takes a shooter character as an input and already is linked to our missile silo so all we have to do is fill it out. It will work very simply if the passenger variable reference is valid don't do anything if it isn't valid then set the input character as our player variable ref.
Then for our move player event we will call it every event tick because that's the only way to get a player to actually seem attached to a missile moving at 1000km. The event will set the rotation and the location of the player to the location and rotation of the missile plus whatever offset you want then grab our player ref's movement component and set it to none so at-least gravity stops trying to make our character depart from the rocket.
Building the explosion actor
- Replicates: True We set this to true for the same reasons as the missile actor.
A decal is an actor that uses a special material to apply textures to objects in the world. For this tutorial we will use a decal to make the area affected by the ballistic missile look irradiated. To start with create a material called "M_RadiationDecal". Next set the domain of the material to "DefferedDecal", this lets the material know it will be used for a decal and opens the material inputs needed for a decal.
The next step is to fill out the graph. We will have a texture sample node with our radiation texture. The output will go into the base color and the alpha will be multiplied by a exponential radial gradient node. This arrangment means as the texture gets closer to it's edges it becomes more translucent effectively turning a square texture into a circular one. The exponential radial gradient will have a constant .6 as it's radius to make the final product a smaller circle but you can set it to whatever suits your needs.
The next step is to create a blueprint of the type "DecalActor" with the decal material being the material we use in the blueprint. When the missile explodes it will spawn this decal.
The effect of the decal on a *previously* forested hill.
If you want to learn more about decals you visit the official documentation here https://docs.unrealengine.com/en-us/Resources/ContentExamples/Decals.
Setting up the event graph
This actor was originally supposed to hold all the explosion related stuff like the particle effects ect but I realized it would be cooler if you could see the explosion from anywhere on the map so this actor just contains all the functional destruction code.
Figuring out how to make rocks and trees get destroyed was an *interesting* process to say the least. Trees and rocks and various other foliage in ark are not separate actors in each sublevel(tiles of the map that are streamed in and out so you don't have to load the whole thing in at once) all the actors are part of a gargantuan actor with every single tree,bush,rock, and metal node being an actor component of this. This type of monster actor is a called and instanced static mesh actor with each foliage being an instance. The reason the devs opted to do foliage in this way is because it is the recommended way to do massive numbers of very simple actors which is definitely something that foliage benefits from. To cut to the case we need to be looking for a collision hit(where certain types of collision detecting nodes collide with something and have a bunch of data on that collision) and gathering the collision component from that hit instead of trying to find the actor since every single foliage is just going to tell you it's instanced static mesh component, singular. Which means we need to use a multi sphere trace to find the foliage because that gives us collision hits instead of just the actor(octree and find all actors of class will both give you just an actor not a "hit").
To start with we need to do a multi sphere trace from the current location of our explosion actor. The multi sphere trace is a line that sends out a bunch of spheres to detect stuff we only need one sphere but we also want multiple hits so the end location of the origin line of our sphere just needs to be our location + 1(for some reason giving it the same value so the line is just a point makes the whole thing break *shakes fist at unreal 4 devs*). The radius is just how big we want the explosion to be and the trace channel is "structure any" which I believe just means static not moving actors of which foliage fits the bill.
Then we do a for each loop of our array of hits grab the hit component which is the actual foliage actor instead of the big daddy foliage actor. We then cast our component to instanced static mesh instance and deal direct damage to it. I don't know why the deal direct damage requires a player controller instance but it won't work with out one so I just give it 0. We also route the hit body index from the hit to the direct damage node(another thing I really don't understand why we need to do it but again it doesn't work with out it even though I don't believe any foliage has multiple sub bodies). So this code now finds all the static components near it gets the actual component hit sees if its foliage or not and if it is it tries to break it.(Bushes seem immune to this so the nuclear apocalypse instead of glassing forests turns them into lush plains with radioactive green soil.
Compared to destroying foliage annihilating all the nearby creatures,players, and structures is fairly simple. We simply do a server octree(basically a cheap node to detect nearby objects that wc added to their version of unreal 4) for structures set a temp variable to it's output then do an octree for pawns(players and creatures are both pawns) and append that output array to our temp array. Finally we do a for each loop to apply damage to all of them (another case where you would probably want to use a reverse foreach loop to make edge cases like executions happening in the wrong order *shakes fist at wc server coding* resulting in some creatures/structures being skipped). I used get primary world to get the level for the octree just because in some cases the k2 get world node which should do the same thing occasionally causes bugs.
Since the decal is an actor we simply need to use the spawn actor from class node to spawn the decal at the current location of the explosion actor with an absolutely massive scale. A decal actor is invisible if there are not meshes nearby but it paints itself on meshes if they are within it's size so making it huge paints a massive area with it's decal material. Finally we destroy the explosion actor after it's performed it's role so as to not have our mod slowly eating unnecessary server ram after each nuke goes off. The decal actor is spawned a -90 degree angle because that is the default value for decals that spawns them so they are painted on the ground primarily. Edit: Instead of the explosion actor add this step to the end of the end play event in the ballistic missile event graph.
Missile Icon: https://openclipart.org/detail/82435/missile
Toxic decal texture: https://patterns-stock.deviantart.com/art/Toxic-waste-texture-149430437
Pleasure's missile/silo texture/fbx files: https://puu.sh/AsMEN/2affd712aa.zip
Rotated Missile that I used in my tutorial replace the one in the puush link: http://www.filedropper.com/untitled_77
Missile Silo Icon: http://www.filedropper.com/missilesilo
Using your own knowledge try to complete these challenges to improve your ballistic missile mod!
- Make the area that is nuked irradiated and have radiation cloud particles
- Make the missile's landing more graceful and realistic
- Add an anti-ballistic missile launcher to counter the ballistic missile
That's it everyone now you just need to set up some fancy explosion and exhaust sounds for your rocket, set up your PGD, add engrams, and of course find some way to balance this inherently unbalanced monstrosity you've created. If you encounter any bugs or issues feel free to contact me I would be happy to improve this tutorial anyway I can!