Unity에서 Find 계열 함수는 성능이 좋지않다.
특히 Find는 Scene의 모든 오브젝트를 탐색하므로 Scene의 오브젝트가 많을수록 탐색 리소스 비용이 크다.
대안으로 필드를 직렬화하여 Inspector에서 직접 참조를 연결해주거나,
FindWithTag를 사용할 수 있다. FindWithTag는 tag가 붙은 오브젝트만 탐색하여 다른 Find 계열 함수들에 비해서는 성능 부담이 적지만 tag가 많아지고 호출 빈도가 높아지면 성능에 영향을 준다.
튜터님이 피드백 주신 부분은 HumanController 스크립트에서의 FindWithTag 사용이다.
Awake에서 호출하기는 하지만 풀링되는 Human의 개수만큼 호출되므로 반드시 여기서 호출되야하는 것이 아니면 다른 부분으로 넘기고 참조 값만 사용하는 것이 좋다.
맵의 시작점과 종료지점을 찾는 것이므로 맵 자체에서 get 프로퍼티로 열어두고 참조해 사용하면 된다. 이렇게 변경하면 Stage가 Awake될 때 1번만 호출하게 되어 매우 효율적이다.
HumanController.cs
private void OnEnable()
{
transform.position = StageManager.Instance.SpawnPoint.position; // 시작 위치 설정
}
StageManager.cs
public class StageManager : SingletonBase<StageManager>
{
public Transform SpawnPoint { get; private set; }
public Transform EndPoint { get; private set; }
protected override void Awake()
{
SpawnPoint = GameObject.FindGameObjectWithTag("HumanSpawnPoint").transform;
if (SpawnPoint == null)
Debug.LogAssertion("Spawnpoint not found");
EndPoint = GameObject.FindGameObjectWithTag("DestinationPoint").transform;
if (EndPoint == null)
Debug.LogAssertion("Endpoint not found");
}
}
그런데 위와 같이 수정하면서 문제가 생겼었다! 바로 Awake와 OnEnable의 호출순서...
Awake 다음에 OnEnable이 호출되는 것은 보장되지만, 다른 오브젝트끼리의 순서는 보장하지 않는다.
HumanController에서 NullException이 뜨자 UI 특강 때 튜터님께서 시연해주신 기이한 Awake와 OnEnable 호출 순서 테스트가 떠올랐다.
HumanController가 StageManger보다 먼저 Awake & OnEnable이 되면서 null 참조 오류를 발생시켰다.
이를 방지하기 위해 아래와 같이 수정했다.
HumanController.cs
private void OnEnable()
{
if (StageManager.Instance.SpawnPoint == null) return;
transform.position = StageManager.Instance.SpawnPoint.position; // 시작 위치 설정
}'내일배움캠프 > TIL' 카테고리의 다른 글
| [내배캠][Unity6기][TIL] Scene Reload 버그 트러블슈팅 (2) (0) | 2024.12.16 |
|---|---|
| [내배캠][Unity6기][TIL] Scene Reload 버그 트러블슈팅 (0) | 2024.12.13 |
| [내배캠][Unity6기][TIL] NavMesh 트러블슈팅 (2) (0) | 2024.12.11 |
| [내배캠][Unity6기][TIL] NavMesh 트러블슈팅 (0) | 2024.12.09 |
| [내배캠][Unity6기][TIL] NavMesh 경로 설정 수정 (0) | 2024.12.06 |