Here is my BluePrint set up for an Angry Birds Style launching mechanism, I would say it is about 90% done, it just needs a few little things improved/added to it. I have tried to lay the BluePrint out as organized as I can, and have collapsed several sections into Functions to make things a bit easier to lay out and keep organized. I made this in Paper2D, but it should be applicable to a 3D game as well.
First we have the Viewport of the BluePrint. (Viewport.jpg)
I have a projectile (Cone_Sprite), a PhysicsConstraint, a hidden sprite (Dot) that I use as an anchor point and a Box Collison (Box) that I use to make âgrabbingâ the projectile easier. For the PhysicsConstraint it is set up to constrain my projectile (Cone_Sprite) and my anchor point (Box), the anchor point is right under the PhysicsConstraint, and cannot be seen from the ViewPort, it is also hidden in game. For PhysicsConstraint, the important settings are to make sure you have soft constraint enabled, make sure that your anchor point is the first object listed in the PhysicsConstraint (you will have to manually enter the names of the two objects) and make sure you have X/ZMotion set to Limited and YMotion set to locked (assuming you are making a game where X is left to right and Z is up and down). For your projectile, make sure that physics is enabled, gravity is disabled, and the sleep family is set to sensitve. For your BoxCollison (or Circle depending on the shape of your projectile), make sure that it is set to generate hit events, and make sure that you scale it down along the Y axis, and pull it a bit forward in Y space, so that it is not colliding with your projectile. FOr your anchor point, make sure collison is enabled, and it is hidden in game, or you could keep it as a visual cue of what angle your shot is going to launch.
Now to the BluePrint (LauncherBP.jpg)
What sets the whole BluePrint off is the On Input Touch Begin, to get this we select our Box Collison (Box) and scroll down in the details panel to events, and click on On Input Touch Begin, this will bring up the On Input Touch Begin even in your Event Graph, and you can start building the BluePrint. From this event, we will trigger a Sequence, which we will then use to open two different Gates, which I have labeled in the BluePrint picture. Gate 1 is used to set the location of our projectile, and gate 2 is used to launch our projectile, so letâs focus on Gate 1 for now.
Weâll need an âEvent Tickâ and the âMovedâ execution from our âInput Touchâ, with both Execution wires going into the Enter input of Gate 1. The reason we use the âEvent Tickâ as well as the âInput Touchâ, is because if we only use the Moved Execution from our âInput Touchâ to set the location of our Projectile, as soon as the player stops moving their finger, the âPhysicsConstraintâ will start pulling the projectile back to the anchor point, which we donât want. With our two execution wires entering our gate, we will now set the position of our projectile, so lets take a look at our first macro we will set up, which will give us the location that our player is touching on the screen. We need to create a Macro with an âETouch Indexâ input, and a âPositionâ output, save the Macro as Finger_To_Vector, and open up your new Macro.
Finger_To_Vector Macro (FingerToVector.jpg)
Inside of our new Finger_To_Vector Macro we need to set up a few things. First we drag a wire off of our input, which should now be called Finger Index, and connect that to the âFinger Indexâ input of our âGet Hit Result Under Finger By Channelâ node. On our Get Hit Reuslts node, we also need to set the target to our Player Controller, so create a âGet Player Controllerâ node and drag a wire from its return to the âTargetâ input of our Get Hit Reusults node. Now we need to get the position information out of our hit results, so we will drag a wire from the âHit Resultâ output to a âBreak Hit Resultâ node, this will take all of the information from the hit result, and allow us to get the information that we need, which is the position. From the âPositionâ output of our âBreak Hitâ node, we drag a wire off and conect it to a âBreak Vectorâ. This will split the position information into 3 seperate float values for each axis, the reason we want to do this, is so that we can insure that our finger position will never return anything other than a value of 0 for the Y axis (as is, it never does, but if I were to change the camera, I am unsure if that would still be true, and this just let me know for sure). From our âBreak Vectorâ node, we create a âMake Vectorâ node that we connect the X and Z wire to, but not the Y, and we make sure to set the Y value to 0, or whatever value you want your projectile to be in Y space. We connect the output of our Make Vector to our output, and our Macro is ready to go. Back in our BluePrint we attach a wire from the âFinger Indexâ output of the Input Touch node to our the âFinger Indexâ input of our Finger_To_Vector Macro.
We are almost ready to set the location of our projectile, but we need to do one more thing first. As you will notice, before the âSetRelativeLocationâ node, I have a âBranchâ, the reason for this, is that while testing with a print string connected to my position output, I noticed that occsionaly it would return a value of 0,0,0 when I let go of the mouse button, and this was no good, as it would move the projectile to the middle of the screen, and completely throw off what we are trying to do. To remedy this issue we simply attach our âPositionâ output from our Finger_To_Vector Macro, and connect that to a âGet Vector Lengthâ node. From here we create an âEqual (Float)â node that we connect our âGet Vector Lengthâ node to, in the A input (the top one), we set the value of B as 0, and then connect the boolean output (red wire) from our âEqual (Float)â node to a Branch. We donât do anything with the âTrueâ output of our âBranchâ as when the location is 0,0,0 we donât want to set the location of our projectile, as that would mess everything up. So, we pull a wire off of the âFalseâ output of our âBranchâ and plug that into the execution input of a âSet Relative Locationâ node. Now we take another wire off of the âPositionâ output of our Finger_To_Vector Macro, and connect that to the position input of the âSet Relative Locationâ node. Finally, we need to tell the âSet Relative Locationâ node what object it needs to set the location of, so we grab the projectile (Cone_Sprite) from our component panel, and drag it into our BluePrint, and connect its output to the âTargetâ input of our âSet Relative Locationâ node. If we save our BluePrint and launch our game in the editor, we should now be able to grab our projectile and move it around with our mouse, assuming you have dragged the launcher BluePrint into the level. Now we will handle the release of our projectile.
Time to launch our projectile into the world!
We need to pull a wire off of the âReleasedâ output of our âInput Touchâ node, and connect it to the âEnterâ input of Gate 2, from the âExitâ output of Gate 2, we will create a âSequenceâ with 3 outputs, we will use these to trigger the launch, and close our âGatesâ. The first and third outputs from Gate 2 are used to close Gate 1 and Gate 2, the middle output is where the fun happens, and where we get to make a new Macro. Create a new Macro with an execution input and output, name it Launch_Projectile, save it, and open up your new Macro.
The Launch. (Launch_Projectile.jpg)
This part is pretty simple and straight forward (I have a sound effect in the picture, but you donât need to have one to make it work, but this would be a godo place in the blueprint to place it). From our Macro input we drag a wire and connect to a âDelayâ which we will set at 0.1 (you can play around with this and the âstiffnessâ value in your Physics Constraint to get a good result depending on the size of your projectile and its mass). From our delay we connect to a âBreak Constraintâ node, for this node we will need to drag our Physics Constraint into the BluePrint and connect a wire from itâs output to the âTargetâ input of the âBreak Constraintâ node. Next we need to enable gravity on our projectile, so we create a âSet Enable Gravity Nodeâ which we will also need to provide a target, so we drag in our projectile and use that as the target, now we can connect the output of the âSet Enable Gravityâ node to the Macro output and contiune to our next step (We disable gravity by default on our projectile, because if we donât it will fall and swing under the anchor point when we load the level). But if we save and launch our game, we should be able to grab our projectile, pull it back, release it, and watch it fly.
Post Launch actions.
After we launch our projectile, we need to do a few things, like be able to launch another projectile. So next we shall cover that, and our Angry Birds style projectile launcher will be done!
Instead of spawning a new projectile and attaching it to the Physics Constraint, I figured it would be easier to just spawn a replacement projectile, destory the original launcher BluePrint, then spawn a new launcher BluePrint, so we will go over how to do that. First we are going to need to create a copy of our projectile, and then make a new BluePrint from it. Next we go back to our launcher BluePrint and put a âDelayâ (how long you want to set the delay is up to you, if you wanted you could even just skip it, but I want to give the projectile a bit of time to interact with the level before I spawn a new one) after our Launch_Projectile Macro, after the delay we will create a âSpawn Actor From Classâ node, in that node, from the drop down menu we will select the BluePrint that we made with our duplicated projectile. Now we need to tell that node where to spawn the replacement projectile, which brings us to our third Macro. We will create a new Macro, name it Projectile_Replacement_Transform give it a âTransformâ output, save it and open it up.
Projectile Replacement Transform (Replacement.jpg)
This one is pretty simple, we just drag our projectile in, from it drag off a wire and create a âGet World Positionâ node. From that we will create a âBreak Vectorâ node and a âMake Vectorâ node. We will connect the output of our 'Get World Position node to our âBreak Vectorâ node, then attach the âPositionâ and âRotationâ outputs of the âBreak Vectorâ into the âMake Vectorâ. The reason we do this, is because the projectile will often be too big or too small if we just use the transform information that we get from the âGet World Positionâ node, this allows us to make sure our replacement projectile spawns at the correct size, you will probably need to play arouund with the scale value to get it right. From our âMake Vectorâ node, we drag a wire to the output of our Macro, and weâre good to go. Back in our BluePrint we will connect the output of our Replacement_Projectile_Transform node to the âPositionâ input of our Spawn Actor From Class node, now our replacement projectile will spawn in the correct location, and at the correct size!
Setting the Velocity of our reaplacement projectile (Velocity.jpg)
Next we need to set the Linear and Angular Velocity of our replacement projectile so that the new projectil will contiue the same path and rotation that the original projectile was on, which brings us to our final Macro. Create a new Macro named Clone_Velocity give it an execution input and ouutput, and also an input that is a refrence to your replacement projectile (to do this, click on the create new input button and type the name of the BluePrint of your replacement projectile, it should now be a blue colored input) save your Macro and open it up.
This part is pretty straight forward. From the execution output of the Macro input, connect in order, a âGet Physics Linear Velocityâ, âGet Physics Angular Velocityâ, âSet Physics Linear Velocityâ and âSet Physics Angular Velocityâ. Next we will connect the return values of the Get Linear and Angular Velocities, and connect them to the Set Linear and Angular velocities inputs, respectivly. Now we drag our original projectile from our BluePrint in and connect its output to the âTargetâ input of the âGetâ nodes, then we drag a wire off of the refrence output of our Macro input (blue wire) and type in the name of our duplicated projectile, and connect the output of that to the âTargetâ input of our âSetâ nodes. Next we connect the last Get node to our Macro output, save and go back to our main BluePrint, where we will connect the blue output of our Spawn Actor From Class to the blue input of our Clone_Velocity, you may need to do this first before you are able to get a refrence to your duplicate projectile.
Now we just need to destory our original launcher and spawn a new one. This is pretty easy. We attach a Destroy Actor node to our Clone_Velocity Macro, then a another Spawn Actor From Class node. On our final Spawn Actor From Class node, we will set the actor to our Current Launcher, and for orange âSpawn Transformâ input, we will right click it, promote it to a variable, and copy/paste the transformation of our original Launcher that we placed in the level, so that our new launcher spawns in the exact same spot. Weâre done!
Iâm sure I forgot a few things, and I will update the post to reflect that when I think of what I forgot. If you have any questions or issues, let me know and I will do my best to help you out.
Now for what I want to change about my launching mechanism.
Smooth out touch input. Iâm guessing as a consequence of trying to figure out a one pixel location from a finger press that covers what Iâm guessing is a lot more than a one square pixel area on my screen, sometimes I will notice my projectile kind of moving back and forth rapidly between two close points. Iâm hoping there is a way to sort of smooth that out.
Proper Rotation on my projectile. Due to how I have the Physics Constraint set up, it usually does a pretty good job, but since my projectile is longer and more like an arrow, it is important that before launch, it is rotated to always be facing the anchor point, as it is now, itâs pretty close, but if I move it around a bunch it will start to sway and get way off rotation.
Circular Constraint. Iâm guessing this is a setting in the Physics Constraint, but I want to be able to have a set distance that you can pull back your projectile, as it is now you can pull it back as far as you have screen space, but I want something like Angry Birds, where you can only pull it back so far. I though about just using a clamp, but then Iâd have a square shaped area where you could pull the projectile back, and as a consequence, certain angles would be able to generate more velocity than other, plus it would just look ugly, and make aiming more difficult.
Disable Collision on the projectile before launch. As it is right now, I am unable to get the Physics Constraint to work unless both constrained object have collision enabled. My issue is that occasionally the new projectile will spawn while there are still things moving around in the level, and sometimes they will collide with my new projectile, causing it to swing around.
Other than that I am pretty happy with this launching mechanism. Iâm hoping that some people get some good use out of this, as I have been unable to find any sort of tutorials on making a true Angry Birds style launching mechanism, and Iâm also hoping some people have some ideas to help me address the few small issues I am having. Also Iâm sure I forgot some stuff, and I will be sure to edit the OP when I find my mistakes.