본문 바로가기

개발/Unity, C#

Unity Update문에 대해서

 

https://blogs.unity3d.com/kr/2015/12/23/1k-update-calls/

 

위 링크를 보고 나서 언젠간 한 번 직접 테스트해봐야지 했던 건데 직접 해봄 

 

1. 모노비헤이비어들의 업데이트문은 어떤 순서로 불려질까?

 

using UnityEngine;

public class UpdateTest : MonoBehaviour
{
    public float t = 0;
    public bool isStart = false;

    // Update is called once per frame
    void Update()
    {
        if (isStart == false)
        {
            return;
        }

        t += Time.deltaTime;
        if (t > 5)
        {
            Debug.Log(this.name);
            t = 0;
        }
    }
}

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    private List<UpdateTest> list = new List<UpdateTest>();

    private void Start()
    {
        for (int i = 0; i < 10; i++)
        {
            var g = new GameObject(i.ToString());
            list.Add(g.AddComponent<UpdateTest>());
        }

        for (int i = 0; i < 10; i++)
        {
            list[i].t = 0;
            list[i].isStart = true;
        }
    }
}

결과

 

일단 기본적으로 생성 순서대로 나옴

 

 

오브젝트들의 일부를 껐다키면 어떻게 되는지 확인

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    private List<UpdateTest> list = new List<UpdateTest>();

    private IEnumerator Start()
    {
        for (int i = 0; i < 10; i++)
        {
            var g = new GameObject(i.ToString());
            list.Add(g.AddComponent<UpdateTest>());
        }
        yield return new WaitForSeconds(1f);

        list[3].gameObject.SetActive(false);
        list[5].gameObject.SetActive(false);
        list[8].gameObject.SetActive(false);

        yield return new WaitForSeconds(1f);

        list[5].gameObject.SetActive(true);
        list[8].gameObject.SetActive(true);
        list[3].gameObject.SetActive(true);

        for (int i = 0; i < 10; i++)
        {
            list[i].t = 0;
            list[i].isStart = true;
        }
    }
}

좀 멋없는 코드지만 테스트하기엔 충분할 듯

 

결과

늦게 켜진 오브젝트가 늦게 호출되고 있음

 

사실 이건 그냥 궁금해서 해본 테스트

 

 

2. MonoBehaviour의 Update와 직접 만든 Update의 비교

 

MonoBehaviour의 Update

using UnityEngine;

public class Test : MonoBehaviour
{
    private void Awake()
    {
        for (int i = 0; i < 10000; i++)
        {
            gameObject.AddComponent<UpdateTest>();
        }
    }
}

 

using UnityEngine;

public class UpdateTest : MonoBehaviour
{
    private int i = 0;

    private void Update()
    {
        i++;
    }
}

 

결과

 

직접 만든 Update

using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    private List<UpdateTest> list = new List<UpdateTest>();

    private void Awake()
    {
        for (int i = 0; i < 10000; i++)
        {
            list.Add(gameObject.AddComponent<UpdateTest>());
        }
    }

    private void Update()
    {
        for (int i = 0; i < 10000; i++)
        {
            list[i].OnUpdate();
        }
    }
}

 

using UnityEngine;

public class UpdateTest : MonoBehaviour
{
    private int i = 0;

    public void OnUpdate()
    {
        i++;
    }
}

 

결과

 

완벽한 테스트라고 보기엔 어려울 수 있지만.. 약 6배 정도 차이가 남

 

 

Base Class를 만들어서 쓰면 편함

 

https://github.com/LeeMyeongHo/BaseMonoBehaviour

 

위 코드는 예시로 만든 것이고 각 프로젝트 환경에 따라 수정해서 쓰면 됨