Search Unity

Improve Update() performance for unused objects

Discussion in 'General Discussion' started by kesada7, Jun 2, 2023.

  1. kesada7

    kesada7

    Joined:
    Jun 21, 2017
    Posts:
    14
    I have hundreds of objects that I animate them by script by changing their rotation and scale. I'm using render.isVisible to prevent Update() of unseen objects from being used. Is this correct practice or is there another more recommended way to approach this? Since although it improves somewhat, there are still hundreds of Update() being called every frame checking if the object is visible with render.IsVisible

    Example code:
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if (_renderer.isVisible)
    4.         {
    5.             if (rotateToRight)
    6.             {
    7.                 transform.Rotate(0f, 0f, Time.deltaTime * _speed);
    8.                 if (Quaternion.Angle(transform.rotation, pointARotation) <= 3f)
    9.                 {
    10.                     rotateToRight = false;
    11.                 }
    12.             }
    13.             else
    14.             {
    15.                 transform.Rotate(0f, 0f, Time.deltaTime * -_speed);
    16.                 if (Quaternion.Angle(transform.rotation, pointBRotation) <= 3f)
    17.                 {
    18.                     rotateToRight = true;
    19.                 }
    20.             }
    21.         }
    22.     }
     
  2. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,191
    First, profile to narrow down what exactly is eating up performance. Is it really the Update calls themselves or is it something inside the Update (isVisible check, transform.Rotate, or Quaternion.Angle)?

    Make sure to close the Scene View when profiling, as isVisible will return true if the Scene View shows your objects, which will cause more of them to need to be rotated even if they are not visible in your game view.
     
  3. ShilohGames

    ShilohGames

    Joined:
    Mar 24, 2014
    Posts:
    3,020
    Instead of having hundreds of game objects with scripts running Update every frame, you could use one script running on one game object to control hundreds (or even thousands) of visual items using DrawMeshInstanced.

    Here is a DrawMeshInstanced sample project for handling thousands of laser projectiles:
    https://github.com/ShilohGames/InstancingPoolDemo

    You could rewrite that GitHub project to do what you want. Just keep in mind the visual items displayed using DrawMeshInstanced don't have individual game objects.

    Another option is to refactor your project to use Unity DOTS.
     
    Last edited: Jun 2, 2023
    tmonestudio and spiney199 like this.
  4. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    Well, it doesn't "prevent Update()" at all, because it is used from inside Update(). At best it's an early exit, but I'd want to check if it's actually cheaper than just doing the rotation anyway. Some things in Unity which look like variables are actually function calls under the hood.

    If you want to prevent Update() from being called then you need to set 'enabled' to false.

    But do heed what the others are saying. First, see if it's an issue by measuring it. Then, if it is, see if there are other fundamental approaches which may be more efficient. Then, whatever you implement, measure it again to see if it actually helped.

    That general process is super important: measure -> modify -> measure again.
     
    SH_qs likes this.
  5. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    The
    CullingGroup
    API is a tool that allows you to trigger events for objects based on their proximity to the camera. It can also be used to enable objects that are close by and disable objects that are farther away. You can find more information at https://docs.unity3d.com/Manual/CullingGroupAPI.html

    Unity also supports the
    OnBecameVisible
    and
    OnBecameInvisible
    MonoBehavior events that can be used to enable/disable objects, see https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnBecameVisible.html

    If you're keen on reducing the cost of invoking
    Update
    , you might want to take a look at a post on the Unity blog that discusses this exact topic. Follow this link to learn more: https://blog.unity.com/engine-platform/10000-update-calls.
     
    Last edited: Jun 4, 2023