공부/Unity

[Unity] 유니티 생명 주기 life cycle, 키보드 입력에 따른 물체 이동 코드

굴러다니다니 2023. 4. 3. 17:46
728x90

유니티에서는 기본적으로 C# 스크립트를 만들면 써있는 Update, Start 외에도 써있지는 않지만 자동으로 실행되는 함수들이 존재한다.

Reset, Awake, OnEnable, Start, FixedUpdate, Update, LateUpdate, OnDisable, OnDestroy, OnApplicationQuite 함수들이 이에 속하는데 직접 몇가지를 실험해보고 이를 검사해보려고한다.

 

Unity 공식 문서에 의하면  (https://docs.unity3d.com/Manual/ExecutionOrder.html)

Awake -> OnEnable -> Reset -> Start -> FixedUpdate -> OnStateMachineEnter/Exit -> OnAnimatorMove -> OnAnimatorIK -> OnTrigerXXX -> OnCollisionXXX -> OnMouseXXX -> Update -> 등등 뭔가 써보지도 않은 함수들이 너무 많다. 실제로 사용하는 함수들 몇가지만 이용해 이를 실험해보겠다.

 

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

public class Testing : MonoBehaviour
{
    private void Awake()
    {
        Debug.Log("Awake.");
    }
    private void OnEnable()
    {
        Debug.Log("OnEnable.");
    }
    
    void Start()
    {
        Debug.Log("Start.");
    }

    void Update()
    {
        Debug.Log("Update."); 
    }
    private void OnDisable()
    {
        Debug.Log("OnDisable.");
    }
    private void OnDestroy()
    {
        Debug.Log("OnDestroy."); 
    }
    private void OnApplicationQuit() 
    {
        Debug.Log("OnApplicationQuit.");
    }
}

위의 코드를 실행해보자

Awake -> OnEnable -> Start -> Update -> OnApplicationQuit -> OnDestroy -> OnDisable

순으로 나의 컴퓨터에서는 실행되었다.

공식 문서에 의하면 OnDestroy가 제일 마지막이었는데, 왜 위와같은 결과가 나온 것일까?

 

일단 Awake 함수는 딱 한번씩만 실행되며, 초기화를 주로 여기에서 진행한다.

만약 다른 오브젝트에서 이번 오브젝트의 Awake 함수에서 초기화한 것을 받고싶다면, 받는 식도 Awake 함수에서 받아야하며 Start등의 다음 순서의 함수에서 읽는다면 Null을 읽어 오류가 난다.

 

 Update 함수는 게임을 진행하는 동안 계속 검사하는 함수이며, 지속적으로 갱신하거나 판단해야하는 경우의 식을 이곳에 작성한다.

 

OnDisable은 비활성화 되었을 때, OnDestroy는 파괴되었을 때, OnApplicationQuit은 꺼질 때 시작된다.

 

해제는 이벤트 함수 순위대로 들어가기 때문에, 본래의 순서는 life cycle의 순서가 맞지만 함수 호출 순서에 따라 해제가 다르게 들어갈 수 있다는 점을 알아낼 수 있었다.

 

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

public class Movement : MonoBehaviour
{
    public Vector3 MoveDirection; 
    [SerializeField] private float speed;
    [SerializeField] private Camera cam;

    void Start()
    {
        MoveDirection = Vector3.zero;
        speed = 5f;
        cam = Camera.main; //Tag가 maincamera인 카메라로 접근
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.W)) 
        {
            //transform.Rotate(new Vector3(0, speed * Time.deltaTime, 0)); //왜 new를 해줄까? 계속 새로 만들어서 대입해야 되니깐 메소드 안에서 선언해버려서 넣고 없어지고
            //카메라 끌어서 넣고 상속시키면 카메라도 같이 돌아간다
            transform.position += Vector3.forward * speed * Time.deltaTime; 
        }
        if (Input.GetKey(KeyCode.A)) //else if 로 처리하면 W누르고 A누르면 안먹힘
        {
            transform.position += Vector3.left * speed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.S))
        {
            transform.position += Vector3.back * speed * Time.deltaTime;
            //cam.transform.RotateAround(transform.position, Vector3.up, 100f * Time.deltaTime);
            //cam.transform.Rotate(new Vector3(0, speed * Time.deltaTime, 0)); -> 카메라 기준 회전
        }
        if (Input.GetKey(KeyCode.D))
        {
            transform.position += Vector3.right * speed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.Q))
        {
            transform.position += Vector3.up * speed * Time.deltaTime;
        }
        if (Input.GetKey(KeyCode.E))
        {
            transform.position += Vector3.down * speed * Time.deltaTime;
        }
    }
}

        transform.position += MoveDirection * speed * Time.deltaTime; -> position에 직접 접근

               deltaTime: 전 프레임, 앞 프레임 사이의 시간

        transform.Translate(MoveDirection * speed * Time.deltaTime); -> builtin method를 사용해 접근

두 가지 식 모두 물체의 위치를 바꾸는 식이지만 접근법이 다른것을 확인할 수 있다.

유니티에서는 같은 결과여도 수많은 방식으로 접근이 가능하다.

 

 GetKey vs GetKeyDown 차이

 눌려있는 동안 계속 키가 불러와졌을때 지속적으로 동작 vs 눌렀을 때 한번만 동작한다.

 

getKey로 눌려있는 키보드의 입력을 받아 이동하는 문구를 처리할 수 있다.

 

 

728x90