왜.... 오셨나요?

부끄러워요

개발관련공부자료

유니티 기술 면접2

와피했는데 2023. 10. 10. 18:19

1. 유니티 이벤트 함수

초기화단계(Awake -  OnEnalble - Start)  => 물리(FixedUpdate) => 그래픽로직(Update - LateUpdate) => 해체 단계(OnDisable - OnDestroy) 

: 유니티 이벤트 함수들은 있으면 실행되고 없으면 실행이 안되는 방식으로 작동하는데 Script내에 이벤트함수가 있다면 유니티가 해당 문자열을 읽고 동작시킨다(매세지브로드케스팅)

: 유니티는 메세지브로드케스팅 기능으로 Object클래스를 상속 받는 Monobeh가 다른 클래스에 기본적으로 상속되어 있는데 상속된 Script는 유니티의 지배하에 메세지브로드케스팅의 대상이 되어 메세지를 받고 해당 함수가 있다면 동작시키고 아니면 무시한다.

: 메세지브로드캐스팅 방식이 채택된 이유는 유니티는 컴포넌트 구조되 된 상속구조를 갖고있기 때문에 메세지를 통해 이벤트를 발생하는 식의 방식을 택했다.

 

1-1.

성능이 좋지 못한 디바이스의 경우 30프레임 나오는 Updata가 FixedUpdate에서는 50이 나오게 해야할경우

: FixedUpdata는 Update와 상관없이 동작하기 때문에 정해진 프레임을 맞춰 동작하는데 Update가 30프레임으로 밀리면 FixedUpdate는 상관없이 50프레임으로 보완해서 동작된다.

 

1-2.

Awake와 Start의 차이점

: Awake는 첫 프레임이전의 컴파일 당시 초기화 되는 이벤트함수임

스크립트가 씬에 포함되었을 때 1회 호출되는 함수
스크립트가 비활성화 되어 있는 경우에도 호출됨
역할 : 스크립트가 필요로 하는 초기화 작업 진행
(게임상황과 무관한 초기화 작업), (순서상관없는 상황)
ex) 데이터 초기화, 컴포넌트 연결

 

: Start는 첫프레임(첫Update)이 시작될때 초기화 되는 이벤트함수임
스크립트가 씬에 처음으로 Update하기 직전에 1회 호출됨
스크립트가 비활성화된 경우 호출되지 않음
역할 : 스크립트가 필요로 하는 초기화 작업 진행
(게임상황이 영향을 줄 수 있는 작업)
ex) 몬스터의 플레이어 타겟선정

 

- 공통점 : 게임오브젝트가 처음으로 초기화작업

 

1-3. FixedUpdate - Update - LateUpdate의 차이점

- Update : 게임의 프레임마다 호출

역할 : 핵심 게임 로직 구현

 

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

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

 ex) 플레이어의 위치가 결정된 후에 카메라의 위치 설정

 

- FixedUpdate : 유니티의 물리설정 단위시간마다 호출 (기본 1초에 50번)
Update와 다르게 프레임당 연산과 단위시간이 일정

단, 게임로직 등, 연산이 많은 작업을 FixedUpdate에 구현하지 않아야 함
역할 : 성능과 프레임 드랍에 영향을 받지 않아야 하는 작업
ex) 물리적 처리

 

- FixedUpdate를 사용하는 경우 : 프레임드랍같은 프레임 이슈가 있을때 생기는 오브젝트의 물리적인 처리 오류를 보완하기 위해 프레임을 단위시간으로 동작하는 FixedUpdate를 사용하여 물리적인 처리를 한다. 

 

- FixedUpdate의 단위시간 이전에는 FixedUpdate를 넘어 Update를 실행시키고 물리시간이 흘렀으면 FixedUpdate를 우선처리 한다.

ex) 0.02s > p {Update 먼저}, 0.02s <= p { FixedUpdate 우선처리}

 

2. Coroutine

- 작업을 다수의 프레임에 분산할 수 있는 비동기식 작업
- 반복가능한 작업을 분산하여 진행하며, 실행을 일시정지하고 중단한 부분부터 다시시작할 수 있음
- 단, 코루틴은 스레드가 아니며 코루틴의 작업은 여전히 메인 스레드에서 실행

- 코루틴이 싱글스레드에서 작업하는 이유는 게임은 순서와 상관없는 작업은 하면 안되는 이유가 있기 때문이다 그 이유는 동시 작업을 하면 공유자원에 대한 결과 오류가 생기기 때문이다

 

-멀티스레드의 공유자원 오류 문제를 해결하기 위한 방법 : 뮤텍스, 세마코어 등 방법을 사용해서 동시작업중 먼저 끝난 작업에 대해서 lock(소유권)을 걸어서 상호동작을 못하게 막다가 다른 동유자원 작업이 끝날때 풀어준다 하지만 이러한 방법들을 사용할경우 게임에서는 1초에 60프레임 같은 동작을 못하기 때문에 싱글스레드를 사용하여 분산처리를 한다.(오버헤드 발생 주의)

 

- 게임의 메인로직은 싱글스레드, 멀티스레드 그이외 필요할경우(공유자원은 안쓸경우)

 

3. 유니티 .Mata파일

- Meta : 에셋 폴더에 텍스처 같은 에셋을 저장하면 Unity가 먼저 새 파일이 추가되었음을 인식하는데 여기서  Asset을 식별할 수 있게 하는 고유한 값(ID)과, 해당 Asset에 대한 Inspector Property 값을 저장하는 파일이 Asset이름.mata파일이다 .mata파일은 Asset파일과 함께 담긴다. ID들로  드래그앤 드롭하거나, 오브젝트 필드 옆에 있는 오브젝트 피커를 사용하여 선택하도록 해주는 특수 기능을 지원합니다.

 

4. 프로파일러 사용

- 게임오브젝트가 늘때마다 프레임 저하를 일으킬 경우같이 프레임 관련 성능 문제를 해결하기 위해서 프로파일러를 이용하여 문제를 해결할 수 있습니다 프로파일러는 유니티에서 게임의 상태창 같은걸로 GPU, CPU, 렌더링 및 오디오 성능 등 게임 실행중 일어나는 것들을 분석하여 수치화 해서 보여줍니다 이걸 이용하여 프레임 단위로 수치화된 정보들을 보고  스크립트 실행, 렌더링, 물리 연산 등에 소요된 시간을 확인하여 오버헤드가 큰구간, 메모리 부족 등 프레임드뢉을 일으키는 원인을 찾는데 많은 도움을 줍니다.

프레임이슈를 일으킨 구간에 가서 원인의 함수를 찾을수도 있음

 

5. 파티클 시스템 : 여러 물리적인 동작을 하긴보단 하나의 파티클을 사용하는 것이 성능에 도움이 될수있음

 

6. 스프라이트 아틀라스 : 스프라이트 아틀라스(Sprite Atlas) 는 여러 개의 텍스처를 단일 텍스처로 결합하는 에셋입니다. Unity는 여러 개의 드로우 콜을 발행하는 대신 이러한 단일 텍스처를 호출함으로써 하나의 드로우 콜을 발행할 수 있습니다. 그러면 큰 성능 소모 없이도 패킹된 텍스처에 동시에 액세스할 수 있습니다. 또한 스프라이트 아틀라스 API는 프로젝트의 런타임 시점에 스프라이트 아틀라스를 로드하는 방법을 제어할 수 있도록 해줍니다.

 

7. 로직 : 캐싱 / Find 함수들

답 : 컴퓨팅에서 캐싱은 오랜 시간이 걸리는 작업의 결과를 저장해서 시간과 비용을 절감하는 기법을 말하는데 예를들어 매번 update에서 find, getcomponent같은 찾는 기능을 사용하면 매프레임마다 시간이 걸리면서 오버헤드를 발생시키는 원인이 될수 있기 때문에 awake, start 같은 초기화중 한번 발생하는 이벤트함수에 변수로 담아 필요할때 발생시키던가 update에 해당 변수를 넣고 사용하면 오버헤드를 줄일수 있음.

find류의 함수들은 자주 호출 할 경우 오버헤드가 더욱 자주 발생시키는 원인으로 성능에 악영향을 줄수있다 그래서 캐싱같은 최적화를 통해 작업해주는것이 좋다.

 

- 수학연산 큰거(ex:시간보잡도가 큰거)또한 캐싱을 쓰면 좋음 

 

8. 수학 최적화

- Distance 대신에 sqrMagnitude : sqrMagnitude는 루트연산을 사용하지 않고 계산된 거리의 제곱값이 리턴된다 연산속도가 빠르지만 정확한 거리보다 대략적인 거리가 계산되어 그냥 빠르게 거리를 비교할때 사용됨, 대신 Distance 는 정확한 거리값이 계산되지만 속도는 느리다

 

9. 물리최적화 : fixedUpdata의 설정을 조정하면서 물리 업데이트 시간을 줄여서 성능면에서 향상을 노릴수있음(물리부 구현이 정교함을 요구 안할때)

 

10. 콜라이더 최적화 : 매쉬콜라이더 남발 보단 다른 콜라이더를 써서 물리적인 성능 향상을 조정할수있음