Senior Production – Week 2

This week was kind of slow for me since I was working with stuff for other classes (making prototype game engine).

This week I messed with Unity’s mechanim system some more and started looking at implementing custom shaders in Unity.

Mechanim

 

Mechanim is kind of painful to work with since there’s seemingly no good way to bind multiple clips of animation to a single skinned model unless they are all placed on the same timeline in Maya and partitioned in Unity. This means that at the moment whenever there is a new animation I have to pull in a duplicate of all the model data that also includes the new animation clip. That’s what we’re doing at the moment, but I really want to find a way to just pull in the animation data.

The player runs, swings, and idles currently.

Ground Shader

 

NecroManager-Ground1

Before with apparent tiling

I started on Unity’s shaders by making the ground texture appear less tiled. I did not really have anything other than the grass texture to start with. Instead of using the texture coordinates on each tile, I decided to use their world space positions to sample the texture. This allowed me to reduce the frequency of the repeating because now the tiling frequency of the texture was not limited by the size of each ground tile.

The grass looked a little better, but the tiling was still pretty apparent. I decided to use some fractal Brownian motion as I had in a previous project, but instead of using it as a height map; this time I used it to darken the grass texture by just factoring the color and the float generated by the FBM together. This got me somewhat closer to removing the tiled look, but I’ll be mixing in a dirt texture using the noise to get the ground looking even nicer.

Fog Shader

 

I also used another round of fractional Brownian motion for a subtle panning fog effect on the ground. The fog moved across the ground slowly, and also changes shape as it moves because I am panning through using FBM in 3D. I put in the x and y as the world space position, and use the current elapsed time that the game has run as the z coordinate.

NecroManager-Ground2

After with dark spots in grass and fog

This was just something I threw together quickly so it does not look incredibly good right now. I plan on improving the fog’s look significantly in one of two ways. The first would be the best option for performance, and it would be to just separate the fog into a transparent plane a foot or so above the ground. This way geometry like the graves and lower part of the player would be occluded by it. The second approach would be exponential falloff height-based fog. This would be a lot more performant if we were using the deferred renderer, but it can still be done in forward rendering. This would give a much more continuous-looking fog effect. If the performance is there I could also trace through the fog volume and accumulate its density along with checking for any point lights in range. This would give a volumetric fog effect where the fog would light up when lights such as the one attacked to the player get closer.

Pathfinding Optimizations

 

Currently the pathfinding for the zombies is rather inefficient and does not necessarily look very good since all the zombies move in very straight lines between tiles. When there are > 50 zombies in a large level the pathfinding algorithm is a significant bottleneck on lower end computers. I’m not sure if Tim would like to do this or if I should handle optimizing the pathfinding. Every frame each zombie recalculates the path towards the exit from their current position and finds the next tile that they need to move to using A*. I’m rather surprised that the game is actually capable of handling as many zombies at once as it is currently.

The simplest solution would be to just store the next tile position until the zombie steps onto that tile. Even if it took the zombies half a second to cross a tile it would be a ~30x performance savings when the game is running at full speed.

The slightly less simple solution that most games go for is to have each character calculate their path once. The moment that each zombie spawns it would calculate its path to the entrance of the graveyard and store all tiles it needs to cross in a list. Then each frame it would check the back of that list for the next tile it needs to move to, and if it is at that tile, then it would remove it from the list and look at the next tile.

The path that is generated could then have the extra time to go and reduce the number of nodes in the path by checking which nodes have line of sight to others and culling any nodes in between. This would lead to less rigid paths and remove the apparent jaggedness in movement when the zombie is attempting to move diagonally.

Finally, there is a technique used in pathfinding for large groups of characters that I researched first semester last year. This technique is called flow field pathfinding, and is pretty much specialized for this exact situation. This technique is capable of generating paths from every point on to map to a destination point or set of destination points. On smaller maps such as the ones our game uses, it can generate the flow field in under 5ms. This flow field will not change until the objectives change, and the only time this happens during gameplay is when the zombies finish eating a brain stalk. This field can be used by thousands of agents for pathfinding with a negligible performance impact. Here’s a video I made of flow fields in action. If I were to implement this, then the movement of the zombies could be made to look much more natural by smoothing their velocity based on the flow field.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>