Hey guys,
I thought you all might be interested in this. I’ve been working on a Diablo/roguelike for a while and I decided I really hated the grid-based moving my characters were doing (smooth movement within a grid). It looks sterile in my case and just overall doesn’t feel right.
So I started to change the game to be polygonal instead of grid-based (or at least have the entities moving freely within a grid-based dungeon). This led me to decide that A* wasn’t really going to work well for all the enemies in the maze, both because it’s expensive to run on like 100+ entities every frame, and because even if the entities are free-moving they can only have as little granularity as the A* algorithm has. It also occurred to me that it doesn’t necessarily make sense that enemies halfway across the maze can just magically find exactly how to get to you.
So I decided to try out a steering algorithm. It only took me a couple hours to get to this point and think it works really well. Basically, each entity sends out 3 raycasts each frame, one in front and two at 45º angles. If the front cast hits anything, the entity will begin decelerating. If any of the side ones hit anything, it will turn in the opposite direction. If both side ones hit anything, it turns towards whichever is furthest from the wall. In the off chance everything is equidistant, it will use its “turn tendency” which gets recalculated every time it finds a clear path.
There are two options here as well. One makes everything look much more natural but allows for the rare chance of the entity getting stuck in a corner turning left and right until the end of eternity. The other makes sometimes greater than 180º turns (so looks weird) but it will never get stuck. I decided to go with the former option. The difference in terms of code is simple - for the latter, once the entity starts turning it must keep turning in that direction until it is completely free and clear. In the former, the entity may recalculate direction any time either its left or right raycast is clear.
One last thing - if the entity gets within a certain radius, it completely stops. This disallows overlapping collisions.
Oh wait, I also added a very simple weighting system that’s not fully hooked up, where as an entity exists in a grid area it adds to the total cost of that space. This makes it desire going towards lower cost spaces, which encourages a sort of patrol behavior.
I’ve also recently added some rudimentary attack logic (not in this demo) and will be improving the cost logic to make it really work. Part of doing that will be by adding a “target” location that makes the cost of the target 0 and nearby spaces like 0.5, causing the entity to always want to hang out there.
Anyway, here is a video of it in action. If you full screen it, you can see very small indicators of the front of the entities.
I’ll keep posting videos as I improve it, and if anyone wants the source let me know (but it’s in Unity C#).