유니티 공부 한 것들!!
유니티에서 기즈모(Gizmo)란, 3D 뷰포트에서 개체(object)를 선택하고 변형(transform)하기 위한 도구들을 의미합니다. 기즈모는 선택된 개체 주위에 나타나며, 개체를 이동, 회전, 스케일링 등의 변형 작업을 할 수 있도록 도와줍니다. 기즈모를 사용하면 개체의 변형이 좀 더 직관적으로 이루어지므로, 유니티에서 3D 오브젝트를 만들거나 이동/조작할 때 유용하게 사용할 수 있습니다.
유니티에서 스프라이트는 2D 이미지를 게임 화면에 그려주는 요소입니다. 여기서 bilinear란, 선형 보간법(linear interpolation)을 이용하여 텍스처의 화질을 조절하는 방법 중 하나입니다. Bilinear filtering은 주로 이미지의 크기를 확대 또는 축소할 때 쓰이며, 더 부드러운 이미지가 되도록 하는 역할을 합니다.
간단히 말해, 유니티에서 스프라이트에 bilinear를 쓴다는 것은 2D 이미지가 게임 화면에 표시될 때 보다 자연스럽게 보이도록 처리하는 것입니다. 이를 통해 게임의 시각적 품질이 향상될 수 있어요
유니티에서는 스크립트의 생명주기에 따른 다양한 이벤트 함수들이 있습니다. 여기서 말씀해주신 'awake', 'start', 'onEnable' 함수는 각각 다음과 같은 역할을 합니다:
- Awake(): 이 함수는 오브젝트가 생성되고 모든 스크립트가 로드될 때 실행됩니다. 스크립트가 처음 초기화될 때 딱 한 번만 호출되는 함수로, 다른 스크립트와의 참조 설정 등 초기 설정을 위해 사용됩니다.
- Start(): Awake 함수와 마찬가지로 이벤트 함수지만, 게임 오브젝트가 활성화된 상태에서 첫 프레임의 Update 함수가 실행되기 바로 전에 호출됩니다. Start()는 컴포넌트간의 의존관계가 끝난 후에 호출되기 때문에, 다른 스크립트에서 초기화된 내용에 의존하는 작업을 처리할 때 사용됩니다.
- OnEnable(): 이 함수는 게임 오브젝트가 활성화되거나 스크립트가 활성화될 때 호출됩니다. 오브젝트 활성화와 관련된 설정을 처리할 때 사용되며, 일시적으로 비활성화된 오브젝트를 다시 활성화할 때에도 호출됩니다.
이 세 가지 함수를 적절하게 활용하면 유니티 스크립트의 초기화 과정을 효과적으로 관리할 수 있습니다. 번외로 종료 이벤트인 OnDisable() 함수도 있는데, 게임 오브젝트나 스크립트가 비활성화될 때 호출되며, 리소스를 정리하는 데 사용할 수 있습니다.
유니티 스크립트의 생명주기는 여러 이벤트 함수들이 순차적으로 호출되는 과정입니다. 이러한 함수들은 게임 객체와 컴포넌트의 초기화, 프레임 업데이트, 프로그램 종료 등 다양한 상황에서 호출됩니다. 주요 이벤트 함수들은 다음과 같습니다.
- Awake(): 오브젝트 생성 시 딱 한 번 호출됩니다. 다른 스크립트와의 참조 설정 등 초기 설정에 사용됩니다.
- OnEnable(): 게임 오브젝트나 스크립트가 활성화되면 호출됩니다.
- Start(): 객체가 활성화되고 첫 프레임의 Update 함수가 호출되기 직전에 실행됩니다. 다른 스크립트의 초기화에 의존하는 작업에 사용됩니다.
- FixedUpdate(): 물리 시뮬레이션을 위한 준비 과정이 진행되기 직전에 호출되며, 고정된 프레임 레이트를 따릅니다. 주로 리지드바디와 관련된 물리 처리를 할 때 사용됩니다.
- Update(): 매 프레임마다 실행되며, 입력 처리, 캐릭터 이동 등 게임 로직을 처리하는 데 사용됩니다.
- LateUpdate(): 모든 Update 함수가 끝난 후 실행되며, 카메라 이동이나 다른 오브젝트의 변화에 맞춰 처리해야 하는 로직에 사용됩니다.
- OnDisable(): 게임 오브젝트나 스크립트가 비활성화될 때 호출됩니다.
- OnDestroy(): 게임 오브젝트나 스크립트가 삭제될 때 호출됩니다. 리소스 정리에 사용됩니다.
이 외에도 여러 코루틴 함수나 이벤트 함수들이 있습니다만, 이것들은 주요 생명주기 함수보다는 특정 상황이나 조건에 때 의해 실행됩니다. 유니티에서 스크립트의 생명주기를 이해하고 관리하는 것은 게임 로직의 효율성과 안정성을 높이는 데 도움이 됩니다.
- 콜백 함수: 다른 함수나 메서드에 인자로 전달되어 특정 이벤트나 조건이 발생했을 때 호출되는 함수를 말합니다. 예를 들어, 버튼 클릭 이벤트가 발생했을 때 실행되어야 하는 함수를 콜백 형태로 구현할 수 있습니다. 유니티에서는 델리게이트(delegate)나 이벤트(event)를 통해 콜백 함수를 사용할 수 있습니다.
- 코루틴: 코루틴은 동시성 프로그래밍을 가능하게 하는 개념으로, 일반적인 함수와 달리 멈추고 다시 시작할 수 있는 함수입니다. 유니티에서 코루틴은 주로 시간 지연을 도입하거나 프레임마다 수행되어야 하는 작업을 처리할 때 유용합니다. 코루틴은 IEnumerator를 반환하는 함수로 정의되며, StartCoroutine() 함수로 호출됩니다. 코루틴 내에서 yield return 구문을 사용해 실행을 일시적으로 중단하고, 다음 프레임이나 특정 시간 후에 계속 실행되도록 설정할 수 있습니다.
- MonoBehaviour: 유니티에서 제공하는 클래스로, 컴포넌트가 게임 오브젝트에 추가되어 동작하게 하기 위한 기본 클래스입니다. 대부분의 유니티 스크립트는 MonoBehaviour 클래스를 상속받아 작성됩니다. 이 클래스는 유니티의 여러 이벤트 함수(Awake, Start, Update 등)와 생명주기를 관리하는 메서드를 제공하여, 스크립트 내에서 유니티 엔진과 상호작용하고 게임 로직을 구현하는 데 도움이 됩니다.
코루틴은 유니티에서 다양한 상황에 유용하게 사용됩니다. 주로 다음과 같은 경우에 코루틴을 활용할 수 있습니다:
1. 지연 처리: 코루틴을 사용하면 특정 작업을 지연 시킨 후 실행할 수 있습니다. 예를 들어, 게임의 인트로 애니메이션을 완료한 후에 메인 메뉴를 표시하기 위해 일정 시간을 기다렸다가 다음 작업을 수행하는 것이 가능합니다.
2. 시간 간격에 따른 반복 작업: 일정 시간 간격으로 반복되어야 하는 작업을 코루틴으로 처리할 수 있습니다. 예를 들어, 캐릭터의 공격 쿨타임이나 아이템 리젠 시간을 구현하는 데 사용할 수 있습니다.
3. 비동기 작업: 서버 통신이나 데이터 로딩과 같은 긴 작업을 처리할 때 코루틴을 사용하면, 메인 스레드를 차단하지 않고 작업을 수행할 수 있습니다. 이렇게 하면 게임이 멈추거나 버벅거리는 현상을 줄일 수 있습니다.
4. 연속된 애니메이션 재생: 여러 애니메이션을 순차적으로 재생하려면, 각각의 애니메이션 끝날때까지 대기해야 합니다. 코루틴을 사용하면 애니메이션간 대기시간을 쉽게 설정할 수 있습니다.
5. 타이머 구현: 게임 내에서 제한된 시간안에 특정 작업을 완료해야 하는 경우, 코루틴을 사용하여 타이머를 구현할 수 있습니다. 이 외에도 다양한 상황에서 코루틴의 장점을 활용하여 게임 로직을 구현할 수 있습니다. 코루틴을 사용함으로써 복잡한 시간 관련 작업을 간소화하고, 다양한 게임 요소를 효과적으로 제어할 수 있습니다.
- 쓰레드: 쓰레드는 프로그램에서 병렬 처리를 가능하게 하는 기본 단위입니다. 유니티에서 대부분의 작업은 기본적으로 메인 스레드에서 실행되지만 일부 오래 걸리는 작업이나 독립적인 동작이 필요한 작업을 스레드를 사용하여 분리할 수 있습니다. 이를 통해 메인 스레드의 부하를 줄이고 게임의 성능을 높일 수 있습니다. 단, 유니티 엔진의 API는 대부분 메인 스레드에서만 호출할 수 있기 때문에 별도의 스레드를 사용할 때 주의가 필요합니다. 서로 다른 스레드끼리의 데이터 공유와 동기화를 처리해야 하는 문제점도 있다는 것 염두에 두어야 합니다.
- 디버그 모드: 유니티에서 디버그 모드는 개발자가 게임을 개발하고 테스트하면서 발생하는 오류나 문제점을 찾고 수정하기 위한 모드입니다. 디버그 모드에서는 게임에 대한 로그 기록이 보다 상세하게 남겨지며, 게임의 성능에 영향을 받지 않고 코드 실행 중의 변수 값이나 오브젝트 상태 등을 확인할 수 있습니다. 유니티 에디터에서 게임을 실행하면 기본적으로 디버그 모드로 실행되며, 유니티 에디터 상단의 Console 탭에서 시스템 메시지와 로그를 확인할 수 있습니다.
- 시리얼라이즈드 모드: 이는 유니티에서 데이터를 쉽게 저장하고 불러오기 위한 방법 중 하나인 시리얼라이제이션(serialization)과 관련된 모드입니다. 시리얼라이제이션은 오브젝트나 데이터를 저장 및 전송 가능한 형식으로 변환하는 과정이며, 이를 통해 게임 진행 상황, 설정 값 등을 별도의 파일로 저장하거나 불러올 수 있습니다. 유니티에서 C#의 [SerializeField] 어트리뷰트를 이용하면, 비공개 필드(private field)를 Inspector 창에서 시리얼라이즈드 모드로 볼 수 있어 데이터 조작이 가능합니다.
- GUID (Globally Unique Identifier): GUID는 전 세계적으로 고유한 식별자로, 128비트의 길이를 가진 문자열입니다. 유니티에서는 에셋의 고유한 식별을 위해 GUID를 사용합니다. 두 개의 동일한 이름의 에셋이 저장되어 있더라도, 각각의 에셋은 고유한 GUID를 가지므로 중복되지 않습니다. 이를 통해 에셋 간에 참조 오류를 방지할 수 있습니다.
- 캐싱: 캐싱은 자주 사용하는 데이터나 결과를 임시로 저장하여, 나중에 동일한 요청이 발생했을 때 빠르게 결과를 제공할 수 있도록 하는 기능입니다. 유니티에서 캐싱은 리소스 로딩 속도를 향상시키고, 프레임 드롭이나 성능 저하를 줄이는데 도움이 됩니다. 특히 게임에서 부드러운 스트리밍 또는 레벨 로딩을 구현하기 위해 사용됩니다.
- 쿼터니언 (Quaternion): 쿼터니언은 3D 회전을 나타내기 위한 복소수 표현 방식입니다. 유니티에서는 오브젝트의 회전을 정확하게 표현하고, 짐벌 락 문제를 피하기 위해 쿼터니언을 사용합니다. 쿼터니언은 다음과 같이 네 개의 부동소수점 값 (x, y, z, w)으로 구성됩니다. 유니티에서는 일반적인 오일러 각도를 쿼터니언으로 변환하거나, 쿼터니언을 사용해 오브젝트를 회전시키는 기능을 제공합니다.
- 짐벌 락 (Gimbal Lock): 짐벌 락은 3D 공간에서 오일러 각도를 사용하여 회전을 처리할 때 발생할 수 있는 문제입니다. 이 문제는 두 개의 회전 축이 일치하게 되어, 한 축의 회전이 잃어버려 3D 객체의 자유도가 제한되는 현상입니다. 유니티에서는 쿼터니언을 사용하여 회전을 처리함으로써 짐벌 락 문제를 회피할 수 있습니다.
C#에서 가비지 컬렉션(Garbage Collection, 이하 GC)은 메모리 관리에 관한 중요한 개념입니다. 가비지 컬렉터는 .NET Framework 또는 .NET Core의 일부로 동작하며, 동적으로 할당된 메모리를 자동으로 관리하고 더 이상 필요 없는 메모리를 회수하는 역할을 수행합니다. C#에서는 개발자가 자원을 직접 해제할 필요 없이 가비지 컬렉터가 메모리 관리를 처리하므로 불필요한 메모리 누수로 인한 문제를 효과적으로 예방할 수 있습니다. 가비지 컬렉션의 주요 작동 원리와 동작 방식은 다음과 같습니다: 1. 메모리 할당: 객체가 생성되면 GC에 의해 관리되는 힙(heap) 메모리에 할당됩니다. 힙은 개체와 데이터 재사용을 위한 공간이며, 프로그램에서 필요한 메모리를 동적으로 할당하고 해제합니다. 2. Reachability 분석: 가비지 컬렉터는 루트 객체(root objects)로부터 참조되는 객체들을 분석하여 메모리를 회수해야 하는지 확인합니다. 루트 객체는 스택, 정적 변수, 관리되는 스레드 등에서 직접 참조되는 객체이며, 간접적으로 참조되는 객체까지 모두 살아 있는 객체로 간주됩니다. 3. 메모리 해제: 가비지 컬렉터는 더 이상 참조되지 않는 객체를 가비지(garbage)로 간주하고 메모리를 해제합니다. 해당 객체의 메모리 공간은 이후 다른 객체들이 사용할 수 있게 됩니다. 4. 메모리 정리: 객체가 해제된 후, 가비지 컬렉터는 힙에 남아 있는 사용 중인 객체들의 메모리를 압축 빈 공간을 줄입니다. 이를 통해 효율적으로 메모리를 관리할 수 있습니다. 가비지 컬렉션은 메모리 관리를 자동화해주지만, 동작하는 동안 프로그램의 프레임 레트에 영향을 줄 수 있습니다. 따라서 성능의 문제가 발생할 수 있으므로, 합리적으로 객체를 생성하고 관하는 것이 중요합니다. 가비지 컬렉션을 최적화하는 방법 중 하나로 불필요한 객체 생성을 줄이거나 객체 풀링(Object Pooling)과 같은 기법을 사용할 수 있습니다.렇게 가비지 컬렉션에 대한 이해와 사용을 통해 더 효율적인 메모리 관리가 가능해집니다.
유니티에서 피벗(Pivot)은 오브젝트의 중심점이며, 이 점을 기준으로 오브젝트의 위치, 회전, 크기 조절이 이루어집니다. 피벗은 3D 모델이나 2D 스프라이트에 존재하며, 게임 오브젝트의 Transform 컴포넌트를 통해 위치와 회전, 크기를 변경할 때 기준이 되는 축심입니다. 피벗의 위치를 변경하면 오브젝트의 이동, 회전, 스케일 조절이 영향을 받아 다른 형태로 작동할 수 있습니다. 예를 들어, 3D 모델의 피벗을 지면에 놓으면, 오브젝트가 회전할 때 지면을 중심으로 회전합니다. 반면, 피벗이 오브젝트의 중앙에 위치하면 오브젝트가 자기 자신을 중심으로 회전하게 됩니다. 피벗의 위치는 3D 모델링 소프트웨어나 2D 그래픽 편집 도구에서 설정할 수 있으며, 유니티 에디터에서도 일부 수정이 가능합니다. 유니티에서 피벗을 잘 활용하면 게임 오브젝트의 움직임과 상호작용을 훨씬 효율적으로 구현할 수 있습니다.