유니티 12

[Unity] VR 시뮬레이터 만들기

VR 시뮬레이터 개요 VR 개발을 하다 보면, 현재 내 상황에 대한 디버깅이 필요한 순간이 있을 것이다. 예를 들어, 운전을 하는 VR을 개발 중이면 현재 개발 단계에서 어느 부분이 모자란지에 대한 정보가 필요한데, 이를 확인하기 위해 매번 빌드하는 과정이 상당히 번거롭다. 따라서 간단한 시뮬레이터를 구현하여 이를 해결해 보는 시간을 가지도록 해보겠다. 본문 전처리 지시문 유니티에서 코드를 실제 빌드 환경과 시뮬레이션 환경을 나누어 처리하고자 할 때 주로 전처리 지시문(Preprocessor Directives)을 사용한다. 전처리 지시문을 활용하면 특정 조건에 따라 코드의 일부를 컴파일러에서 제외하거나 포함시킬 수 있다. 이를 통해 실제 빌드와 에디터 내에서의 시뮬레이션을 구분할 수 있다. 유니티에서 ..

Game/Unity 2024.02.04

[유니티] 한글 폰트 깨짐 with Text Mesh Pro

개요 유니티로 게임 개발을 진행하던 중, 한글 문자가 깨져서 사각형으로 나타나는 문제를 발견하였다. 이 현상은 주로 폰트가 한글을 지원하지 않거나, 파일의 인코딩이 잘못된 경우에 발생하는데, 이제부터 이 문제를 해결하는 방법에 대해 살펴보겠다. 폰트 다운 유니티에서 기본적으로 사용하는 LiberationSans 폰트는 기본적으로 한글을 지원하지 않는다. 특정 폰트가 한글을 지원하지 않을 때, 이를 직접 바꾸는 것은 불가능하다. 따라서 다른 한글을 지원하는 폰트를 찾아서 다운로드하여야 한다. 새로운 폰트는 에셋 스토어 혹은 구글링 등을 통해 다운로드하면 된다. 필자의 경우 넥슨의 메이플스토리 서체와 TextMesh Pro를 기준으로 진행하겠다. 해당 사이트의 TTF 파일을 다운로드하여 폰트 작업이 필요한 ..

Game/Unity 2023.06.18

[유니티] 오브젝트 풀링(Object Pooling)

개요 게임에서 오브젝트를 생성하고 삭제하는 작업은 메모리 사용량이 늘어나는 문제와 성능 저하의 원인이 된다. 예를 들어 FPS 게임에서 플레이어가 총을 쏠 때 매번 탄환을 생성하는 것은 성능적으로 봤을 때 비효율적이다. 이러한 문제점을 해결하기 위해 생긴 개념이 오브젝트 풀링이다. 개념 오브젝트 풀링은 게임 오브젝트를 필요한 만큼 미리 생성해 두고 풀에 쌓아두는 기법으로, 오브젝트를 매번 생성하고 삭제하는 것보다 메모리 사용량과 성능 저하를 줄일 수 있다. 다만, 초기에 더 많은 메모리를 사용한다는 단점이 있다. 이 방식은 풀에 오브젝트를 생성한 후, 새로운 오브젝트가 필요할 때 풀에 있는 오브젝트를 가져다 사용하며, 필요가 없어지면 오브젝트를 비활성화하고 풀에 반환하는 방식으로 동작한다. 이해를 돕기 ..

Game/Unity 2023.04.13

[유니티] 방향, 크기, 회전 (2)

유니티 C# 벡터 Vector type 앞선 [유니티] 방향, 크기, 회전 (1) 포스트에서는 수학적 의미에서 벡터를 다루었다. 이번 게시글에서는 게임 개발에 필요한 기본적인 벡터 수학을 유니티 C#에 적용하는 방법을 알아보자. 유니티는 벡터를 표현하기 위해 Vetor2, Vector3, Vector4를 제공하고 있다. 가장 많이 사용할 Vector3의 정의를 보기 위해 유니티 공식 홈페이지에 접속해 보면 다음과 같이 설명하고 있다. 이때 주목해야할 점은 Vector 타입이 구조체(struct)로 선언되어 있다는 점이다. 클래스로 선언하지 않고 구조체를 이용한 이유는 값 타입으로 동작하게 하여 복사를 했을 때 수정되는 것을 막기 위해서다. 직관적으로 이해하기 위해 다음 예제를 보도록 하자. Vector3..

Game/Unity 2023.03.17

[유니티] 유니티 엔진 원리

상속 게임 엔진은 이미 완성된 기반 코드를 제공한다. 지금까지 포스팅해온 게시글을 움직이는 것(translate)과 충돌하는 것(OnTrigger)과 같이 이미 작성된 코드를 재사용하여 게임을 만들었다. 이러한 '재사용'과 관련이 깊은 키워드는 바로 상속이다. 하지만 유니티 엔진에서는 이러한 상속을 유니티를 동작시키는 데 있어 핵심이라고 부르진 않는다. 왜 그럴까? 바로 상속의 한계 때문이다. 게임을 만들 때 상속의 한계는 명확하다. 상속에 의존하다보면 오히려 코드의 재사용이 힘들어지고, 추후에 자식 클래스와 부모 클래스의 기능이 충돌하는 등 더욱 번거로워지기 때문이다. 예를 들어보자. RPG 게임에서 플레이어와 NPC, Monster를 상속을 이용해 만든다고 가정해보면, 이들의 기반인 Human 클래스..

Game/Unity 2023.02.09

[유니티] 프리팹(Prefabs)과 감지(Detection), 충돌(Collision) (2)

목표 - 프리팹의 개념을 이해하고 프리팹 인스턴스를 생성하기. - 프리팹화된 몹들을 감지하기. 충돌(Collision)과 감지(Detection) 게임을 하다 보면 몹의 특정 범위 내에 들어와서 공격을 받는 상황을 겪어보았을 것이다. 예를 들어보자. 타워 디펜스류 게임을 할 때 타워가 설치되고 몹을 인식하기 전까진 아무런 행동을 하지 않다가, 몹이 범위 안에 들어오면 공격을 하기 시작하는 것을 예로 들 수 있겠다. 이렇게 몹을 감지하고 공격하는 행동은 어떻게 해야 구현이 될까? 공격을 하기 위해선 몹을 감지하는 것이 우선이겠다. 여기서 감지(Detection)란 말 그대로 범위 내에 특정 오브젝트를 인식하는 것을 의미한다. 유니티에서는 감지를 하기 위해 자주 사용하는 것이 있는데, 바로 충돌(Collis..

Game/Unity 2023.02.01

[유니티] 프리팹(Prefabs)과 감지(Detection), 충돌(Collider) (1)

목표 - 프리팹의 개념을 이해하고 프리팹 인스턴스를 생성하기. - 프리팹화된 몹들을 감지하기. 프리팹(Prefabs) 게임을 하다 보면 동일한 목표를 가진 오브젝트가 여러 마리 생성되는 것을 쉽게 볼 수 있다. 예를 들어 보자. 우리가 한 번 씩 해본 메이플 스토리를 생각해보면, 사냥을 할 때 맵에 있는 몬스터들을 봤을 때 동일한 몬스터가 같은 패턴으로 행동한다. 일정 범위 내의 플레이어를 인식하고, 몬스터의 고유의 행동(공격)을 한다. 만약 이러한 몹들이 생성될 때마다 생성된 수만큼 오브젝트를 생성하고 컴포넌트를 부착한다면 굉장히 비효율적일 것이다. 이러한 상황을 해결하기 위해 사용하는 것이 바로 프리팹이다. Unity 공식 문서에 따르면 Unity의 프리팹 시스템은 게임 오브젝트를 생성, 설정 및 저..

Game/Unity 2023.01.26

[유니티] 오브젝트 이동 (2)

목표 - 오브젝트가 특정 경로를 따라 이동하게 구현 - 좌표와 애니메이션을 이용해 오브젝트가 움직이며 이동하게 구현 특정 경로를 따라 이동 이전 [유니티] 오브젝트 이동(1)에서는 기본적인 이동방법 2가지인 transform.Translate와 transform.position에 대해 간략하게 알아보았다. 이번 파트에서는 이 두 가지 방법 중 하나를 이용해서 경로를 따라 이동하는 것을 구현해보자. 다음과 같은 타일을 맵으로 해서 노란색 경로를 따라 지나가다 End를 만나면 멈추는 것을 구현해보자. Start부터 시작해서 꺾이는 분기점을 지나게 하려면 어떻게 해야할까? - Vector3.moveTowards 유니티 공식 문서에 따르면 Vector3의 프로퍼티중 MoveTowards는 다음과 같다. curr..

Game/Unity 2023.01.23

[유니티] 오브젝트 이동 (1)

목표 - 오브젝트가 특정 경로를 따라 이동하게 구현 - 좌표와 애니메이션을 이용해 오브젝트가 움직이며 이동하게 구현 오브젝트 이동 오브젝트가 특정 경로를 따라 이동하는 것을 구현하기 전에, 유니티에 존재하는 이동 방법들에 대해 먼저 알아보자. 우리가 어떤 오브젝트를 생성했을 때 그 오브젝트의 인스펙터창을 보게 되면 다음과 같은 Transform 컴포넌트가 항상 존재한다. 이 Transform 컴포넌트는, 유니티 공식 사이트에 따르면 Scene 속 각 Object의 Position(위치), Rotation(회전), Scale(크기)를 결정한다고 쓰여 있다. 쉽게 말해 좌표에 관한 정보를 담고 있다고 생각하면 되겠다. 따라서 이러한 위치를 프레임마다 변경한다면 우리는 마치 이 오브젝트가 이동하는 것처럼 보일..

Game/Unity 2023.01.19