유니티 개발을 하면서 "어떻게 작성하는 것이 더 최적화된 코드이지?" 라는 궁금증이 생기는 경우가 많이 있습니다. 그랬던 궁금증 중 한가지는 한 오브젝트가 update문에서 for loop를 돌면서 여러 오브젝트들의 함수를 실행하는 것이 빠를까 아니면 각 오브젝트들이 update문에서 자체적으로 실행하는 것이 빠를까 하는 궁금증이었습니다. 그래서 Unity Profiler를 통해서 어느 것이 더 빠른지 간단하게 실험을 해보았습니다. (Unity Profiler 사용법이 궁금하시다면 지난번 게시물을 확인해보세요 (https://lefthanddeveloper.tistory.com/25)
먼저 씬 배치는 다음과 같습니다.
Target 오브젝트가 있고 Followers 오브젝트가 있는데 Followers 오브젝트 child로 follower가 생성이 되게 됩니다. Follwer 오브젝트들은 Target 오브젝트 쪽으로 계속 이동을 하게 할 것입니다. 이동 방법으로 한 스크립트의 update문에서 for loop으로 여러 follower를 움직이는게 더 성능적으로 더 빠른지 아니면 각 오브젝트 update문에서 이동을 하는 것이 성능적으로 빠른지 실험을 해보도록 하겠습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowerController : MonoBehaviour
{
public bool isControllerControlling = false;
[SerializeField] private Transform target;
[SerializeField] private Follower followerPrefab;
[SerializeField] private int numOfFollower = 100;
private List<Follower> followers = new List<Follower>();
void Start()
{
for(int i=0; i< numOfFollower; i++)
{
Follower follower = Instantiate<Follower>(followerPrefab, this.transform);
follower.Init();
followers.Add(follower);
if (!isControllerControlling)
{
follower.SetTarget(target);
}
}
}
// Update is called once per frame
void Update()
{
if (isControllerControlling)
{
for(int i=0; i< numOfFollower; i++)
{
followers[i].MoveTo(target);
}
}
}
}
FollowerController.cs 에서 bool 값 isControllerControlling 이 true이면 FollowerController.cs에서 for loop문을 돌아 follower를 이동시키게 됩니다 (FollowerController.cs에서 update()부분).
만약 isControllerControlling이 false 이면 각 follower.cs 의 update문에서 target을 향해 이동하게 했습니다 (아래 스크립트 참고)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Follower : MonoBehaviour
{
private bool isTargetSet = false;
private Transform target;
[SerializeField] private float movingSpeed = 1.0f;
public void Init()
{
this.transform.position = Random.insideUnitSphere * 30f;
}
public void SetTarget(Transform target)
{
this.target = target;
isTargetSet = true;
}
public void MoveTo(Transform _target)
{
transform.LookAt(_target);
transform.Translate(Vector3.forward * Time.deltaTime * movingSpeed);
}
void Update()
{
if (isTargetSet)
{
transform.LookAt(target);
transform.Translate(Vector3.forward * Time.deltaTime * movingSpeed);
}
}
}
위에 작성된 코드에서는 num of followers가 100으로 되어있는데 인스펙터에서 5000으로 수정하고 테스트를 했습니다.
실험결과는....
속도는 둘다 거의 비슷하다는 점! 위에 스크린샷에서 한 스크립트 update문에서 for loop문을 돌았던 쪽이 약 2ms 정도 더 빨랐는데 이거는 매 frame마다 조금씩 fluctuation이 있기때문에 이정도 차이는 무시해도 될 차이인듯합니다.
5000 오브젝트를 움직일때 한 update에서 5000번 for loop를 돌던, 5000개의 오브젝트에서 update로 움직이던 크게 차이는 없는 것으로 결론이 났습니다.
아래는 테스트를 하면서 5000개의 sphere가 target을 따라가는 모습을 보는게 재밌어서 gif로 남겨봤습니다
'Unity & C#' 카테고리의 다른 글
[유니티] 색깔이 들어간 나만의 Debug.Log() 만들기 (0) | 2022.07.08 |
---|---|
[유니티] Destroy() vs. DestoryImmediate() 차이점은? (0) | 2022.07.07 |
[유니티] Unity Profiler 사용하기 (0) | 2022.07.05 |
[C#] Switch문을 사용한 Type Pattern Matching (0) | 2022.06.26 |
[c#] Indexer [인덱서] 활용해보기 (0) | 2022.05.08 |