왜.... 오셨나요?

부끄러워요

개발관련공부자료

유니티 기술면접

와피했는데 2023. 10. 6. 21:49

1. 유니티 이벤트 함수 (아는대로 이야기)

답 : Awake, Start, OnEnalble, OnDisable, OnDestroy, Update, FixedUpdate, LateUpdate 등

 

1-1. 유니티 스크립트가 생성부터 삭제까지 호출되는 이벤트 함수를 순서대로 나열하기

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

 

1-2. Awake와 Start 차이점

답 : Awake는 항상 Start 함수의 이전 및 프리팹의 인스턴스화 직후(모든 초기화 이후)에 호출되고 Start는 첫 번째 프레임의 업데이트 전에 Start가 호출된다.

 

1-2. Update, FixedUpdate, LateUpdate 이 3가지의 차이

- Update : 프레임당 1회씩 호출되며 해당 프레임이 나타나는 시간은 불규칙적이다.(불규칙적으로 실행됨)

- FixedUpdate : 고정적인 시간(Default : 0.02sec)으로 반복적으로 실행되는 함수로 Update 함수와는 달리 프레임에 기반하지 않고 동일한 시간으로 동작해서 유니티 내의 물리 계산이 실행되어서 물리 효과가 적용된(Rigidbody) 오브젝트를 사용할 때 적합.

- LateUpdate : Update가 완전히 끝난 후 프레임당 한 번 호출되는 함수로, Update가 마무리된 후에 호출되기 때문에 3인칭 카메라에 주로 사용된다.


2. 유니티 게임 엔진의 동작원리

2-1. 게임루프와 단위시간에 대해서 (프레임개념)

답 : 30프레임에서 1프레임의 걸리는 실제 시간은 0.033333...정도 된다하고 60프레임은 당 0.0166666...정도 된다 한다 그래서 30프레임과 60프레임이란 1초에 30, 60프레임이 걸린다 해서 30fps(Frames Per Second), 60fps다 그리고 게임개발자들은 이 프레임을 실제시간 1초의 시간으로 흐르게 하기 위해 deltime을 사용했는데 deltime은 1*30/30 == 1 처럼 1프레임을 1초의 시간으로 바꾼다.

 

2-2. 메시지 브로드캐스팅(스크립트 & 이벤트함수 원리)

답 : 유니티의 스크립트들은 게임 오브젝트의 컴포넌트로 작동되기 위해서 MonoBehaviour라는 클래스 상속받게 되는데 여기서 MonoBehaviour는 유니티의 제어를 받기 때문에 유니티에서 보내는 메세지를 받을수 있게 됩니다 여기서 유니티는 컴포넌트의 기능을 실행하기 위해 메세지 브로드캐스팅 방식을 사용해서 실행하는데 유니티가 실행하고자 하는 기능 일일히 찾아내는 방법 대신 기능의 이름을 담은 메세지를 씬월드에 전체 전송하면 (오브젝트 전체) MonoBegaviour를 가진 오브젝트들이 받고 해당 이름에 대한 기능이 있다면 실행하고 없다면 무시하는 형태로 유니티는 기능을 실행한다.

 

메세지 브로드 캐스팅

 

2-3. Coroutine 구현 원리 / 코루틴과 스레드 차이 +a(인보크)

답 : 코루틴은 비동기적으로 실행되는 코드를 간소화할 수 있는 동시 실행 설계 패턴인데 경량 스레드라고도 부른다 Coroutine은 yield return을 통해 그 바로전 시점을 기억하고 다음 호출하게 될떄 그 다음부터 실행이 되는 것이다. 유니티에서는 대부분 그 시점을 Update에서 체크한다, 그래서 멀티쓰레드 처럼 비슷하게 작동하게 보여준다.

 

코루틴과 스레드는 모두 비동기적이다

둘은 비슷해 보이지만 차이점이 있는데 코루틴은 여러 작업을 잘게 쪼개서

동시에 수행하는 것처럼 보이게 작업을 수행하는 것이고, 스레드는 여러 작업을 정말로 동시에 수행한다는 것이다

단, 이때는 CPU의 코어에 따라 멀티 코어인 경우이다.

 

코루틴은 많이 사용할경우 리소스를 많이  사용하여 성능저하를 일으킬수 있고 유니티의 경우 가비지를 생성하여 GC사용을 늘릴수 있음.

코루틴의 구조

 

2-4. Meta 파일, Object 클래스, 유니티 레퍼런싱, 스크립트 직렬화

답 : 

-Meta : 에셋 폴더에 텍스처 같은 에셋을 저장하면 Unity가 먼저 새 파일이 추가되었음을 인식하는데 여기서  Asset을 식별할 수 있게 하는 고유한 값(ID)과, 해당 Asset에 대한 Inspector Property 값을 저장하는 파일이 Asset이름.mata파일이다 .mata파일은 Asset파일과 함께 담긴다

 

- Object 클래스: 이 클래스는 Unity가 에디터에서 참조할 수 있는 모든 오브젝트의 기본 클래스 역할을 합니다. UnityEngine.Object에서 상속되는 클래스는 인스펙터의 필드로 드래그앤 드롭하거나, 오브젝트 필드 옆에 있는 오브젝트 피커를 사용하여 선택하도록 해주는 특수 기능을 지원합니다.

 

- 유니티 래퍼런싱 : 

 

- 스크립트 직렬화 : 직렬화는 데이터 구조나 오브젝트 상태를 Unity 에디터가 저장하고 나중에 재구성할 수 있는 포맷으로 자동으로 변환하는 프로세스를 말합니다

 

3. 유니티 최적화

3-1. 프로파일러 사용

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

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

 

3-2. 로직 : 캐싱 / Find 함수들

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

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

 

3-3. 메모리 : 오브젝트 풀링 (써야할때 & 안써야할때)

답 : 게임 오브젝트의 생성, 파괴하는 것은 순간적인 프레임 저하 및 성능에 부정한 영향을 발생시킬 수 있음 그래서 오브젝트 풀링을 써서 생성, 파괴 대신 활성화, 비활성화 방식으로 사용하여 순간적인 프레임 저하를 줄일 수 있음.

대시 오브젝트 풀링은 처음 만들당시 메모리의 사용량이 크게 증가 하기 때문에 cpu성능 소모를 줄이지만 메모리 사용량은 더욱 늘리는 기법임.

 

-주의-

1. 오브젝트 풀링의 대상이 되는 오브젝트는 처음 초기화 때 발생하는 함수가 있을경우 awake, start함수에서 => Onenable함수로 옮겨 주어야 한다.

2. 자주 사용하지 않은 오브젝트는 풀에 계속 남아있기 때문에 불필요한 메모리 소모를 일으켜 상황에 맞게 사용하거나 때때로 제거를 해야한다.(세이브&로드에 사용하긴 적합하지 않음) 

 

3-4. 그래픽 : 파티클 시스템, 스프라이트 아틀라스, 텍스처

답 : 

1. 파티클 시스템 : ???

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

3. 텍스처 :

압축 텍스처를 사용하여 텍스처의 크기를 줄이고 이에 따라 로딩 시간과 메모리 사용을 줄이며 렌더링 퍼포먼스를 비약적으로 향상시킬 수 있습니다. 압축 텍스처는 비압축 32비트 RGBA 텍스처에 필요한 메모리 대역폭과 비교해보았을 때 일부분을 사용하는 정도에 그칩니다.

텍스처(Texture) 밉맵

3D 씬에서 사용되는 텍스처에 항상 밉맵 생성을 활성화합니다. 텍스처 압축이 GPU의 렌더링시 전송되는 텍스처 데이터의 양을 제한하는 데 도움이 되듯 밉맵된 텍스처는 GPU가 작은 삼각형에 낮은 해상도의 텍스처를 사용하게 합니다.

규칙에서 유일한 예외는 텍셀(텍스처 픽셀)이 UI 엘리먼트나 2D 게임에서처럼 렌더링된 화면 픽셀에 1:1로 매핑하는 경우입니다.

 

3-5. 수학 : 동일한 연산이라도 더 빠른 연산 방법들

답 : 

- 나눗셈보다 곱셈으로 변환 (%2대신 *0.5f쓰는거등) : 나눗셈은 부동소수점까지 연산되어 오래걸림 곱셉으로 하면 정수로 계산되어 메모리를 적게 쓰면서 연산이 빠르다.

 

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

 

- Angle 대신 Dot(내적)

 

3-6. 물리 : FixedUpdate 루프, 메쉬 충돌체와 복합충돌체 차이

답 : 

1. 

 

4. 게임수학

4-1. 쿼터니언과 오일러 차이, 짐벌락

답 : https://jmook.tistory.com/11

 

4-2. 탄도학(포물선), 베지어 곡선, 선형보간 Lerp

답 : 배지어곡선은 점과 점 사이의 선형보간을 통한 곡선을 만드는 방식으로 유니티에서는 Lerp함수를 사용하면 된다.

ex:

Vector3 p4 = Vector3.Lerp(_p1.position, _p2.position, time);
            Vector3 p5 = Vector3.Lerp(_p2.position, _p3.position, time);
            _target.position = Vector3.Lerp(p4, p5, time);

 

4-3. 백터와 스칼라 차이, 단위 백터

답 : 벡터(vector)는 크기와 방향을 갖는 개념이다. 벡터와 대비하는 개념으로, 스칼라(scalar)는 방향을 갖지 않고 크기만 갖는 개념이다.

 

4-4. 삼각함수들 sin, cos, tan, 내적, 외적 사용처

답:

 

5. 그래픽

5-1. 랜더링파이프라인 : 큐브가 모니터에 나오기 위해 거치는 단계들

답 :

입력 조립
GPU가 CPU로부터 정점 데이터를 전달 받아서 프리미티브(삼각형)들을 만든다.
정점 쉐이더
Object Space에서 Clip Space까지 정점들의 공간 변환을 수행한다.
래스터라이저
Clip Space의 정점 데이터를 Viewport로 변환하고,
정점 데이터를 기반으로 보간된 프래그먼트(픽셀 데이터)를 생성한다.
픽셀(프래그먼트) 쉐이더
프래그먼트를 입력 받아 화면에 그려질 모든 픽셀의 색상과 깊이 값을 출력한다.
출력 병합
Z-Test, Stencil Test, Alpha Blending 등을 통해 최종적으로 화면에 그려질 색상을 결정한다.

 

6. 게임에서 자주 사용되는 디자인 패턴

6-1. 싱글톤

답 : 객체의 인스턴스를 한개만 생성되게 하는 패턴입니다.

이러한 패턴은 주로 프로그램 내에서 하나로 공유를 해야하는 객체가 존재할 때 해당 객체를 싱글톤으로 구현하여 모든 유저 또는 프로그램들이 해당 객체를 공유하며 사용하도록 할 때 사용됩니다.

 

6-2. MVC : MVC는 사용자 인터페이스(뷰), 데이터(모델) 및 응용 프로그램 논리(컨트롤러)를 분리하는 데 사용되는 디자인 패턴입니다(참고 : https://m.blog.naver.com/jhc9639/220967034588)

6-3. 옵저버 : 어떤 객체의 상태가 변할 때 그와 연관된 객체 들에게 알림을 보내는 디자인 패턴

6-4. 어댑터, 플라이 웨이트(경량화) : 

1. 어댑터 :

  • 한 클래스의 인터페이스를 클라이언트에서 시용하고자 하는 다른 인터페이스로 변환한다.
  • 댑터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 쓸 수 있다.

2. 경량 패턴 : 

한개의 고유 상태를 다른 객체들에서 공유하게 만들어 메모리 사용량을 줄인다.

내용이 같은 객체가 이미 있으면 새로 객체를 또 만들지 않고 그 내용 같은 기존 객체를 공유한다.

 

6-5. 명령패턴과 전략패턴 차이

명령 :

커맨드 패턴은 내부 동작을 위한 모든 정보를 하나의 객체로 캡슐화한다. 

커맨드 패턴은 유사한 동작을 하나의 객체로 묶어 실행하는 행위 패턴이다

실행될 기능을 캡슐화해 기능 실행을 요구하는 호출자와 실제 기능을 실행하는 수신자 클래스 사이의 의존성 제거

 

전략 :

동일 계열의 알고리즘을 정의하고

동적으로 행위의 수정이 필요한 경우

전략을 바꾸는것으로 행위의 수정이 가능하게 만드는 패턴 

객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고, 유사한 행위들을 캡슐화 하는 인터페이스를 정의하여,

객체의 행위를 동적으로 바꾸고 싶은 경우 직접 행위를 수정하지 않고 전략을 바꿔주기만 함으로써 행위를 유연하게 확장하는 방법을 말합니다.

 

 


나중에 해야할 것

CS

 - 네트워크

 - 운영체제

 - 컴퓨터 구조

 

 

 

 

'개발관련공부자료' 카테고리의 다른 글

유니티 기술 면접2  (0) 2023.10.10
C# Static 함수  (0) 2023.10.07
버블정렬  (0) 2023.10.06
C#의 빌드과정  (0) 2023.10.06
알고리즘  (0) 2023.10.06