

유니티는 단일 쓰레드
단일 쓰레드 : 작업을 처리하는 단위가 1개
-> 씬을 넘어갈때 불러오는 작업을 마치지 못하면 씬은 넘어가더라도 움직일 수 없음
이걸 로딩을 사용하여 감추는 것을 페이크 로딩이라 함
페이크 로딩 : 로딩이 99까지 찬 뒤 씬을 멈추는 기능
-> 99이후로는 서서히 로딩하는 방식
-> 컴퓨터마다의 성능차이를 동일 시 하기 위해 사용한다
이전 씬에서 새로운 씬으로 이동할 때, 비동기적으로 씬을 로딩할 수 있다
멀티 쓰레드 : 작업을 병렬적으로 처리 가능

둘 이상의 스레드가 서로의 작업이 끝나기만을 기다리며 작업을 더 이상 진행하지 못하는 상태
멀티 스레드는 한 번에 하나의 스레드만 리소스에 접근할 수 있다
-> 접근하고 잠금(Lock)을 한다는 것
아래의 예시에서 B가 key를 가지고 리소스에 접근하면 잠구기 때문에 다른 A가 접근할 수 없다
-> 근데 만약 점유하고 그대로 쭉 대기한다면?
-> 다른 스레드가 계속 접근할 수 없기 때문에 교착상태 발생

구조 : 접근 지정자 + 클래스 + 클래스 이름 : 상속받는 클래스
public class NewBehaviourScript : MonoBehaviour
MonoBehaviour을 상속받아야만 게임 오브젝트에 스크립트를 넣어줄 수 있다
-> MonoBehaviour는 Behaviour을 상속받은 상태
-> Behaviour는 Component 클래스를 상속받은 상태
유니티는 컴포넌트 패턴을 따르기 때문에, 컴포넌트여야 게임 오브젝트에 넣을 수 있다
-> 즉, 이 스크립트가Monobehavior를 상속받아야만 게임 오브젝트에 넣을 수 있는 것
즉,MonoBehaviour를 상속받지 않는 스크립트라면 게임 오브젝트에 넣을 수 없음
유니티 내에서 스크립트 이름을 변경한 뒤 스크립트 내부의 이름도 바꿔줘야함


UnityEngine : 유니티에서 제공하는 다양한 함수 클래스들을 사용할 수 있다
Collections : C#의 컬렉션 클래스들이 포함된 네임스페이스
-> 리스트, 큐, 스택, 딕셔너리와 같은 일반적인 자료구조 사용가능
생명주기는 순서대로 진행되지만, 우리는 크게 볼 것이다
Awake -> OnEnable -> Start -> FixedUpdate -> Update -> LateUpdate -> OnDisable -> OnDestroy

초기화
Awake / OnEnable / Start
물리
FixedUpdate / OnTrigger / OnCollision
업데이트
Update / LateUpdate
소멸
OnDisable / OnDestroy
Awake
Awake함수란?
게임 오브젝트가 생성되었을 때, 단 한번만 호출되며,
컴포넌트가 비활성화된 상태에서도 호출되는 이벤트 함수입니다.
: 생성자 역할 (값 초기화나, 미리 정의해두는 것)
: 모든 생명 주기 함수에서 가장 먼저 실행된다
: 두 게임 오브젝트에 같은 스크립트를 넣었을 경우, 어떤 오브젝트에 Awake가 먼저 호출되는지는 알 수 없다
-> 실제 실행할때마다 매번 바뀜
-> 스크립트 우선순위를 바꾸면 되지만 선호하지 않는 방법임
이러한 문제를 해결하는 방법은 Awake와 Start를 이용해 초기화 단계를 분리하는 것이다
OnEnableOnEnable 함수란?
게임 오브젝트가 활성화될 때마다 호출되는 이벤트 함수입니다.
: 게임 오브젝트가 활성화 될때마다 호출된다
유니티 가비지 컬렉터는 C#가비지 컬렉터와 달라서 메모리 파편화가 남아있게 되어 메모리 낭비 (C#가비지 컬렉터는 세대별 가비지 컬렉터로 압축이 가능하다)
-> 게임 오브젝트를 생성, 파괴, 생성, 파괴 하지말고 비활성화 시키고 -> 다시 생성할때 다른 위치에서 생성되게 한다
-> 다시 활성화 했을때, 그 위치 그대로 다시 활성화 되기 때문에 다른 위치로 이동 후 활성화
게임 오브젝트 비활성화

StartStart 함수란?
게임 오브젝트가 활성화되었을 때 호출되며, 단 한번만 호출되는 함수로,
컴포넌트가 비활성화 되었을 땐 호출되지 않는 이벤트 함수입니다.
: 스크립트가 비활성화 -> 활성화 하더라도 start는 호출되지 않는다
: 맨 처음부터 활성화되어야만 호출되는 것
(컴포넌트와 게임오브젝트는 다른 말이야.)
: 즉, 컴포넌트가 활성화 된 상태에서 한번 호출되는 것
-> 처음부터 컴포넌트가 비활성화되었다면 호출되지 않는다

FixedUpdateFixedUpdate 함수란?
게임 오브젝트가 활성화되었을 때 호출되며,Time Step에 설정된 값에 따라
일정한 주기로 호출되는 이벤트 함수입니다.
: 정교한 체크가 필요한 (고정된 단위로) 작업에서 사용
-> 물리 관련들에서 사용
-> time step에 지정된 값에 따라 일정한 주기로 호출
-> 이 값은 건드리지 않는 편을 선호한다(알아만 두자)

Update Update 함수란?
게임 오브젝트가 활성화되었을 때 호출되며, 프레임 간격으로 호출되는 이벤트 함수입니다.
: 입력받을때 주로 사용, 물리적인 내용이 없다면 Update문에서 작성해도 상관없다
LateUpdate LateUpdate 함수란?
게임 오브젝트가 활성화되었을 때 호출되며, Update가 끝난 뒤에 호출되는 이벤트 함수입니다.
: 카메라가 오브젝트를 따라다니는 연출 같은거
-> FixedUpdate를 사용하는 게임 오브젝트는 카메라도 Fixed에 해야함
-> LateUpdate는 업데이트 함수가 끝난뒤에 호출되기 때문에, 정교하게 움직이는 오브젝트라면 fixed에
OnDisable
OnDisable함수란?
게임 오브젝트가 비활성화되었을 때 호출되는 이벤트 함수입니다.
OnDestroy
OnDestroy함수란?
게임 오브젝트가 소멸되었을 때 단 한번만 호출되는 이벤트 함수입니다.
Package Manager -> my Assets

Awake() Start() 차이점두 함수의 차이점이 헷갈려서 더 알아보았다
다른 객체의 컴포넌트를 참조하고 싶을 경우를 예시로 들어보자
위에서 봤듯이 두 객체의 Awake함수를 호출하더라도 어떤 것이 먼저 실행될지는 알 수 없다 (매번 호출 순서가 다름)
-> 운이 좋아서 B객체의 Awake 먼저 호출되면 괜찮겠지만, 만약 A객체의 Awake가 먼저 호출된다면?
B객체의 컴포넌트가 초기화되지 않은 상태기 때문에 A객체가 B객체의 컴포넌트를 참조하려고 할 경우 NullReferenceException 오류가 발생!

그럼 Awake와 Start는 주로 어떻게 사용하는가?
Awake에서는 자기 자신의 컴포넌트를 초기화하거나 참조한다
Start에서는 다른 객체의 컴포넌트를 참조한다
-> 컴포넌트는 초기화 된 상태여야지만 사용이 가능하다
Awake는 무조건 Start보다 먼저 실행되기 때문에, 이렇게 초기화를 나눠서 작성하게 되면 초기화 순서 문제를 해결할 수 있다

OnEnable() Start() 차이점OnEnable, Start 모두 컴포넌트가 활성화 되었을 때 호출된다
OnEnable은 게임 오브젝트가 활성화 될때마다 호출됨Start는 게임 오브젝트가 활성화 되있다면 딱 한번 호출됨라이프 사이클 호출 순서에 따르면 OnEnable이 먼저 실행되고 Start가 실행된다
OnEnable은 게임 오브젝트가 활성화 될때마다 호출되기 때문에, 한번만 발생해야하는 초기화 작업에는 적합하지 않다Start에서 초기화 작업이 이루어지는게 효율적OnDisable() OnDestroy() 이벤트 구독 취소OnDisable은 게임 오브젝트가 비활성화 되었을때 & 컴포넌트가 비활성화 될때 호출된다
OnDestroy는 게임 오브젝트가 소멸될때 호출된다
라이프 사이클 실행 순서를 보면 OnDisable이 OnDestroy보다 먼저 실행된다
OnDisable은 이벤트 구독 취소를 할 수 있다
-> 게임 오브젝트가 비활성화 되었어도, 이벤트 구독이 유효할 수도 있음
만약, 이벤트가 등록된 상태에서 OnDestroy()로 게임 오브젝트가 파괴 될 경우 이벤트 구독자로써 메모리에 남게된다 <메모리낭비>
OnDisable을 호출해야만 한다그러니 메모리 누수 방지를 위해서라도
게임 오브젝트를 비활성화 한 뒤OnDisable을 호출하여 구독을 취소하고, 게임 오브젝트를 파괴하여OnDestroy를 호출하고 리소스 해제 및 정리를 해주는 것이 좋다
FixedUpdate() Update() 차이점Update : 스크립트(컴포넌트)가 활성화 상태일 때, 프레임마다 한번씩 호출된다
-> 주기가 일정하지 않아 물리효과가 적용되지 않은 오브젝트의 움직임이나 단순 타이머, 키입력 등을 받을 때 사용한다
FixedUpdate : Time Step에 설정된 값에 따라 일정한 주기로 호출된다
물리 효과가 적용된(Rigidbody) 오브젝트를 조정할 때 사용된다. Update는 불규칙한 호출임으로 물리충돌 검사로는 상대적으로 부적합하다.
참고 자료
https://kukuta.tistory.com/406