I wanted to create a system where insects could crawl on walls like in nature. I never use the built-in NavMesh system because of the limitations I feel it adds to the developers, so I avoided the easy route. Digging deeper I found there was not much information on crawling onto walls from all angles like a spider, the most I found was orbiting around a planet, which wouldn't work the way I wanted.
So I began with what I knew. This took me 3 days to complete which I am not happy about as I like my projects to be quick but I had to finish what I started. After all that, I have a “very much adequate” finished product. So with all that, ill get started on explaining how I got this done!
Explaining The System
First, we need to figure out how we are going to move our transform, which is simple enough, we chose to move our transform forward along the Z-axis and have it rotate/change direction by using only the Y-axis.
These are pretty standard methods when developing games unless you're creating a unique controller.
Our entire system is run with two Raycasts and one Spherecast, we first need a Raycast to check for walls so we can know when there is something in front of our insect. The next Raycast we need is something to check for the ground but since we need to check for sharp angles and corners, we used a Spherecast and call that our GroundCheck. The final addition was so we could know when a cliff was ahead of us, we tried many alternative methods as we did not want to add a third cast, but after long countless hours of trial and error + intensive research, it seemed there wasn’t a known alternative. So in the end, we created a final cast to let us know when there was no ground and to prepare to climb downwards.
All of these origins were connected to spheres for testing purposes, also to just make it easy to understand.
So we began to test our first Raycast, the WallCheck. If we hit a wall, we grab that hitpoint and use unity to return the angle. Which is what we will use to rotate our transform on the X-Axis to match the surface of the wall.
All rotating will be on the X-Axis, all movement will be forward on the Z-Axis and directional rotation will be on the Y-Axis.
Once we are climbing up the wall, we need to keep in mind what it is we are doing, so we create two bools called ClimbingUp and ClimbingDown. When we are going up a wall, we set ClimbingUp to true. So once we reach the edge, we know we still have to turn up and hit the surface. We want this to be called only when we are not climbing down because if we are climbing down, the next time we hit a “wall” it will be the ground and we won't be able to climb up that.
What makes everything get complicated is if we hit a “wall” while climbing down, how can we know if its a flat plane, or another steep plane? We have to check the Raycast hit angle again to be sure.
So what this means is we have to check the angle for both when we are climbing up and climbing down. Based on the booleans we set we can differ which direction we are going and only have these changes if we are in the correct state.
Finally, we have the WallCheck done and once we run into the wall, our insect will flip and match the wall angle.
The next step is to teach our insect how to walk along curves and confusing angles. Well, this was easier than expected, using the same math to match the angle as the wall, we were able to have the GroundCheck call a command on a timer to check for angles below the insect. This helped us easily match almost all angles! That was until our insect reached the halfway point and needed to descend down. Since we are matching the angle to go “Up” we needed to flip the angle at the right time in order to create a walking down effect. To do this we had CliffCheck let us know when it wasn't reaching anything so we should start to turn down.
Going up was the easy part once we started grabbing angles it all connected like magic, that is until our insect reached an edge and jumped off! Earlier we mentioned the ClimbingUp and ClimbingDown booleans, this is where they really made a world of difference.
If ClimbingUp was not set to true, then all cliffs would have us walk down them. Why did we have to add this? When originally climbing up a cliff, nothing is needed to make the magic happen, mainly because of gravity pulling us down.
Did I forget to mention the gravity? If our GroundCheck fails to hit anything we set IsGrounded to false and have it subtract the Y-axis by Time.delaTime. Resulting in pulling down our insect until we hit the ground.
Back to the point. If we are not ClimbingUp and our CliffCheck tells us there is nothing there, then we can set our ClimbingDown to true.
A few things to be noted! we haven't lerped any rotations and they all currently just snap. This usually is fine but for optimizations we added a RaycastCheck interval timer so that instead of checking every second for obstacles, it only plays every X seconds. Without lerping it will create a jinky effect. If your insects will be small in size compared to the character this will be hardly noticeable, still, we plan to implement this soon and its fairly simple.
Finally, after our insect is climbing up and down obstacles its time to finish off with the easy stuff. If you noticed above we had an image that had a variable called turnRadius. We added this float inside of where our X-Axis rotation is controlled and set an InvokeRepeating on the Start that randomly changes our direction if we are not climbing up or down.
In the end, this was one of the most difficult of my journies so far. I have learned a lot and hope I helped some of you to learn how to make a wall-crawling insect for your game, happy developing!
Unity Asset Package will be available on my Patreon
1) Since I did not use any colliders or rigidbodies the insect will miss the floor and continue falling if the GroundCheck fails to hit, I am working on fixing this and will update any changes here.
2) Moving too fast will cause the insect to miss an edge and not climb down it. I’m working on a solution and will post any changes here.