Unity - 4. 라이프 사이클

땡구의 개발일지·2025년 4월 26일

Unity마스터

목록 보기
17/78
post-thumbnail

유니티 내부에서 어떤식으로 게임이 동작하는지 알아보자
유니티 - 이벤트 함수의 실행 순서(라이프 사이클)

유니티의 게임 제작 원리

  • 유니티는 게임 오브젝트들로 이루어져 있고, 이들은 속성(컴포넌트) 들을 가짐. 무게, 모양, 재질 등
  • 게임은 오브젝트들의 상호작용을 통해 구현한다

컴포넌트 디자인 패턴

  • 클래스와 비슷한 기능을 한다. 상속탄탄한 구조를 만들 때 쓰기 좋지만, 유연한 대처를 하기 힘들다. 컴포넌트는 그 부분을 해결해준다.
  • 인터페이스와 비슷해 보이지만 다르다. 인터페이스는 클래스에서 구현해야 하는 기능(요구사항). 컴포넌트는 기능을 만들어 둔 단위. 붙여서 활성화 하는 방식
  • 유연성, 비의존적, 독립적 특성을 가지고 잇다
  • 게임 오브젝트에 컴포넌트를 붙였다, 뗐다 하는 식으로 구현한다
  • 점프 구현하기

    • 컴포넌트에는 점프가 없다. 점프를 구현하려면 어떻게 해야될까? 여기서 지금까지 배운 C#이 등장한다
    • 스크립트를 새로 추가해서 컴포넌트로 만든 다음, 게임 오브젝트에 추가하면 점프를 할 수 있다
    • 인벤토리, 경로 탐색 등과 같은 기능들도 이런식으로 구현한다
  • 점퍼 컴포넌트 구현

    public class Jumper : MonoBehaviour
    {
    	public Rigidbody rigid;
    	public float power;
    	void Update()
    	{
    		if(Input.GetKeyDown(KeyCode.Space))
    	    {
    	    	rigid.AddForce(Vector3.up * power, ForceMode.Impulse);
    		}
    	}
    }

    MonoBehaviour

    • Script를 만들면 자동으로 이 클래스를 상속받는다. 컴포넌트의 기본 클래스
    • Object - Component - Behaviour - MonoBehaviour 순으로 상속된다
    • 게임 오브젝트스크립트를 컴포넌트로 연결할 수 있게함

변수 : 정보

직렬화

참고 유니티 - 직렬화

  • 게임 오브젝트파일이나 메모리, 데이터 베이스와 같은 저장할 수 있는 형태로 바꾸는 것을 직렬화 라고 한다

  • 유니티 에서의 직렬화데이터 구조 또는 게임 오브젝트 상태Unity가 보관하고 나중에 다시 복구할 수 있는 포맷으로 변환하는 자동 프로세스

  • 유니티는 게임 오브젝트직렬화를 이용해서 인스펙터 창에 표현을 한다. 실제로 파일을 텍스트 파일로다가 불러오면 게임 오브젝트 들이 직렬화 된 것을 볼 수 있다. 이 직렬화 된 파일을 역직렬화 해서 빌드 한다

  • 직렬화로 표현 가능한 변수

  • 드래그&드롭만 해도 참조 시킬 수 있다

  • 직렬화

    • 데이터 구조 또는 게임 오브젝트 상태를 보관 및 관리하는 용도로 쓰임
    • 인스펙터 창에서 오브젝트의 직렬화된 멤버변수 값을 보여줌
    • 소스코드의 수정 없이 유니티 에디터에서 값을 변경 가능
  • 데이터 직렬화

    • 오브젝트의 멤버변수 값을 확인 또는 변경
    • 오브젝트의 멤버변수 참조를 드래그&드랍 방식으로 연결

표현방법

// C#
public int value;
public float jumpPower;
public bool boolValue;
public int movePower;

// Unity
public Color color;
public Vector3 position;
public Gradient gradient;
public AnimationCurve curve;

// 열거형
public enum Type { Normal,Special}
public Type type;

// 직렬화 가능한 필드의 배열 및 리스트
public int[] array;
public List<int> lists;
public Rigidbody rb;

어트리뷰트

-Atrribute

  • 동작, 게임의 결과물에는 영향을 주지 않음. 에디터에서 편하게 쓰기 위해서 사용하는 기능
  • [] 대괄호 안에 표현
  • 클래스, 속성 또는 함수 위에 쓰는 마커. 에디터 상에서 분류체계로 쓰일 수도 있고, Range의 경우 슬라이드도 가능하다
  • 제목

  • 모아둔 거에 제목을 달아준다
  • 참조타입을 모아두려고 Reference로 제목을 지정했다
[Header("Reference")]
public GameObject go;
public Rigidbody rig;
  • 숨기기

  • public 접근제한자여도 에디터 상에서 숨길 수 있다
[HideInInspector]
public int publicValue;
  • 범위

  • 슬라이드로 조절할 수 있다
  • 최솟값, 최댓값을 입력한다
  • 소숫점이면 double이 기본형이라, float로 쓰고 싶을 경우 f지정자를 사용하거나(10f), (float)와 같은 명시적 형변환을 사용한다
[Range(0, 100)]
public float rate;
  • 대화창 줄 확장

[TextArea(3, 5)]
public string textField;
  • 직렬화영역

  • private 이더라도 에디터에서 수정 가능해짐
[SerializeField]
private int privateValue;
  • 구조체, 클래스

  • 직렬화 가능 속성을 포함 시킨다
[Serializable] 
public struct StructType
{
    public int value1;
    public string value2;
}
public StructType structField;

[Serializable]
public class ClassType
{
    public int value1;
    public string value2;
}
public ClassType classField;

함수 : 기능

  • 유니티 메시지 함수 : 유니티에 있는 메시지 함수면 먼저 불러옴. 특수 함수
  • 이벤트 함수 7종 : 각각의 특정 타이밍 마다 호출하는 함수. 이것들이 메시지 함수

라이프 사이클

  • 일전에 배웠던 렌더 파이프라인을 떠올리면 된다. 이제 거기에 게임 내부의 처리인 Update가 추가된다
  • 기존에는 Start -> 게임 루프(Render - Input - Update - Result) -> End 순으로 배웠다. 유니티에서는 이러한 개념을 이벤트 함수로 나타낸다. 이것이 라이프 사이클이다
  • 게임의 라이프 사이클을 이해하고 적재적소에 필요한 연산을 수행하는 것은 최적화 기법의 기초중의 기초
  • 유니티 에서는 유니티 이벤트 함수들이 라이프 사이클을 이룬다

유니티 이벤트 함수

  • 유니티가 보내는 메시지에 반응하는 함수
  • MonoBehaviour 클래스의 메시지와 같은 이름의 함수가 반응
  • 스크립트는 유니티 엔진이 보내는 메시지를 받아 사건 타이밍을 확인
  • 메시지 함수에서 자신의 행동을 정의하여 기능을 구성
  • 컴포넌트라이프 사이클의 순서에 맞게 만들어야 한다. 라이프 사이클은 이벤트 함수들의 순서다
  • 유니티의 라이프 사이클을 순환하면서 한 프레임씩 출력한다. 라이프 사이클에 있는 모든 함수는 모든 게임오브젝트에 보낸다. 이를 메시지 브로드캐스팅이라고 한다
  • 모든 게임 오브젝트에 메시지 함수를 보내서, 대응 되는 컴포넌트를 가진 게임 오브젝트들이 함수를 수행 한다
  • 유니티의 이벤트 함수 처리 순서

    • 1프레임을 단위로 위 과정을 진행한다
    • 각 순서마다 모든 게임오브젝트들이 대응하는 이벤트 함수를 수행한다. 대응하는 함수가 없을 경우 수행하지 않는다
    • 아예 그냥 통으로 외우자
  • 이벤트 함수 종류

    • 각 오브젝트들은 매 프레임마다 각각의 가지고 있는 이벤트 함수를 라이프 사이클 순서에 맞게 수행한다

      오브젝트 : 게임오브젝트,컴포넌트,스크립트 등 모든 요소들이 오브젝트다

유니티의 이벤트 함수들

  • 아래는 실행 순서다

  • Awake()

    • 오브젝트 생성시 단 1회 수행
    • 스크립트가 씬에 포함 되었을 때 수행한다(비활성화 되어 있어도 수행함)
    • 외부의 상황과 상관없이 자기 자신을 준비시키기 위한 과정에 쓰인다. 외부에서 값을 가져와야 하는 경우에는 Awake()에 쓰지 말고 Start() 또는 OnEnable()에서 쓰는것이 좋다
  • OnEnable()

    • 오브젝트 활성화마다 1회 수행, Update() 이전에 호출됨
    • 보통 이벤트를 붙일 때, 뗄 때 사용한다

    SetActive() : 활성화, 비활성화 바꾸기
    OnEnable() : 활성화 시 1회 호출

    enabled : SetActive(true), SetActive(false)와 같다

  • Start()

    • Awake() 이후 오브젝트의 생성 및 활성화시 첫 1회만 호출
    • 최초 Update 직전에 1회 수행함
    • 스크립트가 비활성화 되어잇으면 수행하지 않음
    • 외부 게임 상황을 갖다 써야 하는 경우에 쓴다
  • FixedUpdate()

    • Physics
    • 업데이트 보다 우선권을 갖는다
    • 다 수행하고 시간이 남으면 업데이트로 넘어가는 것이다
    • 시간 내에 FixedUpdate 내용을 수행하지 못하면, Update로 넘어가지 않는다...
    • FixedUpdate 전 시간을 확인해서 0.02초가 지났으면 Physics 쪽만 진행. 안지났으면 넘어가고 Logic(Update)쪽 진행을 한다
    • 일정한 시간(기본 1초에 50번) 마다 호출
    • Update와 다르게 프레임당 연산과 단위시간이 일정
    • 물리엔진과 같이 게임의 프레임과 무관하게 일정해야 하는 작업에 사용
    • 게임로직 등 연산이 많은 작업을 FixedUpdate에 구현하지 않아야 함
  • Update()

    • 매 프레임마다 1회 호출되며, 오브젝트스크립트의 생존 및 활성화 시에만 수행함
    • 연산이 많은 게임 로직 등, 핵심로직 을 쓰는 경우에는 업데이트를 넣는다. FixedUpdate에 넣지 않도록 해야한다
  • Coroutine

    • 연산 수행시 Update() 이후에 수행하지만 실행과 정지를 사용자가 자유롭게 사용할 수 있는 서브루틴
  • OnDisable()

    • 오브젝트 비활성화시 1회 호출, Update() 이후에 호출됨
    • OnEnable()과 마찬가지로 이벤트를 붙일 때, 뗄 때 많이 사용된다
  • OnDestroy()

    • 오브젝트 파괴 시 1회 호출
  • LateUpdate()

    • 게임의 프레임 마지막마다 호출

    • 씬의 모든 게임오브젝트의 Update가 진행된 후 호출

    • 역할 : 게임프레임의 진행 결과가 필요한 동작이 있는 기능 구현

    • 애니메이션 같은 곳에 쓰인다

[RuntimeInitializeOnLoadMethod]

  • 씬에 포함시키지 않아도 알아서 실행되어서 초기설정을 진행할 수 있다
  • Awake()보다 먼저 실행 되어서, 랜덤으로 Awake() 되는 게임 오브젝트들 보다 우선적으로 깨워서 초기화를 할 수 있다. 싱글톤과 궁합이 좋다
[RuntimeInitializeOnLoadMethod]
public void Init()
{
	초기화 내용
}
profile
개발 박살내자

0개의 댓글