Pv_log

Awake()와 Start() 본문

Develop Study/Unity

Awake()와 Start()

Priv 2021. 2. 27. 23:06


 

 


출처

 

Unity - 스크립팅 API: MonoBehaviour.Awake()

Awake는 게임이 시작되기 전에, 모든 변수와 게임의 상태를 초기화하기 위해서 호출됩니다. 스크립트 인스턴스가 종료될 때까지 한번만 호출됩니다. Awake는 모든 오브젝트가 초기화되고 호출되기

docs.unity3d.com


 

1. 속도 경쟁

Start()와 Awake()의 속도를 비교하면 Awake() > Start()라는 말을 여럿 들어보았다.

Start()는 Update() 호출 이전 단계에 1회 호출되고, Awake()는 스크립트 인스턴스가 로딩될 때 호출된다.

유니티 공식 도큐먼트에 따르면, Awake는 게임이 시작되기 이전, 모든 변수와 게임의 상태 초기화를 위해 호출된다고 한다.

간략히 순서를 표현하자면, 스크립트 인스턴스 로딩 > Awake() 호출 > Start() 호출 > Update() 호출 순이다.


 

2. Awake()는 갑자기 왜?

공부를 겸해 개발 중인 자작 게임, RGB 프로젝트 코드 최적화를 진행하다가 Awake()를 Start()로 바꾸니 에러가 발생하는 것을 목격했다.
(예전에 짜둔 코드를 왜 이따구로 짰냐며 혼자 욕하면서 괜히 건드렸다가 첨 보는 에러 터트리고 멘붕 빠진 건 안 비밀.)

그게 무슨 코드냐?

 

public class ProjectileController : MonoBehaviour
{
    Rigidbody2D rigidbody2D;


    // 
    void Awake()
    {
        rigidbody2D = GetComponent<Rigidbody2D>();    
    }

    void Update()
    {
        if (transform.position.magnitude > 1000.0f)
        {
            // Far away; Destroy
            Destroy(gameObject);
        }
    }
    
    public void Launch(Vector2 Direction, float Speed)
    {
        // Projectile Shoot; ForceMode2D.Impulse !! 
        rigidbody2D.AddForce(Direction * Speed, ForceMode2D.Impulse);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        // Hit; Projectile 2 Projectile
        if (collision.transform.tag == "Projectile_B" || collision.transform.tag == "Projectile_G" || collision.transform.tag == "Projectile_R" || collision.transform.tag == "Projectile_W")
        {
            return;
        }
        else
        {
            // Hit; Destroy
            Destroy(gameObject);
        }
    }
}

 

이런 (변태 같은) 코드다.

총알을 발사하는 스크립트인데, 휘황찬란하게 혼자 독보적인 길이를 자랑하는 if문은 못 본 걸로 치고, 맨 위에 Awake()를 보자.

저 부분을 괜히 Start()로 바꾸었다가 Launch() 메서드를 호출하는 과정에서 NullReferenceException이 발생했던 것.

앞서 언급했듯이, Start()는 Awake() 이후, Update() 이전에 호출된다.

헌데, 여기서는 위의 소스코드에 있는 Launch()라는 이름의 사용자 정의 메서드를 다른 스크립트에서 참조해 호출하는 형태였다.

즉, Start()고 자시고 스크립트 인스턴스 생성 후에 곧장 Launch() 메서드로 하이패스 진입을 해버리는데, 우리의 친구 유니티가 rigidbody2D가 뭔지 알아먹을 리가 없지.

즉, 인스턴스 생성 직후에 호출되는 Awake()에 rigidbody2D = GetComponent <~~> 이 코드를 넣어줘야 Launch() 톨게이트 지나기 전 단계에서 유니티에게 rigidbody2D가 뭔지 가르쳐줄 수 있다는 것.

 


Comments