Unity C# > 이벤트 함수 정리
카테고리: UnityDocs
태그: Unity Game Engine
공부하면서 알게 된 이벤트 함수들을 정리한 문서입니다.😀
- 유니티 공식 매뉴얼 https://docs.unity3d.com/kr/current/Manual/UnityManual.html
- Scripting Overview http://www.devkorea.co.kr/reference/Documentation/ScriptReference/index.html
이벤트 함수
실수로 이름 오타나면 절대 실행 안된다!! (당연한 얘기지만.. 😂)
- 오타여도 사용자 지정 함수인 줄 알고 잡아주지도 않음 ㅠ ㅠ OnTriggerEnter 인데 onTriggerEnter 라고 소문자로 써서 계속 실행되지 않았었는데 한참을 헤맸다…
- 이름 실수 하지 않도록 주의 하자!!
이벤트 함수 실행 순서
[유니티 공식 문서 <이벤트 함수의="" 실행="" 순서=""> 참고](https://docs.unity3d.com/kr/2018.4/Manual/ExecutionOrder.html#InBetweenFrames)이벤트>
👩🦰 void Start()
- 컴포넌트 초기화 부분
- 스크립트가 붙은 해당 오브젝트가 처음으로 생성 되는 그 순간 and 오브젝트 활성화 상태일 때 최초로 1 회 실행된다.
- 유니티가 Start 메세지를 브로드캐스팅 하여 뿌려 온 컴포넌트들을 각자 구현된 Start 내용대로 초기화 시킨다.
- 유니티는 게임 시작할때 Start 메세지를 뿌린다.
- 스크립트가 붙은 해당 오브젝트가 처음으로 생성 되는 그 순간 and 오브젝트 활성화 상태일 때 최초로 1 회 실행된다.
- Awake() 후 + Update() 전에 1회 동작하는 이벤트 함수다.
- 오브젝트가 최초 생성될 때 실행 순서
- Awake() 👉 OnEnable() 👉 Start()
- Awake 와의 차이점
- 둘 다 오브젝트가 생성될 때(스크립트가 최초로 실행될 때) 최초 1회 실행된다는 점에서 같다.
- 그러나
- Awake() 👉 코루틴 실행이 안된다. Start()보다 먼저 실행된다.
- Start() 👉 코루틴 실행이 가능하다.
- OnEnable 와의 차이점
- OnEnable 👉 오브젝트가 ‘활성화’될 때마다 실행된다.(꺼졌다가 켜졌을 때 OR 오브젝트가 최초 생성될 때) Start()보다 먼저 실행된다.
- Start() 👉 오브젝트가 최초 생성될 때 1회 실행
👩🦰 void Awake()
- Start()와 비슷한데 Start()보다도 먼저 실행되는 시작 함수다.
- Start 함수의 이전 및 프리팹의 인스턴스화 직후에 호출
- 생성 하자마자 들어가는 1회 동작 함수
- Start 메세지보다 더 빨리 호출되므로 다른 스크립트들의 Start보다 더 빨리 실행되야 하는 내용이 있으면 Awake에 구현하면 된다.
- 오브젝트가 최초 생성될 때 실행 순서
- Awake() 👉 OnEnable() 👉 Start()
- Start 와의 차이점
- 둘 다 오브젝트가 생성될 때(스크립트가 최초로 실행될 때) 최초 1회 실행된다는 점에서 같다.
- 그러나
- Awake() 👉 코루틴 실행이 안된다. Start()보다 먼저 실행된다.
- Start() 👉 코루틴 실행이 가능하다.
👩🦰 void Update()
- 1초에 수십번씩 자신의 상태를 갱신하고 주기적으로 계속 실행
- 외부에서 직접 찾아 실행할 필요 없음.
- 스스로 매 프레임마다 실행 됨.
- 프레임 속도는 환경마다 다르기 때문에 물리 처리를 update() 함수에서 해주면 환경에 따라 물리 처리 오차가 발생할 수 있어 비추천
👩🦰 void FixedUpdate()
디폴트로 0.02초 (초당 50회)마다 실행된다.
- Update()처럼 매번 반복 실행되나 프레임에 기반하지 않고 어떤 고정적이고 동일한 시간에 기반하여 실행된다.
- Update()와의 차이점
- Update()는 화면 한번 깜빡일때마다 실행되서 렉걸리거나 환경이 안좋거나 하면 그만큼 Update()도 적게 실행되지만
- Fixedupdate()는 환경에 상관없이 무조건 실행 횟수를 지킨다. 정해진 수만큼 무조건 실행 함
- Update()와의 차이점
- 프레임과 상관없이 고정적인 시간마다 실행되기 때문에 환경에 상관없이 물리처리를 오차 없이 실행시킬 수 있다.
- 물리처리는 FixedUpdate() 안에서 해주기.
Time.fixedDeltaTime의 시간 간격으로 실행이 된다. 디폴트로Time.fixedDeltaTime값은 0.02f 이다.
👩🦰 void LateUpate()
- 유니티 함수로, 매 프레임마다 실행되지만 Update()함수 보다 늦게 실행된다.
- Update() 함수 실행이 다 끝난 후에, Update()함수의 종료 시점에 맞춰서 LateUpdate() 가 실행된다.
- 예를 들어 캐릭터의 이동 방향 계산은 Update() 에서 끝내준 후,Update()에서 계산 끝낸 캐릭터의 이동 방향에 따라 LateUpdate()에서 카메라가 캐릭터를 따라가도록 하는 식으로 구현한다.
- ⭐ 만약 Update() 함수로 했다면, 📜PlayerController.cs 에서 플레이어의 위치와 회전값을 업데이트 하는 것과 📜CameraController.cs 에서 플레이어의 위치와 회전을 업데이트 하는 것이 같은 Update()로서 동시에 섞여 실행되기 때문에 아직 업데이트 되지 않은 플레이어의 위치와 회전값으로 카메라가 따라가게 되는 프레임이 발생할 수 있다.
- 정확히 말하자면 📜PlayerController.cs 에서 `플레이어의 위치와 회전값을 업데이트 하는 OnKeyboard() 함수는 액션에 등록되어 📜Manager.cs 의 Update() 에서 실행 됨
- 따라서 반드시 플레이어의 위치와 회전값을 업데이트 하는 일은 📜PlayerController.cs 에서 먼저 이루어지고 난 후에 업데이트 된 플레이어의 위치와 회전 값을 가지고 카메라의 위치와 회전 값을 업데이트 해야 한다.
- 그래서 📜CameraController.cs 에선 카메라의 위치와 회전값을 업데이트 하는 일을 Update 보다 더 늦게 호출되는 LateUpdate() 안에서 한다. 📜PlayerController.cs 에서 플레이어의 위치와 회전값 업데이트를 마친 후에 그 업데이트 된 값을
_delta여유를 두고 따라가도록 하기 위하여
- 그래서 📜CameraController.cs 에선 카메라의 위치와 회전값을 업데이트 하는 일을 Update 보다 더 늦게 호출되는 LateUpdate() 안에서 한다. 📜PlayerController.cs 에서 플레이어의 위치와 회전값 업데이트를 마친 후에 그 업데이트 된 값을
- ⭐ 만약 Update() 함수로 했다면, 📜PlayerController.cs 에서 플레이어의 위치와 회전값을 업데이트 하는 것과 📜CameraController.cs 에서 플레이어의 위치와 회전을 업데이트 하는 것이 같은 Update()로서 동시에 섞여 실행되기 때문에 아직 업데이트 되지 않은 플레이어의 위치와 회전값으로 카메라가 따라가게 되는 프레임이 발생할 수 있다.
👩🦰 void OnTriggerEnter(Collider other)
- OnTriggerEnter :
Trigger인 Collider와 충돌할 때 자동으로 실행된다.Is Trigger가 체크된 Collider와 충돌하는 경우 발생되는 메세지- 사실 충돌하는 두 오브젝트 중 하나만 Trigger 라도 두 오브젝트 모두 이 함수가 실행된다.
- 즉 물리적 충돌은 일어나지 않고 닿기 만 하더라도, 뚫고 지나가지만 그래도 이벤트 발생은 시켜야 하는 경우.
- 오브젝트끼리 충돌하면 유니티에서 OnTriggerEnter 메세지를 충돌한 오브젝트들 에게 브로드캐스팅 한다.
- 충돌한 두 오브젝트끼리는 서로 독립적이고 연관이 없으니 서로 충돌한 사실을 모르지만 두 오브젝트가 충돌하면 유니티에서 두 오브젝트에게 OnTriggerEnter 메세지를 뿌리므로 두 오브젝트는 OnTriggerEnter 함수 안에 구현한 내용대로 충돌 처리를 한다.
- 유니티는 충돌한 상대 오브젝트의 정보를
Collider타입의other가 참조하도록 넘겨준다.- 충돌한 상대 오브젝트에 붙어있는 Collider 컴포넌트
Collider컴포넌트 👉🏻 물리적 표면
- 충돌한 상대 오브젝트에 붙어있는 Collider 컴포넌트
- 이 스크립트가 붙은 오브젝트(나 자신)가 다른 오브젝트와 충돌시
OnTriggerEnter이벤트가 발생하기 위한 조건. 아래 조건을 전부 만족해야 이 이벤트가 발생할 수 있다.- 내가 혹은 상대방 둘 중 하나는 꼭 Rigidbody 컴포넌트를 가지고 있어야 한다.
IsKinematic체크 여부는 상관 없다.
- 나 그리고 상대방 둘 다 모두 Collider 컴포넌트를 가지고 있어야 한다.
- 단, 둘 중 하나라도
IsTrigger는 반드시 켜져 있어야 함
- 단, 둘 중 하나라도
- 내가 혹은 상대방 둘 중 하나는 꼭 Rigidbody 컴포넌트를 가지고 있어야 한다.
void OnTriggerEnter(Collider other)
{
Debug.Log("충돌 발생!");
}
- 위 스크립트가 붙어있는 오브젝트에서 충돌이 일어날 때마다 콘솔창에 “충돌 발생” 메세지 출력.
OnTriggerEnter, OnTriggerExit, OnTriggerStay의 차이
- OnTriggerEnter :
Enter는 충돌하는 순간 - OnTriggerExit :
Exit는 떼어지는 순간. 더 이상 붙어 있지 않는 순간. - OnTriggerStay :
Stay는 충돌 중인, 붙어 있는 동안.
👩🦰 void OnCollisionEnter(Collision other)
- OnCollisionEnter : Trigger가 체크되지 않은 일반 Collider를 가진 오브젝트와 충돌한 경우 자동으로 실행된다.
Collider와Collision의 차이Collision은 충돌한 상대 오브젝트에 대한 많은 정보를 담고 있다. 나랑 부딪친 오브젝트의 Transform, Collider, GameObject, Rigidbody, 상대 속도 등등이Collision에 담겨서 들어 온다. 물리적인 정보가 더 많이 들어 있다.Collider는Collision보다는 담고 있는 정보가 적다. 물리적인 정보는 담고 있지 않아서.
private void OnCollisionEnter(Collision collision)
{
Debug.Log(collision.gameObject.name);
}
- 이 스크립트가 붙은 오브젝트(나 자신)가 다른 오브젝트와 충돌시
OnCollisionEnter이벤트가 발생하기 위한 조건. 아래 조건을 전부 만족해야 이 이벤트가 발생할 수 있다.- 내가 혹은 상대방 둘 중 하나는 꼭 Rigidbody 컴포넌트를 가지고 있어야 한다.
IsKinematic은 꺼져 있어야 함- 즉, 둘 중 하나는 꼭 충돌로 인한 물리적인 힘에 영향을 받을 수 있는 상태여야 함. 그래서 OnCollisionEnter는 뭔가 물리적인 힘에 의한 충돌 느낌
- 나 그리고 상대방 둘 다 모두 Collider 컴포넌트를 가지고 있어야 한다.
IsTrigger는 꺼져 있어야 함
- 내가 혹은 상대방 둘 중 하나는 꼭 Rigidbody 컴포넌트를 가지고 있어야 한다.
FPS 게임 같은데서 총알이 사람에게 맞으면 총알 입장에선 사람 오브젝트 정보가 Collision으로 들어오게 되므로 그 사람의 체력을 깎거나 하는 처리를 할 수 있다.
👩🦰 void OnEnable()
해당 스크립트(컴포넌트) 혹은 스크립트가 붙어있는 오브젝트가 활성화 될 때마다 자동으로 실행된다.
컴포넌트가 꺼져 있다가 켜지는 상태마다 발동된다. Start()와 비슷하지만 Start()는 게임 시작시 한번 발동되는 반면 OnEnable()은 컴포넌트가 꺼져있다가 켜질 때마다 1회씩 실행된다.
- 게임 시작되자마자
enabled = true상태인 컴포넌트들에게 발동 - 게임 도중에
enabled = false이다가enabled = true가 되는 컴포넌트들에게 발동- 오브젝트 끌 때는
SetActive(false) - 컴포넌트나 스크립트를 끌 때는
enabled = false
- 오브젝트 끌 때는
- 오브젝트가 최초 생성될 때 실행 순서
- Awake() 👉 OnEnable() 👉 Start()
- Start 와의 차이점
- OnEnable 👉 오브젝트가 ‘활성화’될 때마다 실행된다.(꺼졌다가 켜졌을 때 OR 오브젝트가 최초 생성될 때) Start()보다 먼저 실행된다.
- Start() 👉 오브젝트가 최초 생성될 때
- 둘 다 코루틴 사용이 가능하다.
👩🦰 void OnDisable()
해당 스크립트(컴포넌트) 혹은 스크립트가 붙어있는 오브젝트가 비활성화 될 때마다 자동으로 실행된다.
컴포넌트가 켜져 있다가 꺼지는 상태마다 발동된다.
👩🦰 void OnDestroy()
오브젝트가 Destroy 될 때 자동 호출되는 이벤트 함수다. 마치 소멸자 같은 것.
👩🦰 void OnAnimatiorIK()
- 애니메이션의 관절 꺾는 IK 정보가 갱신될 때마다 발동되는 이벤트 함수.
- Animator와 관련된 이벤트로 애니메이터가 붙어있는 오브젝트만 이 이벤트 함수를 동작시킬 수 있다.
- 씬상에 존재하기는 하나 아직 보이지는 않는 그런 오브젝트들을 기즈모를 통해 보여줌으로서 위치 조정을 쉽게 해주는 등등 개발자 편의를 돕는다.
👩🦰 void OnDrawGizmos()
- 유디터 에디터 내에서만, 씬 상에서만 매 프레임 기즈모를 그리는 역할을 한다.
- 이 함수가 소속된 스크립트가 컴포넌트로서 붙은 오브젝트가 Scene 화면 상에서 항상 보이도록 하는 이벤트 함수.
- 씬상에 존재하기는 하나 아직 보이지는 않는 그런 오브젝트들을 기즈모를 통해 보여줌으로서 위치 조정을 쉽게 해주는 등등 개발자 편의를 돕는다.
👩🦰 void OnDrawGizmosSelected()
- 유디터 에디터 내에서만, 씬 상에서만 Hierarchy 창에서 선택된 오브젝트에 한해서만 매 프레임 기즈모를 그리는 역할을 한다.
- 이 함수가 소속된 스크립트가 컴포넌트로서 붙은 오브젝트가 선택됐을때만 보이도록 하는 이벤트 함수.
👩🦰 사용자 지정 이벤트
해당 이벤트에 원하는 함수가 들어 있는 스크립트들을 드래그 해 와서 발동시킬 함수들을 선택하면 해당 이벤트를 발동시켰을 때 등록한 함수들도 다 같이 실행된다.
using UnityEngine.Events;
public UnityEvent myEvent;
myEvent.invoke();
- using UnityEngine.Events;
- myEvent라는 이름의 사용자 지정 이벤트 변수를 선언한다.
- 이제 유니티에서 myEvent 슬롯이 열릴텐데 여기에 원하는 스크립트를 드래그 앤 드롭해준다.
- 원하는 함수들을 선택한다.
- invoke() 해주면 등록한 함수들이 모두 실행된다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글남기기