Approach to render pedestrians like in Cities Skylines?

I see a video showing pedestrians like in Cities Skylines

So which approach should I use to render these pedestrians and keep the FPS so that the player won’t complain about lagging.
Requirements:
Each ped (or group of ped) can move on his path.
Each ped (or group of ped) can disappear when a specific event happens.

This thread focuses about the approach to render pedestrians (I think if I include the AI here, the topic will be too broad). I think of some approaches but I don’t know which one is possible or better.

Approach 1: Use DrawMeshInstancedIndirect, here is the example on github, I really want to use this approach but I don’t know if it’s possible to simulate the pedestrians with this approach. I see that DrawMeshInstancedIndirect move the object with shader code instead of C# code.
Note: this is the most powerful way to render crowd, but I don’t know if it’s possible to simulate ped.

Approach 2: Use DrawMesh, this is pretty good, I can easily set the position & rotation of the pedestrians through the function DrawMesh.
Note: like the docs said: Use DrawMesh in situations where you want to draw large amount of meshes, but don’t want the overhead of creating and managing game objects.

Approach 3: Just create each ped as a game object like every other mesh object in the scene. I once tried to test how many animated characters with physic Unity can handle, and I see that the number of characters is not large enough, maybe I’ll remove the Physic for the pedestrians to improve FPS.
Note: This is the simplest way and I can make use of the Unity’s animation system.

Please share which approach you will take (maybe none of the approach above) if you have to create the game Cities Skylines.

Certainly do not apply physics to each pedestrian! That’s just madness.

Yes, for something like this you want to think of them like particles in a particle system. Not literally a ParticleSystem, as I don’t believe you’ll be able to get them to move the way you want with that — but similar, a mesh (or use of DrawMesh) where each pair of triangles is one pedestrian, with an appropriate position in the world and a texture that looks approximately right given the camera angle, pedestrian angle, and pedestrian type/animation frame.

It’s a lot of work to set up, but will enable you to render a large number of these little guys with good performance.

Moving it onto the CPU might be even better, but I don’t know how to do that… if you figure it out, please write it up! :slight_smile:

I think it’s better to go with Approach 1, but use DrawMeshInstanced() instead of DrawMeshInstancedIndirect(). I can easily call DrawMeshInstanced() multiple time per frame while DrawMeshInstancedIndirect() is pretty trouble to do this.
With DrawMeshInstanced(), I can pass the array of transform (position/rotation/size, use Matrix4x4.TRS() to set each of them) to control the peds movement.

DrawMeshInstanced() is easy to use, check SupahPOW31 on reddit for demo.

About peds animation, thanks to zulfajuniadi for his incredible open source Animation-Texture-Baker on github.

Edit: About animation, it’s just the shader play animation from an image file: check this project Animation-Texture-Baker of sugi-cho which is simpler and easier to understand.

About Approach 3, I think it’s possible if using C# Job System: check Unite 2016 Keynote - Performance Optimization, C# Job System Demo.

Check this interesting Unite Austin Technical Presentation on Github. I haven’t checked it out because the download size is pretty big.

You can tag them all. Use enums function something like:

using UnityEngine;

public enum PedType
{// you can store every tagged pedestrian here

ped1,
ped2,
ped3

}

public class YourClassNameHere : MonoBehaviour{


public PedType currentPedTag;


void Awake(){

AssignPeds();
// This will grab EVERY tagged object listed
// inside the enum above and fill them with the stats below

}

public void AssignStats() // Assigns the enemy HP and enemy damge
    {

        if (currentPedTag == PedType.ped1)
        {
          // set animations, stats, anything here
         // for Ped1 tag
        }

        else if (currentPedTag == PedType.ped2)
        {

         // Load your ped2 tag class here        

        }
else if (currentPedTag == PedType.ped3)
        {

         // Load your ped3 tag class here        

        }

    }



}

I found this is the quick way for me to load an entire scene with stats.

I use it for EnemyMaxHp, EnemyHp, EnemyDmg, etc…

But you can use this to set your animations and stuff for MANY different tags.