NEW Procedural Animation In Godot 4.0

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
With the removal of the SkeletonModificationStack from Godot 4.0 I’ve received a few requests to update my tutorial. In this video I’m going to show you how to create an improved procedurally animated spider bot that is fully controllable and can walk on rough terrain, walls and ceilings. The first step is to have a model that’s been rigged. I’m using this quick one I threw together in blender, If you want to follow along with the video, I’ll put a download link for the model in the description. Now in Godot, I’ve created a simple room in the main scene using CSG nodes. I’m now creating a new inherited scene from the blender model & updating the materials so it looks a little nicer. Now let's get the IK set up. As I mentioned in the intro, the SkeletonModificationStack was removed from 4.0. Either they’ll re-add an improved implementation in a later version, or we’ll get something new entirely. For now though we need to use the deprecated SkeletonIK3D node. Add 4 SkeletonIK3D nodes to the Skeleton node, one for each leg on our robot, and set up the chain. There’s a strange behaviour where only the bone before the tip bone will point at the target, but in our case we actually want the last bone in the chain to do that. To work around this I added an extra bone to the end of the bots legs in blender that has 0 weighting for mesh deformation and set that as our tip bone in Godot. The root bone is the third bone up from our tip. We also want to use a magnet force with the value set to 10 on the Y access to keep our legs pointing upwards. Set this up for each leg. Now let's set up 4 nodes to act as our IK targets. I’m using Markers to make them visible in the editor. Adjust their position until you’re happy with the default pose. We need to attach a script to our IK nodes to start the IK simulation when the game is started. We can add tool to this script so the IK runs in the editor too, which makes finding the right positions for the targets easier. Get the targets into a place you're happy with! At the moment if you move the scene's root node, the IK targets will move too. We can set the transform to top-level so they will ignore the parents' movement when the game is ready. Let’s add a script to our Robot so we can move around. Attach a script and at the top export two variables to hold move speed and turn speed. Then in _process lets get our input directions then translate & rotate accordingly. You may wonder why I’m using rotate_object_local, instead of rotate_y. Using rotate_object_local like this means we’re rotating around the local y axis of the object, regardless of its global orientation. This means it will work while we're standing on the wall or upside down. Now let's add our bot to the main scene and try it out! To handle walking, our IK target is going to track its distance to a “Step” target. Unlike our IK target, this step target move will not be top level, so it will move along with our spider. If the distance gets too far, we’ll move our IK target to the step target's position. Let's begin by setting up our step targets. First I’m going to add a node 3d called StepTargetContainer, which we’ll need for later. To make things quicker, I’m copying the IK target nodes, removing top_level & renaming them to StepTarget. We want our step target to always align with the floor, so I’m then positioning ray cast nodes at the step targets, angling them slighting and moving them up. The angle helps when attempting to walk up 90 degree surfaces. To position our step targets to the floor, create a new script and attach it to the rays. Get a reference to the step_node for the ray and in physics_process, if a hit point is found, move the target to the hit location. Then in the editor, set the step target references. Now attach a new script to your IK Targets, this script will handle the animating of the target. At the top add two variables, one is a reference to our step target, the other is our distance between taking a step. Then add a new function called step. Like before, we’re going to use tweening to animate the target. This is the tweening logic from the old implementation. It was overly complicated and only lifted the leg upwards globally on the Y axis, which ruins the effect while walking up vertical inclines or while upside down. I’ve now simplified the tween to this: We get our target position, and then find the halfway point between it and our current location. Then we tween to the halfway point plus our owner’s, which is the spider bot’s, basis.y. This will be one metre up in whichever direction the spider is currently oriented. Once we reach that target, we then tween to the final target position. Finally, in process, check the distance between the target and our current position, and if we exceed our required value, call step. Let's see how that looks. Well, it works, but all legs are stepping at the same time. Let’s make it so we can’t step if the the adjacent leg on the left or right is already stepping. Back in our script, add a reference to our adjacent leg, and a boolean to track if we're currently in the stepping state. Then add to our if statement, to only step if 1, we aren’t already stepping, and 2 if the adjacent leg isn’t stepping. Then in the step function, set is_stepping to true. Then lets add a callback tween to the end of our tween queue. For the callback, we are going to use a lambda function to set is_stepping back to false after the step is complete. Set the adjacent references and let’s take another look. That’s much better! But personally, I like it when the legs diagonally step at the same time. If you want to implement that too, let's add another reference for our diagonally opposite leg, and then when we call step, call step on the opposite leg too. Muuuch better! This looks great while turning around, but when walking the legs lag behind a bit. Let's fix that now. Add a new script to our step target container. Add a variable to the top to store our desired offset when moving, lets also grab a reference to the parent node & store the parents previous position. Then in _process, we can calculate the velocity by subtracting the previous position, from the parents current position. We can then set our container's position using this velocity multiplied by our offset. Finally update our previous position variable. This is looking way better! We just need to get our body moving & rotating based on the leg positions now. Back in our main spider_bot script, let's first move our movement logic into another function for neatness. Then let's add some references at the top to hold our legs IK targets. Let's also create a variable to hold our desired height offset from the ground. In the old video I used the following logic to handle the rotation, taking the average leg positions and using the difference to calculate rotations on the relevant axis. This method works great until you go vertical or upside down, and then it quickly falls apart. I had to come up with a solution that would work for any orientation, that’s when I remembered my old friend, the Plane class. A plane is essentially a position and a direction, also known as a normal, that has various uses. One way we can initialise a plane is by putting in 3 positions in clockwise order. My idea was to create two planes from the ik target positions. Then, we can average the normals to get our bodies desired orientation. We just then need to be able to turn this normal into a transformation basis. We can do this in a similar way to how we did it in the path-based mesh generation video. I’ll skip the explanation on the basis's, as I already went over it in that video. Our new basis’s y is the normal direction, its x is the normal crossed with our forward direction, and the z is the right direction crossed with the normal direction. Finally, let's overwrite our basis with the newly calculated one. We can use lerp too to make this smoother. Let’s check the result! Awesome! We’re almost there. There’s just one last thing we need to do. We need to make sure we lift the body up and down based on the height of the ik targets. Let’s calculate the average position of the legs. Then calculate the target position as this average, plus our bots up direction, multiplied by our ground offset. Now we only care about the difference between our current position & the target position in the spider bots current direction, we can calculate this by using the always helpful dot product. If we take our direction, call the dot function and pass in the target position minus our current position, we’ll get only the difference for that direction! We can then lerp towards our position plus our up direction multiple by our calculated distance, this will work no matter which way our spider bot is oriented! And then we'll have the final result. There are few things we can do to improve this, but I'll leave it up to you in your imagination. Anyway, I think that’s about it for this video. I hope you found that useful. I’ll leave a github link to the finished project in the description below. If you found this video useful, please give it a like and think about subscribing! In a future version of godot has killed this implementation again, let me know and I’ll do another updated video. I’ve recently started streaming my Godot tinkering on twitch, if you want to see my fumble at both streaming & coding simultaneously, be sure to send me a follow. Anyway, I’ll see ya in the next one. Cheers!
Info
Channel: Crigz Vs Game Dev
Views: 123,589
Rating: undefined out of 5
Keywords: Procedural Animation, Godot, Godot 4.0, Godot 4, Godot 3, Godot 3.5, Spider, Spider bot, Game development, Tutorial, Educational, Programming, GDScript
Id: G_seJ2Yg1GA
Channel Id: undefined
Length: 9min 26sec (566 seconds)
Published: Sun Mar 19 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.