Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Script for each Game Object

Discussion in 'Scripting' started by oukibt_unity, Aug 25, 2022.

  1. oukibt_unity

    oukibt_unity

    Joined:
    May 6, 2022
    Posts:
    19
    Greetings. This question is about optimizing scripts in Unity.

    I have 20 characters on stage (or more, whatever).
    My task is to make them follow the player's moving camera with their eyes. There are 2 solutions to this problem.

    1.
    Create a small script that will take 2 Transform eyes as arguments

    The script will handle eye rotation in FixedUpdate (or Update). But this script will be for each character, of which there are 20 and therefore 20 FixedUpdate will be called.

    2.
    Create a larger script that will process the array of eyes in one FixedUpdate (this is less convenient than using the script for each character separately).



    But the question is primarily about how much worse it is to use the first option instead of the second in terms of script performance?
     
  2. Magiichan

    Magiichan

    Joined:
    Jan 5, 2014
    Posts:
    403
    Interesting question, As you've stated the second options seems like a more efficient way of handling the logic.
    It's very difficult to give an exact answer to your question because in what unit do we measure the "worse" scripting option...

    Performance could also be very dependent on the content of your code.
    I think the best & truly only way to answer your question is by conducting an experiment yourself.

    Let me know if you have some new insights! :)
     
  3. oukibt_unity

    oukibt_unity

    Joined:
    May 6, 2022
    Posts:
    19
    Yes. I did a test, there is a small difference. I have created 100x100 cubes and each one changes its Y position every frame.

    Script per object


    One script for all objects


    A script:


    Code (CSharp):
    1. public class Main : MonoBehaviour
    2. {
    3.     private static Vector2Int m_cubesCount = new Vector2Int(100, 100);
    4.     List<GameObject> cubeList = new List<GameObject>(m_cubesCount.x * m_cubesCount.y);
    5.     GameObject Cubes;
    6.  
    7.     private bool m_SingleScript = true;
    8.  
    9.     void Start()
    10.     {
    11.         Cubes = new GameObject("Cubes");
    12.  
    13.         int i;
    14.         if (m_SingleScript)
    15.         {
    16.             for (i = 0; i < cubeList.Capacity; i++)
    17.             {
    18.                 cubeList.Add(GameObject.CreatePrimitive(PrimitiveType.Cube));
    19.                 cubeList[i].transform.parent = Cubes.transform;
    20.                 cubeList[i].transform.position = new Vector3((int)(i / m_cubesCount.x) * 2.0f, 2.0f, (i % m_cubesCount.y) * 2.0f);
    21.             }
    22.         }
    23.         else
    24.         {
    25.             for (i = 0; i < cubeList.Capacity; i++)
    26.             {
    27.                 cubeList.Add(GameObject.CreatePrimitive(PrimitiveType.Cube));
    28.                 cubeList[i].transform.parent = Cubes.transform;
    29.                 cubeList[i].transform.position = new Vector3((int)(i / m_cubesCount.x) * 2.0f, 2.0f, (i % m_cubesCount.y) * 2.0f);
    30.                 cubeList[i].AddComponent<CubeHandler>();
    31.             }
    32.         }
    33.     }
    34.  
    35.     void Update()
    36.     {
    37.         if (m_SingleScript)
    38.         {
    39.             Vector3 cubeTransform;
    40.  
    41.             for (int i = 0; i < cubeList.Count; i++)
    42.             {
    43.                 cubeTransform = cubeList[i].transform.position;
    44.                 cubeTransform.y = 2.0f + Mathf.Sin(cubeTransform.x + Time.fixedTime);
    45.  
    46.                 cubeList[i].transform.position = cubeTransform;
    47.             }
    48.         }
    49.     }
    50. }
    51.  
    And script for game object
    Code (CSharp):
    1. public class CubeHandler : MonoBehaviour
    2. {
    3.     void Start()
    4.     {
    5.      
    6.     }
    7.  
    8.     void Update()
    9.     {
    10.         Vector3 cubeTransform;
    11.  
    12.         cubeTransform = gameObject.transform.position;
    13.         cubeTransform.y = 2.0f + Mathf.Sin(cubeTransform.x + Time.fixedTime);
    14.  
    15.         gameObject.transform.position = cubeTransform;
    16.     }
    17. }
    18.  
     
  4. RadRedPanda

    RadRedPanda

    Joined:
    May 9, 2018
    Posts:
    1,593
    Doesn't seem like much of an improvement. Perhaps you could instead try GPU Instancing? Supposing all of your meshes are the exact same, it would drastically improve performance.
     
  5. Terraya

    Terraya

    Joined:
    Mar 8, 2018
    Posts:
    646
    To Improve your performance i would suggest todo so when its needed.

    Things to help you improve your performance in terms of CPU:
    - Dynamic Scene Loading (Could improve in case you have got more MonoBehaviours in different locations which are not needed in your current situation)
    - Use a Manager to handle your AI Lifecycle, which means, have an Array (If you dont add/remove) AI out from it and Tick your AI. In case you enable/disable AI runtime, use a list.
    - Depending on the distance of your AI, you can tweak their behaviour, if they are far away from your Player, dont Tick every second but every 15 for example. if they get close, tick every second once.
    - Dont use Update/LateUpdate/FixedUpdate but only from your Manager.
    - Cache values/References

    Small Edit: There are more adv. ways ofc. but for 20 AI this should do easly
    hope this might help :)