유니티 생명주기 (Unity Lifecycle)

게임이 진행되는 정도에 따라 유니티에서 게임 오브젝트스크립트특정한 실행 흐름을 따른다.

유니티의 스크립트는 MonoBehaviour에서 상속 받아 생명주기 함수를 사용하는 것이다.

 

아래의 내용은 생명주기의 순서를 한눈에 정리한 것이지만

모든 메서드를 작성한 것이 아닌 자주 사용하는 메서드들을 정리한 것이다.

Unity LifeCycle의 중요 함수들


핵심적인 생명주기 함수와 역할

1. 객체 생성과 초기화

- Awake() :  가장 먼저 실행 

  • 오브젝트가 Scene에 생성될 때 가장 먼저 실행된다.
  • (스크립트가 활성화 되면 가장 먼저 호출된다고 생각하면 된다)
  • 비활성화(SetActive(false))된 오브젝트도 실행되는 특징이 있다.

- OnEnable() :  오브젝트 활성화 시 실행 

  • 게임 오브젝트가 활성화될 때(SetActive(true)) 실행된다.
  • Awake() 이후, 오브젝트가 활성화될 때마다 호출된다. (다시 활성화해도 호출됨)

- Start() :  Awake이후 1번만 실행 

  • Awake() 다음에 스크립트 활성화된 후 & 첫 번째 프레임이 시작되기 직전한 번만 실행됨.
  • 모든 Awake가 실행된 이후 실행된다

 

2. 게임 실행 (프레임 단위 업데이트)

- Update() :  매 프레임 호출 

  • 매 프레임마다 호출되는 메서드.
  • 게임의 로직이나 오브젝트의 상태를 업데이트 하는데 이용된다.

- FixedUpdate() :  물리적 연산 

  • Update()와 다르게 고정된 시간 간격으로 실행된다. (기존 0.02초, 임의로 조절 가능)
  • 물리적 연산이 필요할 경우 사용되는 메서드이다.

- LateUpdate() :  Update 이후 마지막 실행 

  • 모든 Update()가 실행 후 호출된다.
  • 후처리 작업카메라 트래킹 등 주요 동작 업데이트 이후 실행되어야 하는 코드를 작성한다.

 

3. 오브젝트 상태 변화 (비활성화 또는 파괴 시)

- OnDisable() :  오브젝트 비활성 

  • 오브젝트가 비활성화될 때 실행됨 (SetActive(false)).

- OnDestroy() :  오브젝트 파괴 시 실행 

  • 오브젝트가 파괴될 때, 즉, Destroy(gameObject)로 제거될 때 호출된다.

 

4. 게임 종료

- OnApplicationQuit()

  • 게임이 종료될 때 호출됨.
  • 데이터 저장, 로그 기록 등의 마무리 작업을 수행할 때 사용한다.

5. 그 외 메서드

- OnTriggerXXX

  • 게임 내 Trigger 이벤트(강제 실행) 발생시 호출된다
  • OnTriggerEnter, OnTriggerStay, OnTriggerExit

- OnCollisionXXX

  • 게임내 Collision 이벤트(충돌) 발생 시 호출된다.

- 간단 정리

Scene에서 게임이 처음 시작되면

1. 객체를 생성하고 초기화 작업을 한 후 (Awake, OnEnalbe, Start)

2. 매 프레임마다 반복 실행을 하면서 (Update, FixeUpdate, LastUpdate)

3. 오브젝트의 상태 변화를 감지한다. ( OnDisable, OnDestroy )

4. 마지막으로는 게임이 종료된다. (OnApplicationQuit)


- 코루틴(Coroutine)에 대해

Update와 Coroutine의 간단요약

 

생명주기와 더불어서 유니티로 게임을 개발한다면 필수적으로 알면 좋은 내용이다.

일반적인 코루틴은 Update 함수가 반한된 후 실행되며 Update와 비슷하게 반복적인 작업을 할 때 사용하는 기능이지만

Update와 차이점은 시간이 걸리는 작업비동기적으로 사용할 때 사용한다

 

 

< 코루틴 사용 예시 >

 1. 애니메이션이나 이펙트 연출 후 동작할 때 (몬스터 처치 후 서서히 사라지는 효과)

 2. 일정한 간격으로 반복할 때 (3초마다 1번 실행)

 3. 시간이 지나면서 변해야 하는 값이 있을 때 (체력이 서서히 회복 UI 효과)

 4. 비동기적으로 작업을 해야할 때 (3초 후 실행 처럼 일정 시간 이후 특정 이벤트 실행)

 5. 네트워크에서 요청 처리 작업을 할 때 (서버에서 데이터를 받고 대기 시간 동안 다른 작업 수행)

게임에는 아이템, 마법진, 포탈 등 다양한 게임 오브젝트가 존재하며,
이러한 오브젝트는 플레이어와 닿으면 사용자와 상호작용을 할 수 있어야 한다.

 

예시로 플레이어 캐릭터를 하나 만들고 움직이는지 테스트를 해본 뒤 간단하게 구현해본다.

 

유니티에서 프로젝트는 3D로 프로젝트 생성한 후

Hierachy(하이어라키)에서 3D Object > Cube로 간단한 바닥 지형을 만든다.

플레이어는 간단히 Hierachy(하이어라키)에서 3D Object > Capsule 을 하나 생성해서 만들어준다.

 


플레이어(캡슐) 간단 구현하기

 1. 플레이어는 테스트를 위해 캡슐(Capsule)로 선택한다.

Hierarchy 창 우클릭 > 3D Object > Capsule 선택
플레이어 캡슐에 Add Component로 Rigidbody 를 붙인다

 

+ 리지드바디(RigidBody)란?

Rigidbody의 속성

유니티에서 GameObject가 물리적 동작을 할 수 있게 하는 컴포넌트

리지드바디는 유니티에서 필수적으로 사용되는 요소라 파악해 두면 유용하다

캡슐이 이동 중에 넘어질 수도 있으므로 Freeze Rotation의 Y값만 체크해 주자.

 

유니티 공식문서에서 살펴보면 큰 도움이 된다.

 

https://docs.unity3d.com/kr/2019.4/Manual/class-Rigidbody.html

 

리지드바디 - Unity 매뉴얼

Rigidbody 는 GameObject 가 물리 제어로 동작하게 합니다. 리지드바디는 힘과 토크를 받아 오브젝트가 사실적으로 움직이도록 해줍니다. 리지드바디가 포함된 모든 게임 오브젝트는 중력의 영향을

docs.unity3d.com

 

 

2. 캡슐(플레이어)를 움직이기 위해 스크립트를 생성한 뒤 플레이어 코드를 만들고 플레이어에 추가한다

Project 우클릭 > Creat > C# Script

주의!) C# Script 생성하고 바로 이름을 만들어줘야 된다. 생성하고 나서 이름을 바꿔주면 Unity에서 바꾸기 까다롭다.

생성한 플레이어 코드(Player.cs)를 캡슐(플레이어)에 컴포넌트로 붙인다

플레이어 코드는 간단하게 키보드에서 방향키를 입력받아서 움직일 수 있도록 구현해보자!

 

 

PlayerTest.cs

public class PlayerTest : MonoBehaviour
{
    [SerializeField]
    private float moveSpeed = 100f;

    Rigidbody myRigid;

    private void Awake()
    {
        myRigid = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        KeyboardMove();
    }

    private void KeyboardMove() 
    {        
        Vector3 moveHorizontal = transform.right * Input.GetAxisRaw("Horizontal");
        Vector3 moveVertical = transform.forward * Input.GetAxisRaw("Vertical");
        Vector3 moveDirection = (moveHorizontal + moveVertical).normalized;

        Vector3 velocity = moveDirection * moveSpeed * Time.deltaTime;
        myRigid.MovePosition(transform.position + velocity);
    }

}
Input.GetAxisRaw("Horizontal");
Input.GetAxisRaw("Vertical");

 

유니티에서는 Horizontal(수평), Vertical(수직)을 통해서 키보드의 방향키 입력이 이미 적용되어있다.

이제 Unity에서 게임 실행 시 잘 움직이는지 한번 테스트 해보자!


이벤트 영역 만들기

1. 영역 스크립트(Area.cs) 생성

잘 움직이는지 성공했다면 이번엔 영역을 담당하는 코드를 만들어 보자.
영역을 담당하는 c# 스크립트(Area.cs)를 생성하고 코드를 작성한다.

 

public class Area : MonoBehaviour
{
    private bool isInside = false;
    
    void Update()
    {
        if (isInside)
        {
            Debug.Log("플레이어가 들어왔습니다!");
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            isInside = true;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            isInside = false;
        }
    }
}

 

영역 코드에서는 유니티에서 게임 오브젝트의 Tag 중 Player 태그에만 반응하도록 작성했다

그러므로 캡슐의 태그값을 Player변경해주자

 

 

 

2. 영역 이벤트 테스트

영역 코드가 잘 작동되는지 확인하기 위해서 간단한 테스트를 진행해 보자!

 

하이어라키 창에서 Create Empty를 생성하고 영역 스크립트를 넣고 Add Component로 Box Collider 추가한다

Hierachy 창 우클릭 > Create Empty 선택 > Empty 오브젝트 생성됨. 생성된 오브젝트에 Box Collider를 추가한다

 

Box Collider의 속성값에서 Is Trigger를 활성화 시킨다.

Is Trigger 활성화, 영역 스크립트 추가

 

+ 콜라이더(Collider) 컴포넌트란?

콜라이더라충돌이라는 뜻을 가지고 있다.

즉, 물리적인 상호작용(접촉, 충돌...)의 모든것을 관리하는 컴포넌트라고 생각하면 편하다.

보이지 않는 게임 오브젝트의 충돌도 물론 관리하기에 투명한 영역에 들어오면  이벤트가 발생한다.

 

https://docs.unity3d.com/kr/2021.3/Manual/CollidersOverview.html

 

콜라이더 - Unity 매뉴얼

Collider 컴포넌트는 물리적 충돌을 위해 게임 오브젝트의 모양을 정의합니다. 보이지 않는 콜라이더는 게임 오브젝트의 메시와 완전히 똑같을 필요는 없습니다. 메시의 대략적인 근사치로도 효

docs.unity3d.com

 

 

3. 실행 테스트 결과

영억에만 들어올 때만 Debug.Log에서 출력되는 것을 확인할 수 있다

 

테스트 결과: Area 영역에만 들어올때만 실행되고 나가면 실행된다.


학습한 내용으로 활용할 수 있는 내용들

게임에서는 수많은 범위와 충돌이 존재하는데 공격의 범위, 스킬의 범위, 폭발의 범위 뿐만 아니라

특정 영역의 범위, 적 캐릭터의 인지 범위 등 눈에 보이지 않는 오브젝트에서도 범위가 존재하며

범위 내에 들어오면 충돌이 발생해 이벤트를 실행할 수 있다.

 

예를 들어 떨어진 아이템을 습득하는 것도 아이템 습득 범위 내에서만 습득 할 수 있거나

포탈 범위 내에 들어오면 다른 지역으로 이동 할 수 있는 것도 이 내용을 활용해서 구현할 수 있다.

+ Recent posts