The good news is in a big game like yours I think you can improve your fps easily.
What I learn from the different documentation I have been reading is geometry, lighting and code can have a big weight in performance. I see in your stats you have 3.3M of tris, 2032 passes, 609 shadow casters and 2809 batches.
I think one of first things you can try and it’s really easy, it’s the Occlusion Culling, so instead of rendering the whole level, the camera only renders what sees, that should drop your tris, passes, batches, etc. and improve your performance. Here is some info: https://docs.unity3d.com/Manual/OcclusionCulling.html

For the shadow casters, check if you really need those elements to cast shadows. Sometimes the element is already in a dark area and the shadow is not noticeable. And bake your lights, I don’t know how many lights you have, but I feel with one or two directional lights, and baking the rest you will get similar results.

For your code another big improvement is only use update if you really need it, you can mostly replace the update by using coroutines.

Those are just some of the general things you can do, I feel optimizing is the sum of lots of little things. If you are interested in optimizing I highly recommend these collection of articles, they were really helpful for me:

Hope it helps :slight_smile:


Thanks for posting this and i will definatly be looking into this as i feel it will be an issue for me in the future.
However this turned out not to be my route cause.

@ben @Rick_Davidson

When you code the patrol routes using the couroutines i dont think you actually resolve the issue with having no waypoint container on the AI.
I got around this by giving them a blank one to stop the error but the code still looks for it.
When i increased my number of enemies i was noticing a substantial drop in FPS (20 every 10-15 enemies)

I found my solution to check for null and break if it is null

    IEnumerator Patrol()
        state = State.patrolling;
        while (true)
            if (patrolPath != null)
                // Work out where to go next
                Vector3 nextWaypointPos = patrolPath.transform.GetChild(nextWaypointIndex).position;
                yield return new WaitForSeconds(waypointDwellTime); // TODO parameterise
            else yield break;


Okay found a few bugs that were “bugging” me and although not a total fix i have found some fixes to some issues.

Mage actually now casts a spell instead of pointing has hand and hoping. The game also knows which weapon it has at the time of attacking and so knows if its got a staff or sword and attacks accordingly with the particle system for the staff only.
This in turn as i incorporated it into the weapon system means that any of my characters can have a particle effect applied to their main attack now as long as they have a ranged weapon. (Healer included)
A bug that i am still in the process of solving is that the character.Kill() method i thought at one point stopped the movement of corpses it apparantly doesnt or never did.
I have an issue atm where stopping motion by disabling the navmesh works but the character script makes calls on it. If i try to disable the character script earlier then the navmesh some calls still go though and give errors.

There is probably a better way to do this but will figure it out another day for now happy my mage attacks more appropriately now.

EDIT @CreativebytheSea It has become noticeable, I did have an amusing flash back of wondering why looking at the floor in some older games in old end graphics cards improved performance.
It makes total sense as well as you wont experience this issue in a fixed camera enviroment. Once i get these few bugs squashed they were making my game not fun i will build up the level some more and get on the occulsion!


I’m not sure if I understood your issue with your navmesh, but did you try:

    IEnumerator KillCharacter()
        // disables navmesh 
        GetComponent<UnityEngine.AI.NavMeshAgent>().isStopped = true;
        // Trigger Death Animation

        //Play Death sound
        audioSource.clip = deathSounds[UnityEngine.Random.Range(0, deathSounds.Length)];
        audioSource.Play(); // override all sounds
                            // Slow game down
                            // Time.timeScale for time slow down
                            // delay
        yield return new WaitForSecondsRealtime(audioSource.clip.length);

        var playerComponent = GetComponent<PlayerControl>();
        if (playerComponent && playerComponent.isActiveAndEnabled) // relying on lazy evals (if first fails it wont check 2nd arg)

            //Reload scene 
        else // assume is NPC
            Destroy(gameObject, deathVanishSeconds);

Perfect solution thanks :slight_smile:



Hey Marc,

Really enjoying seeing the continuing progress on Orenidron. The spinning cubes above the quest givers are a nice touch.

What mic did you buy in the end?


Hey rob,

Taking a day chilling with some tv today lol creative juices ran out after designing an Inn.
The microphone

Its really sensitive as in even my kids downstairs can be picked up on it although you should be recording and filtering background noise for recording anyway.
As i can do it whilst everyone is out its not so bad for me.

I had another look yesterday at the FPS and batches issue and rather than trying to bake more than 5 textures in the terrain to a mesh would cost money.
I have managed to drop some of the pixel error settings and other settings to get a lot low batch number and reduced the view distance.
This does mean i will have to be a bit clever with how i build my levels (No real open world area’s) unless i can get occulsion to work with it nicely.

I am going to over the next few weeks flesh out the entire level and then look at performance again as a whole and adjust befor setting enemies and levels again.

At this rate i may be ready next christmas for a demo lol (Hopefully joking)