혼자 개발을 공부하다가 여러 명의 팀원들과 함께 게임을 개발을 시작했을 때, 개발한 내용을 어떻게 다른 작업자와 공유하고 프로젝트의 최신 상태를 유지할 지 궁금하신 분들이라면 필수 시청!

깃허브를 이용해서 유니티 프로젝트를 관리하고 공유하는 방법을 알아봅시다!

 

타임라인

0:06 프로젝트 관리가 필요한 이유

2:46 프로젝트를 관리하기 위한 프로그램과 서비스

3:28 깃허브 가입 방법

3:55 깃허브 웹사이트의 기본

4:47 새 리포지토리 만들기

5:08 리포지토리 공개 수준 설정

5:33 .gitinore 파일 설정

6:24 깃허브 데스크탑 설치하기

6:45 웹사이트에서 만든 리포지토리를 로컬에 복제하기

7:08 유니티 프로젝트를 깃허브 저장소에 업로드하기

7:45 깃허브의 기본 동작

7:59 커밋(Commit)

8:50 버리기, 디스카드(Discard)

9:10 푸시(Push)

9:27 풀(Pull)

9:58 머지(Merge)

11:36 다른 개발자를 내 리포지토리에 초대하기

12:22 유니티 프로젝트를 깃허브로 관리할 때 주의점 1 : 유니티 버전

13:32 유니티 프로젝트를 깃허브로 관리할 때 주의점 2 : 애셋 직렬화 방식

14:56 유니티 프로젝트를 깃허브로 관리할 때 주의점 3 : .meta 파일

16:26 .meta 파일의 생성/파괴 패턴

17:39 깃허브를 사용하지 않고 다른 개발자에게 파일을 보낼 때

18:13 .meta 파일이 갱신되는 경우

19:21 깃 서버에서 다른 사람의 커밋을 받을 때마다 메타파일이 바뀌는 문제가 발생할 때와 해결책

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

내비게이션 시스템 (2) 

NavMeshAgent와 NavMeshObstacle

 

작성 기준 버전 :: 2019.2

 

[이 포스트는 유튜브 영상으로도 시청하실 수 있습니다]

 

이전 포스트에서는 유니티의 내비게이션 시스템 중에서 길찾기 영역을 설정하는 NavMesh에 대해서 알아보았다.

 

이번 포스트에서는 이 NavMesh 위에서 길을 찾아서 움직일 NavMeshAgent와 NavMeshAgent의 길을 방해하는 NavMeshObstacle에 대해서 알아보도록 하자.

 

NavMeshAgent

 

Agent는 내비게이션 메시 위에서 길을 찾아서 움직일 오브젝트를 의미한다.

 

 

우선 캡슐 게임 오브젝트를 하나 만들어서 내비게이션 메시 위에 배치해보자. 그리고 캡슐의 자식 게임 오브젝트로 큐브 하나를 배치하고 캡슐의 정면이 어디를 가리키고 있는지 알기 쉽게 만든다. 거기에 더해 Rigidbody 컴포넌트를 붙이고 Constraints를 전부 체크해준다.

 

그 다음에는 NavMeshAgent 컴포넌트를 부착한다.

 

게임 오브젝트 준비가 끝나면 이 NavMeshAgent를 움직이기 위해서 Moveable라는 이름으로 C# 스크립트를 생성한다.

 

using UnityEngine;
using UnityEngine.AI;   // 스크립트에서 내비게이션 시스템 기능을 사용하려면 AI 네임스페이스를 using 선언해야함

public class Moveable : MonoBehaviour
{
    // 길을 찾아서 이동할 에이전트
    NavMeshAgent agent;

    // 에이전트의 목적지
    [SerializeField]
    Transform target;

    private void Awake()
    {
        // 게임이 시작되면 게임 오브젝트에 부착된 NavMeshAgent 컴포넌트를 가져와서 저장
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        // 스페이스 키를 누르면 Target의 위치까지 이동하는 경로를 계산해서 이동
        if(Input.GetKeyDown(KeyCode.Space))
        {
            // 에이전트에게 목적지를 알려주는 함수
            agent.SetDestination(target.position);
        }
    }
}

 

유니티의 내비게이션 메시와 관련된 기능을 사용하기 위해서는 우선 AI 네임스페이스를 using 선언해줘야 한다.

 

먼저 NavMeshAgent 변수를 선언하고 Awake 함수에서 게임 오브젝트에 부착되어 있는 NavMeshAgent 컴포넌트를 가져와서 저장해준다. 그리고 agent가 목표로 잡고 찾아갈 target 변수를 Transform 타입으로 만든다.

 

그 다음에는 Update 함수에서 스페이스 키 입력을 감지하는 코드를 작성한다. 그 안에서 agent에게 목적지를 설정해주는 코드를 작성해야 한다. agent에게 가야할 목적지를 알려주는 함수는 agent.SetDestination이다.

 

매개변수로 target.position을 넣어주면 스페이스를 누를 때마다 agent가 타깃의 위치를 찾아서 경로를 계산하고 이동할 것이다.

 

 

그리고 하이어라키 뷰에서 빈 게임 오브젝트를 하나 생성하고 Target으로 이름 지은 뒤 좀 더 보기 쉽게 아이콘을 설정해준다. 다음에는 캡슐 게임 오브젝트에 Moveable 컴포넌트를 부착하고 Target 게임 오브젝트를 Target 프로퍼티에 할당해준다.

 

 

  

게임을 플레이 시켜보자. 게임 플레이가 시작되고 Target 게임 오브젝트를 적당한 위치로 가져다 놓은 다음 스페이스 키를 누르면 캡슐이 Target을 향해서 장애물과 부딪히지 않고 이동하는 것을 볼 수 있다.

 

NavMeshAgent의 프로퍼티

 

Base Offset

 

 

우선 첫 번째 프로퍼티인 Base Offset은 길을 찾을 때 사용되는 충돌 실린더의 위치이다. 이 값을 조절해보면 캡슐 게임 오브젝트가 바닥에 파묻히거나 공중에 뜨는 것을 볼 수 있다.

 

캐릭터와 에이전트의 위치를 맞추기 위해서 사용되는 프로퍼티이다.

 

Steering

 

Speed

 

Speed는 단어 그대로 에이전트가 움직이는 속도이다. 

 

Angular Speed

 

Angular Speed는 에이전트가 회전하는 속도이다.

 

Angular Speed 프로퍼티의 값은 degree/sec로 회전 속도를 결정한다.

 

Acceleration

 

Acceleration은 가속도이다. 

 

기본 값이 8에서는 에이전트가 최대 속도까지 도달하는데 어느 정도 시간이 걸리지만 20 정도로 수정해주면 빠르게 최대 속도에 도달하는 것을 볼 수 있다.

 

Stopping Distance

 

Stopping Distance는 목표와 얼마만큼의 거리를 두고 멈출 지를 결정한다.

 

이 기능은 원거리 유닛이 공격할 대상을 향해서 이동하다가 공격 가능한 사정거리에 도달하면 이동을 멈추고 공격하게 하려고 할 때 사용할 수 있다.

 

Auto Breaking

 

Auto Breaking은 에이전트가 목적지에 도착하기 직전에 감속을 시작할 것인가를 결정하는 프로퍼티이다.

 

Auto Breaking이 켜져있을 때는 도착하기 직전에 감속을 시작해서 목적지에 제대로 멈추지만 Auto Breaking을 끄고 이동을 시키면 목적지에 도착하고나서 감속을 시작하기 때문에 속도를 주체하지 못하고 목적지를 넘어간 뒤 목적지에 도착하기 위해서 계속 왔다갔다하는 모습을 볼 수 있다.

 

Obstacle Avoidance 

 

Obstacle Avoidance 파트는 다른 에이전트와 나중에 설명할 NevMeshObstacle을 어떻게 회피할 것인지를 결정하는 내용의 프로퍼티들을 가지고 있다.

 

먼저 기본 상황에서 이동하는 에이전트는 길을 막고 있는 에이전트를 향해서 이동하다가 돌아갈 길이 있으면 돌아가고 길이 없다면 살짝 밀어내고 길을 찾아간다.

 

Radius

 

Radius를 변경하면 초록색 원기둥의 두께가 두꺼워지는 것을 볼 수 있다.

 

하지만 지형인 벽과는 관계없이 다른 에이전트나 NavMeshObstacle과만 충돌하는 영역의 두께만 조절된다.

 

Height

 

Height는 에이전트끼리의 높이 충돌을 조절하는 프로퍼티이다. 

 

Quality

 

Quality는 장애물 회피 품질을 뜻한다. 

 

HighQuality로 설정하면 다른 에이전트를 회피하기 위해서 최대한 정밀한 움직임을 보이게 되고 Low Quality로 설정하면 피하는 움직임이 간소화된다. 그리고 양 쪽 다 None으로 설정하면 서로 완전히 무시하고 지나간다.

 

Priority

 

Priority는 에이전트 간의 우선 순위이다. 우선 순위는 0부터 99까지 있는데 0이 가장 높고 99가 가장 낮다.

 

우선 순위가 높은 에이전트는 길을 찾을 때 우선 순위가 낮은 에이전트를 고려하지 않고 그냥 밀고 지나가버린다. 그리고 우선 순위가 같으면 회피하려는 노력은 하지만 여의치 않을 때는 그냥 밀고 지나가게 된다. 마지막으로 낮은 우선 순위의 에이전트는 높은 우선 순위의 에이전트를 밀어내지 못한다.

 

Path Finding

 

Auto Repath

 

Auto Repath는 내비게이션 메시에 변동이 생겼을 때 자동으로 길을 다시 찾을 것인가를 설정하는 프로퍼티이다. 목적지로 가는 최단 경로의 중간이 막히면 자동으로 경로를 다시 계산해서 이동한다.

 

하지만 아주 먼거리를 이동할 때 아직 시야에 보이지 않는 중간이 막혀도 경로를 바로 재계산하기 때문에 경로가 막힌 구역까지 도착한 다음 경로를 새로 계산하기를 원한다면 체크를 해제하고 경로가 막힌 구역까지 도착한 다음 경로를 새로 계산하는 기능을 직접 구현해야 한다.

 

Area Mask

 

Area Mask에서는 이 에이전트가 지나갈 수 있는 영역과 지나가지 못하는 영역을 설정할 수 있다. 

 

특정 영역을 꺼주면 이 캐릭터는 아무리 가까운 거리라도 그 영역을 건너지 못하게 된다.

 

 

NavMeshObstacle

 

 

컴포넌트의 이름에서도 알 수 있지만 이 컴포넌트는 장애물 역할을 한다. 기본 상태에서는 작은 장애물에만 자연스러운 움직임을 보이고 큰 장애물은 부자연스럽게 회피하는 동작을 보이게 된다.

 

작은 장애물만 회피가 가능하면 그냥 Navigation Static으로 설정한 벽을 배치하는게 더 나을 것이라고 생각할 수 있다. 하지만 Navigation Static이 적용된 지형과 NavMeshObstacle은 큰 차이점이 있는데 Navigation Static으로 설정된 벽은 움직일 수 없다는 것이다. 그와 반대로 NavMeshObstacle을 사용하는 장애물은 게임이 플레이되는 도중에 언제든지 움직일 수 있다.

 

그리고 실시간으로 에이전트를 밀어내는 동작도 가능하며 장애물에 밀려난 목적지가 있는 에이전트는 다시 원래 자리로 돌아오려는 움직임으로 보이게 된다.

 

Shape

 

먼저 Shape 프로퍼티는 장애물의 형태를 결정하는 옵션으로 Box, Capsule, 두 가지 형태를 지원한다.

 

Carve를 제외한 프로퍼티는 이 Box나 Capsule의 크기를 설정하는데 쓰인다.

 

Carve

 

 

Carve는 "파내다"라는 뜻으로 내비게이션 메시 영역을 새로 굽지 않아도 실시간으로 "파내서" 에이전트가 지나갈 수 없는 영역으로 만드는 것이다.

 

Carve를 켜서 실시간으로 내비게이션 메시를 파내게 하면 큰 장애물도 자연스럽게 회피하게 할 수 있다.

 

Move Threshold

 

Carve의 하위 프로퍼티인 Move Threshold는 최소 이동 거리를 뜻한다. Move Threshold보다 조금 움직인 것은 오브젝트가 움직이지 않은 것으로 간주하여 Carve를 새로 계산하지 않는다.

 

큐브 게임 오브젝트를 미세하게 움직일 때는 내비게이션 메시의 파인 부분이 그대로 유지되지만 Move Threshold 보다 크게 움직이면 파인 부분이 사라진다. 그리고 움직임을 정지하면 내비게이션 메시에 파인 부분이 새로 생겨난다.

 

Time To Stationary

 

Time To Stationary는 게임 오브젝트가 얼마나 정지해있으면 완전히 멈춘 것으로 판정하고 Carve를 새로 계산해서 내비게이션 메시를 파낼지를 결정하는 값이다.

 

기본 값은 0.5초 후에 새로 계산하게 되어있다. 이것을 2로 변경하고 내비게이션 탭을 활성화해서 영역이 보이게 만든 다음 장애물을 움직여보자.

 

장애물이 이동을 멈추고나면 아까보다 훨씬 시간이 많이 지난 다음에 내비게이션 메시가 파지는 것을 확인할 수 있다.

 

Carve Only Stationary

 

Carve Only Stationary는 정지된 상태에서만 내비게이션 메시를 파내도록 할 것인지를 결정하는 프로퍼티이다. 

 

기본 값은 true로 체크되어 있다. 그래서 장애물이 움직이면 파내진 구멍이 사라졌다가 정지하면 내비게이션 메시가 다시 파내진다. 하지만 Carve Only Stationary를 끄면 장애물이 움직일 때 내비게이션 메시의 파인 구멍이 실시간으로 장애물을 따라 움직인다.

 

자연스러운 움직임을 위해서는 Carve Only Stationary를 끄는게 좋지만, 물체가 움직이는 상황에서 실시간으로 내비게이션 메시에 구멍을 파내는 계산을 계속하는 것은 게임의 성능에 좋지않은 영향을 끼칠 수 있기 때문에 반드시 필요한 경우에만 이 옵션을 끄고 그 외에는 이 옵션을 사용하는게 좋다.

 

이 NavMeshObstacle은 여러가지 용도로 사용할 수 있습니다.

 

유니티 공식 문서에서 언급되듯이 천천히 움직이는 탱크 같은 곳에 사용해도 되고 특정한 트리거를 발동하면 떨어져서 길을 막는 돌무더기 같은 것에도 사용해도 됩니다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

내비게이션 시스템 (1) 

NavMesh

 

작성 기준 버전 :: 2019.2

 

[이 포스트의 내용은 유튜브 영상으로도 시청하실 수 있습니다]

 

이번 포스트에서는 유니티의 내비게이션 시스템에 대해서 알아보도록 하자.

 

 

내비게이션이라는 단어는 실생활에서도 많이 들어보았을 것이다. 어떠한 목적지까지 가는 경로를 알려주는 프로그램을 우리는 내비게이션이라고 부른다.

 

유니티에서도 어떤 한 지점에서 다른 지점으로 이동하는 길을 알려주는 역할을 하는 것이 바로 내비게이션 시스템이다. 그런데 원하는 지점까지 캐릭터를 조작해서 이동하면 될텐데 내비게이션 시스템이 왜 필요할까?

 

물론 플레이어는 캐릭터를 잘 조작해서 원하는 지점까지 이동할 수 있을 것이다. 하지만 플레이어가 조작하는 캐릭터가 아니라 AI가 조작하는 몬스터 같은 NPC는 어떨까?

 

일직선의 아무런 장애물이 없는 길이라면 AI가 조작하는 몬스터라도 무리없이 목적지까지 도착할 수 있겠지만, 벽이나 기둥, 상자 같은 장애물이 가득하고 구불구불한 길이라면 몬스터는 장애물에 막혀서 제대로 목적지에 도착하지 못할 것이다.

 

내비게이션 시스템은 바로 이렇게 장애물이 가득한 환경에서 AI가 최단 경로를 찾아서 목적지에 도달하는 것을 도와주기 위해서 필요한 것이다.

 

그럼 이제 본격적으로 유니티의 내비게이션 시스템에 대해서 이야기해보자.

 

유니티의 내비게이션 시스템은 기본적으로 NavMesh, NavMeshAgent, NavMeshObstacle. 이 세 가지 요소로 이루어집니다.

 

NavMesh

 

이번 포스트에서는 먼저 NavMesh에 대해서 살펴보자.

 

 

하이어라키 뷰에 우클릭하고 [3D Object > Plane]을 선택해서 평면을 하나 만들고 크기를 x는 3, z는 10으로 설정한다. 그러면 적당히 캐릭터가 움직일 만한 바닥이 만들어진다.

 

 

이 다음에는 상단 메뉴바에서 [Window > AI > Navigation]을 선택하면 내비게이션 뷰가 열린다.

 

 

내비게이션 뷰에는 Agent, Area, Bake, Object, 이렇게 네 개의 탭이 있다.

 

Object 탭

 

이 중에서 일단 Object 탭을 먼저 살펴보도록 하자.

 

Object 탭에서는 제일 상단에 Scene Filter를 볼 수 있는데 필터의 종류로는 All, Mesh Renderer, Terrains가 있다.

 

우선 All 필터는 씬에 있는 모든 오브젝트를 보여주는 필터다. 

 

그리고 Mesh Renderer 필터는 Plane처럼 Mesh Renderer 컴포넌트를 가지고 있는 게임 오브젝트만을 보여주도록 하는 필터다.

 

마지막 Terrains 필터는 유니티 엔진에서 거대한 평면에 직접 높낮이를 조절하면서 지형을 만들 수 있는 터레인 오브젝트만을 보여주도록 하는 것이다.

 

터레인이 아니거나 메시 렌더러(Mesh Renderer) 컴포넌트를 가지지 않은 게임 오브젝트를 선택하면 메시 렌더러를 가진 게임 오브젝트나 터레인을 선택해 달라는 문구가 표시된다.

 

 

배치한 Plane을 선택하면 Navigation Static을 체크할 수 있는 체크박스와 함께 다른 옵션들이 나온다. 한마디로 터레인이나 메시 렌더러 컴포넌트를 가진 게임 오브젝트만 캐릭터가 돌아다닐 수 있는 내비게이션 영역으로 설정할 수 있다는 뜻이다.

 

여기서 Navigation Static을 체크해보면 아래 쪽의 옵션들도 활성화되는 것을 볼 수 있다. Navigation Static을 체크하면 해당 메시를 캐릭터가 길을 찾을 수 있는 표면으로 설정된다.

 

우선은 아래 쪽의 두 항목은 나중에 알아보도록 하고 넘겨두도록 하자.

 

Bake 탭

 

 

Bake 탭에는 원기둥 그림과 함께 다양한 옵션들이 보이지만 그보다 먼저 제일 아래에 이 탭의 주인공처럼 보이는 Bake 버튼을 눌러보자.

 

 

Bake 버튼을 누르면 씬 뷰에서 Plane 위에 파란색 영역이 생겨난 것을 볼 수 있다. 이게 바로 캐릭터가 길을 찾아서 이동할 수 있는 영역을 의미하는 NavMesh이다.

 

참고로 Bake는 빵이나 과자같은 것을 굽는다는 뜻을 가지고 있다. 그래서 이렇게 NavMesh를 만드는 작업 역시 "NavMesh를 굽는다"라고 표현한다.

 

 

캐릭터가 돌아다닐 NavMesh를 만들기는 했지만 아무 장애물도 없어서 너무 밋밋해보이기 때문에 몇 가지 장애물을 설치해보자. 그리고 새로 만든 장애물 역시 Object 탭에서 Navigation Static으로 설정해준 뒤, Bake 탭에서 NavMesh를 구워보자.

 

 

그러면 완전히 평면이었던 파란색 영역이 배치한 장애물을 따라서 여러 면으로 쪼개지는 것을 볼 수 있다.

 

Mesh라는 단어는 3D에서는 삼각형이나 다각형 여러 개로 면을 구성하는 것을 의미한다. NavMesh는 다각형 여러 개로 캐릭터가 이동할 수 있는 표면을 구성하는 것이다. 이 면들을 이용해서 캐릭터가 찾아갈 길을 찾아내는 것이다.

 

그럼 이제부터 Bake 탭의 주요 옵션들을 하나씩 알아보도록 하자.

 

Agent Radius

 

Agent는 내비게이션 메시 위에서 움직이는 대상을 의미한다. 즉 Agent Radius는 NavMesh 위에서 움직일 대상의 반지름이다.

 

 

이 값을 1로 변경하고 NavMesh를 새로 구워보면 내비게이션 메시의 비어있는 경계 부분이 넓어지는 것을 볼 수 있다. 이것은 NavMesh 위를 돌아다닐 Agent의 Radius가 증가해서 뚱뚱해졌기 때문에 벽에 바짝 붙어서 움직일 수 없기 때문에 이렇게 된 것이다.

 

Agent Radius를 원상복구하고 NavMesh를 다시 구워보면 날씬해진 Agent가 돌아다닐 수 있는 범위가 증가한다.

 

Agent Height

 

Agent Height = 2
Agent Height = 1
Agent Height = 4

 

 Agent Height를 Agent의 키를 의미한다.

 

오르막길 아래의 작은 길을 보면서 Height를 1로 변경하면 Agent의 작아진 높이 때문에 통과할 수 있는 범위가 늘어나는 것을 볼 수 있다. 반대로 Height를 4로 변경하면 오르막길 아래의 샛길로 이동하지 못하게 된다.

 

Max Slope

 

Max Slope 값은 NavMesh에 이동할 수 있는 길로 포함될 수 있는 경사로의 최대 각도를 의미한다.

 

여기 맵에 배치된 경사로의 각도는 25도이다. 그리고 Bake 옵션의 최대 경사로 각도의 기본값은 45도이다.

 

 

그렇기 때문에 NavMesh를 구울 때 이 경사로가 이동할 수 있는 지역으로 포함된 것이다.

 

 

만약 MaxSlope 값을 25도보다 작은 20도로 변경하고 다시 구우면 이 경사로가 이동할 수 없는 지역이 되는 것을 볼 수 있다.

 

Step Height

 

그 다음 Step Height는 Agent가 가벼운 계단 정도로 여기고 올라갈 수 있는 단의 높이를 의미한다. 기본 값은 0.4로 설정되어 있다.

 

 

맵에 낮은 단으로 설치된 오브젝트의 높이는 0.25로 Step Height가 이보다 크기 때문에 이 단 역시 NavMesh로 연결되어 있다.

 

 

Step Height를 0.1로 변경하고 내비게이션 메시를 구워보면 연결된 NavMesh가 끊어져서 이동할 수 없는 지역이 되는 것을 볼 수 있다.

 

이렇게 Agent Radius, Agent Height, Max Slope, Step Height를 이용해서 내비게이션 메시의 영역을 설정할 수 있다.

 

Area 탭

 

 

Area 탭에서는 사용자가 필요한 내비게이션 메시 구역을 설정하고 그 구역을 지나가는 비용을 설정할 수 있다. 기본 Area로는 Walkable, Not Walkable, Jump. 이렇게 세 가지가 있다.

 

 

User3 위치에 Water를 추가하고 비용을 3으로 설정해보자.

 

 

그리고 맵에 추가적인 구조물을 몇 개 더 설치해보자. 이렇게 다른 쪽으로 넘어가는 두 갈래 길을 만들었다.

 

한 쪽은 바닥이 내려간 길이고 다른 한 쪽은 바닥이 올라간 다리 같은 길이다.

 

먼저 제일 낮은 바닥 부분을 제외한 구역을 선택해서 Navigation Static을 체크하고 Area는 Walkable으로 둔다. 그 다음에는 바닥을 선택해서 Navigation Static을 체크하고 Area를 Water로 설정한 다음 NavMesh를 구워보자.

 

 

그러면 다른 구역은 전부 같은 파란색으로 영역이 지정되지만 가장 낮은 바닥만 다른 색으로 지정된다.

 

반대편으로 넘어가는 블록 한 칸의 이동 비용을 1이라고 가정했을 때, 여기서 건너편으로 건너가기로 결정했을 때 이 다리를 건너는 비용은 3이고, Water로 지정된 바닥을 건너는 비용은 5이기 때문에 위로 건너는 방법이나 아래로 건너는 방법이나 이동 거리 자체는 같지만, Agent는 가급적이면 이 다리 쪽 경로를 선택하려고 할 것이다.

 

이렇게 Area마다 다른 비용을 책정해서 내비게이션 메시를 잘 구성하면 길은 쉽지만 몬스터가 자주 돌아다니는 구역과 몬스터는 자주 오지 않지만 함정이 많은 구역처럼 좀 더 다양한 레벨 디자인을 손쉽게 구성할 수 있을 것이다.

 

Agents 탭

 

 

Agents 탭에는 Bake 탭에서 본 것과 같은 그림과 옵션들이 있다. 다만 Humanoid라는 기본 타입과 함께 새로운 타입을 추가할 수 있다.

 

덩치가 큰 에이전트와 덩치가 작은 에이전트를 만들어서 덩치가 작은 에이전트는 지나갈 수 있는 곳을 덩치가 큰 에이전트는 돌아서 가야되게 만들 수 있다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Vector 

좌표와 속도를 다루기 위한 도구

 

작성 기준 버전 :: 2019.2

 

[유튜브 영상에서도 본 포스트의 내용을 시청하실 수 있습니다.]

 

이번 섹션에서는 유니티 엔진의 벡터에 대해서 알아보자.

 

게임 속에 존재하는 모든 오브젝트들은 어느 위치에 존재하거나, 어딘가를 향해서 이동한다. 아무것도 움직이지 않는 게임은 거의 존재하지 않는다. 그렇기 때문에 이렇게 오브젝트의 위치와 이동 등에 대해서 다루는 도구가 필요한데, 그것을 위한 도구가 바로 벡터이다.

 

벡터에 관한 이번 포스트를 읽기 전에 유니티의 좌표계에 대한 글을 읽어보는 것도 좋다.

 

벡터(Vector)

 

벡터에 대해서 수학이나 물리학에서는 여러 복잡한 정의가 존재하는데 간단하게 요약하자면 특정한 공간에서의 방향과 크기를 표현하는 도구로서 주로 화살표로 표시되는 개념이다.

 

[그림 1]

 

[그림 1]을 예시로 들면 오른쪽으로 뻗어나가는 X축과 위쪽으로 뻗어나가는 Y축, 두 개의 축으로 구성된 2차원 평면 공간이 있고, (2, 2) 위치를 가리키고 있는 V1 벡터와 (-1, -2) 위치를 가리키고 있는 V2 벡터, 두 개의 벡터가 2차원 공간 속에 존재하는 것을 볼 수 있다.

 

즉, 여기서는 2차원 평면이 "특정한 공간"이며, 벡터는 그 공간 안에서 방향과 크기를 표현하는 도구라고 말했듯이, 벡터를 표시한 화살표를 보는 것만으로도 이 벡터가 어느 방향을 가리키고 있고 얼마만큼의 길이를 가지는지 알 수 있다.

 

그리고 이 "특정한 공간"은 몇 차원이든 가능하지만 대부분은 사람이 쉽게 인지할 수 있는 2차원 혹은 3차원으로 정의된다. 유니티에서도 2차원과 3차원의 벡터만 사용한다.

 

벡터의 활용

 

벡터는 방향과 크기를 표현하는 도구라고 이야기했는데, 이것을 이용해 여러 가지 용도로 활용된다.

 

첫 번째 활용법은 방향이다. [그림 1]과 같이 평면에 벡터가 표시하는 좌표까지 화살표를 그리는 것으로 방향을 쉽게 알 수 있다.

 

[그림 2]

 

두 번째 활용법은 속도이다. V1과 V2가 [그림 1]에서는 서로 다른 방향을 가리키고 있는데, [그림 2]와 같이 두 벡터를 같은 방향으로 놓고 보면, V1이 V2보다 긴 것을 확인할 수 있다. 1초 동안 각 벡터의 길이만큼 이동한다고 가정하면, 당연히 같은 시간동안 V1만큼 이동한 것이 V2만큼 이동한 것보다 멀리 이동할 수 있고, 벡터의 방향 자체가 이동 방향의 의미를 가지기 때문에, 이동하고자하는 방향과 속력, 즉, 속도의 개념으로 활용되는 것이다.

 

세 번째 활용법은 좌표이다. [그림 1]에서 X축과 Y축이 교차하는 지점을 공간의 중심이라고 가정했을 때, V1 위치에 어떤 오브젝트가 있다면, 그 오브젝트는 공간의 중심으로부터 (2, 2)의 위치에 있다고 말할 수 있다.

 

벡터의 계산

 

벡터에 대한 여러가지 계산들이 존재하는데 이러한 계산 방법들을 잘 활용하면 게임의 기능을 구현하는데 유용하게 사용할 수 있다.

 

벡터의 덧셈과 뺄셈

 

두 개의 벡터는 서로 더하거나 뺄 수 있다.

 

[그림 3]

 

우선 벡터의 덧셈을 살펴보자. [그림 3]을 보면 (1, 2)의 V1과 (2, 1)의 V2를 더하면 (3, 3)의 V3가 나오는 것을 볼수 있다. V1 지점에서 V2 만큼 이동했다고 여기면 된다.

 

[그림 4]

 

또 다른 관점에서 살펴보면 두 벡터의 합은 서로 다른 방향의 두 힘이 충돌했을 때의 그 합쳐진 힘의 진행 방향으로 해석될 수도 있다.

 

[그림 5]

 

벡터의 뺄셈은 역시 (1, 2)인 V1에서 (2, 1)인 V2를 빼면 (-1, 1)인 V3가 나온다. 다만 여기서 기억할 점은 이렇게 결과 값으로 나온 V3가 V2 지점에서 시작하여 V1 방향으로 이동하는 V3'와 길이와 방향이 모두 같다는 것이다. 이것을 이용하면 V1과 V2 사이의 거리, V2에서 V1으로 가는 방향등을 구할 수 있다.

 

벡터와 스칼라의 곱셈

 

벡터는 좌표로서 공간 상에서 방향과 크기를 의미하지만 스칼라는 크기 만을 가지는 값이다. 벡터가 차원 축을 따라서 (2, 0), (1, 2, 3)과 같은 값을 가지는 것에 비해 1, 10, 24 등의 단일한 값을 의미한다.

 

[그림 6]

 

(1, 1)인 V1에 4인 스칼라 S를 곱하면 V1의 각 원소에 S를 곱하여 (4, 4)인 V2를 얻게 된다. 이렇게 벡터에 스칼라를 곱하는 계산은 주로 벡터의 크기를 원하는대로 늘이거나 줄이는 등의 계산이나, 벡터에 -1을 곱해서 현재 벡터의 반대 방향을 구하는데 주로 사용된다.

 

벡터의 길이

 

[그림 2]에서는 벡터를 나란히 놓는 원시적인 방식으로 벡터의 길이를 비교했다. 이런 방식 외에 계산적인 방식으로도 벡터의 길이를 구할 수 있다.

 

 

벡터의 길이를 구하는 공식은 위와 같다. 벡터의 각 원소를 제곱한 뒤, 모두 더하여 제곱근을 구하면, 벡터의 길이가 나온다.

 

[그림 1]

 

다시 [그림 1]을 보자. V1의 좌표는 (2, 2)이다. 이것을 공식에 대입하면 : 

 

 

위와 같은 값이 나온다. 이것은 사실 피타고라스의 정리에서 유도된 빗변의 길이를 구하는 공식이다. 벡터는 항상 각 축을 대상으로 직각을 이루는 직각 삼각형의 형태이기 때문에 이 공식으로 길이를 구할 수 있는 것이다.

 

벡터의 길이는 즉, 거리로, 벡터의 뺄셈을 이용하면 두 벡터 간의 거리를 구할 수 있다.

 

 

3차원 벡터에 대한 공식은 2차원 공식에 z축 좌표를 추가해서 계산하면 된다.

 

벡터의 정규화(Normalize)

 

벡터의 정규화는 현재 벡터의 방향을 유지한 채로 벡터의 길이를 1로 만드는 것을 의미하며, 이를 단위 벡터라고 부른다.

 

 

단위 벡터를 구하려면 벡터의 각 원소를 벡터의 길이로 나누어 주면 된다. 예를 들어 [그림 1]의 V1을 단위 벡터로 만들려면 V1의 각 원소 (2, 2)를 각각 벡터의 길이인 2.828427로 나누어주면 된다. 그러면 각 원소의 값은 (0.707106..., 0.707106...)이 된다. 이렇게 나온 단위 벡터에 대해서 다시 벡터의 길이를 구해보면 1의 근사값이 나올 것이다.

 

이런 단위벡터는 정확히 벡터의 방향만을 추출하고자 할 때 사용되는데, 주 사용처를 이야기 해보자면, 만약 캐릭터를 마우스의 방향으로 이동시키려고 할 때, (마우스 위치) - (캐릭터 위치)로 캐릭터에서 마우스 위치 방향을 찾아낼 것이다. 그런데 이 벡터를 그대로 사용하면 마우스의 거리가 멀어지면 멀어질 수록 이 이동 벡터의 길이가 길어지기 때문에 마우스와 캐릭터의 거리가 멀면 캐릭터가 빨라지고 가까워지면 캐릭터가 느려지는 문제가 발생할 것이다.

 

(마우스 위치) - (캐릭터 위치)로 찾아낸 방향을 정규화해서 단위 벡터로 만든 다음에 캐릭터의 이동 속도만 곱해주면 캐릭터가 일정한 속도로 이동한다.

 

벡터의 내적(Dot Product)

 

점곱(dot product), 내적(inner product)이라고 부르는 계산으로 계산 결과 값으로 벡터가 아닌 단일 값, 즉 스칼라 값을 내는 계산이다. 때문에 스칼라 곱이라고도 부르는데, 벡터와 스칼라의 곱셈과 헷갈려서는 안된다.

 

 

계산 공식은 위와 같다. 벡터의 각 원소끼리 곱한 뒤, 모두 더하는 것으로 벡터의 내적을 구할 수 있다.

 

이렇게 나온 계산 결과의 의미는 내적의 값이 0이면 두 벡터의 각이 90도이고, 0보다 크면 두 벡터 사이의 각도가 90도보다 작고, 0보다 작으면 각도가 90도보다 크다는 의미이다. 여기에 삼각함수를 이용하면 두 벡터 사이의 각도를 구할 수 있다.

 

벡터의 외적(Cross Product)

 

가위곱(cross product), 외적(outer product)이라고 부르는 계산으로 두 벡터와 모두 직교하는, 즉 두 벡터와의 각이 모두 90도를 이루는 벡터를 결과값으로 내며, 3차원 공간에서만 성립하는 계산이다.

 

 

외적의 계산 공식은 위와 같다. 

 

[그림 7]

 

 V1과 V2에 대해서 직교하는 벡터는 V3, V4 둘 다 될 수 있는데, 이 결과는 왼손 좌표계를 사용하느냐, 오른손 좌표계를 사용하느냐에 따라 결과가 달라진다. 왼손 좌표계에서 V2 X V1의 결과값은 V3로 나오고 오른손 좌표계에서는 V4로 나온다. 이렇게 나온 벡터를 법선 벡터(Normal Vector)라고 부른다.

 

[그림 8]

 

그래서 벡터의 외적은 [그림 8]과 같이 한 면이 바라보는 방향을 구하는 용도로 주로 사용된다.

 

 

 

 

 

유니티 엔진의 벡터

 

그러면 이제 유니티 엔진에서의 벡터에 대해서 알아보자.

 

Vector2 vector2 = new Vector2();

 

vector2.x = 1f;

vector2.y = 1f;

 

Vector3 vector3 = new Vector3();

 

vector3.x = 1f;

vector3.y = 1f;

vector3.z = 1f;

 

위의 코드 예시는 유니티에서 사용되는 Vector2 구조체와 Vector3 구조체이다. Vector2 구조체는 2차원 평면 공간에 속하는 벡터로 X축의 좌표를 표시하기 위한 x 변수와, Y축의 값을 표시하기 위한 y 변수를 가진다. Vector3 클래스는 여기에 더해 Z축을 표시하는 z 변수까지 가진다.

 

Vector2는 대부분 UI 같은 2D 공간이나 2D 게임을 제작할 때 사용되고, Vector3는 일반적인 3D 공간에서 사용된다.

 

자, 그렇다면 우리는 벡터와 관련된 기능을 전부 직접 구현해서 사용해야 할까? 아니다. 유니티에서는 이러한 벡터와 관련된 기능들을 모두 제공한다.

 

벡터의 덧셈과 뺄셈

 

Vector3 v1 = new Vector3(1f, 2f, 0f);

Vector3 v2 = new Vector3(2f, 1f, 0f);

// 벡터의 덧셈

Debug.Log("v1 + v2 = " + (v1 + v2));

// 벡터의 뺄셈

Debug.Log("v1 - v2 = " + (v1 - v2));

 

 

벡터의 덧셈과 뺄셈은 간단하게 일반 덧셈과 뺄셈을 하듯이 연산자를 사용하면 바로 구할 수 있다.

 

벡터와 스칼라의 곱셈

 

// 벡터와 스칼라의 곱셈

Vector3 v1 = new Vector3(1f, 1f, 0f);

int scalar = 4;

Debug.Log("v1 * scalar = " + (v1 * scalar));

 

 

벡터와 스칼라, 단일 정수 혹은 단일 실수와의 곱셈 역시 일반 계산과 같이 간단하다.

 

벡터의 길이

 

Vector3 v1 = new Vector3(2f, 2f, 0f);

// 벡터의 길이

Debug.Log("length of v1 = " + (v1.magnitude));

 

 

벡터의 길이는 Vector3 구조체에 포함되어 있는 magnitude 프로퍼티를 통해서 가져올 수 있다. 이것은 Vector2에서도 똑같다.

 

벡터의 정규화

 

Vector3 v1 = new Vector3(2f, 2f, 0f);

// 정규화된 단위 벡터

Vector3 normalizedVector = v1.normalized;

Debug.Log("||v1|| = " + normalizedVector);

// 단위 벡터의 길이 확인

Debug.Log("length of ||v1|| = " + normalizedVector.magnitude);

 

 

Vector3 구조체의 normalized 프로퍼티를 이용하면 정규화된 단위 벡터를 가져올 수 있다. magnitude 프로퍼티를 다시 사용해보면 단위 벡터의 길이가 1임을 확인할 수 있다.

 

벡터의 내적

 

[그림 9]

 

아래 코드 예시에 정의된 각 벡터는 [그림 9]와 같다.

 

Vector3 v1 = new Vector3(2f, 0f, 0f);

Vector3 v45 = new Vector3(1f, 1f, 0f);

Vector3 v90 = new Vector3(0f, 2f, 0f);

Vector3 v135 = new Vector3(-1f, 1f, 0f);

 

// 벡터의 내적

Debug.Log("v1 . v45 = " + Vector3.Dot(v1, v45));

Debug.Log("v1 . v90 = " + Vector3.Dot(v1, v90));

Debug.Log("v1 . v135 = " + Vector3.Dot(v1, v135));

 

// 두 벡터 사이의 각도

Debug.Log("v1 . v45 = " + Vector3.Angle(v1, v45));

Debug.Log("v1 . v90 = " + Vector3.Angle(v1, v90));

Debug.Log("v1 . v135 = " + Vector3.Angle(v1, v135));

 

 

벡터의 내적을 구하려면 Vector3 클래스의 정적 함수인 Dot 함수를 사용하면 된다. 벡터의 내적에 대해서 설명했듯이, v1과 v45 사이의 각도는 90도 보다 작기 때문에 0보다 큰 값이 나왔고, v1과 v90 사이 각은 정확히 90도이기 때문에 0, v1과 v135 사이 각은 90도보다 커서 0보다 작은 값이 나온 것을 확인할 수 있다.

 

덤으로 Vector3의 또 다른 정적 함수인 Angle 함수를 사용하면 두 벡터 사이의 각을 얻을 수 있다.

 

벡터의 외적

 

Vector3 v1 = new Vector3(2f, 0f, 0f);

Vector3 v2 = new Vector3(0f, 0f, 2f);

 

// 벡터의 외적

Debug.Log("v1 X v2 = " + Vector3.Cross(v1, v2));

 

 

벡터의 외적은 Vector3 클래스의 정적 함수인 Cross 함수를 통해서 구할수 있다.

 

이번 섹션에서는 벡터와 그 계산법을 알아보고 유니티 엔진에서는 어떻게 사용되는지 알아보았습니다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Tilemap (3) 

타일맵에 콜라이더 추가하기

 

작성 기준 버전 :: 2019.1.4f1

 

이전 섹션들에서는 타일맵 생성 방법2D 엑스트라의 룰 타일을 이용한 타일 자동 연결 기능을 알아보았다. 이번 섹션에서는 타일맵에 콜라이더를 추가하는 방법을 배워볼 것이다.

 

이제까지 타일맵에 사용될 타일 이미지를 만들고 가져오는 방법, 타일맵을 만들고 사용하는 방법들을 배웠다. 이제 만들어낸 타일맵을 이용해서 맵을 그려내면 게임 레벨이 될 것이다. 하지만 여기에 아직 부족한 점이 있다.

 

지금까지 배운 것들로는 맵을 그리기만 할 수 있다. 무슨 말인가 하면, 2D RPG 류의 게임에서는 어떤 타일은 벽이 되서 캐릭터가 이동하는 것을 막는 장애물이 되어야 하고, 플랫폼 게임(Platform Game)에서는 타일이 캐릭터가 딪고 설 바닥이 되어주어야 한다. 즉, 타일에 콜라이더를 추가해서 물리적인 작용이 가능하게 만들어야 한다는 뜻이다.

 

그림 1

 

플랫폼 게임을 만드는데 노란 공이 떨어져서 바닥에 닿으면 튕기게 만들고 싶다고 가정해보자.

 

그림 2

 

노란 공에 물리효과를 주기 위해서 Circle Collider 2D 컴포넌트와 Rigidbody 2D 컴포넌트를 부착해주었다. 그리고 꽤 그럴듯하게 공처럼 튀기게 만들기 위해서 물리 머티리얼(Physics Material)까지 넣어주었다.

 

그림 3
그림 4

 

하지만 타일맵에 물리적인 컴포넌트가 아무것도 없는 상태이기 때문에 플레이를 시작하면 떨어지는 공은 타일맵을 그냥 통과해버린다. 

 

그림 5

 

타일맵 콜라이더 2D 컴포넌트(Tilemap Collider 2D Component)

 

이전 섹션을 진행해왔다면 하이어라키 뷰에 존재하는 타일맵은 게임 오브젝트하나로 존재하기 때문에 어떻게 콜라이더를 배치해야할지 난감할 수도 있다.

 

그림 6

 

타일맵을 위한 콜라이더를 유니티에서는 이미 제공하고 있다. 타일맵 콜라이더 2D 컴포넌트(Tilemap Collider 2D Component)가 바로 그것이다.

 

그림 7

 

타일맵 컴포넌트가 붙어있는 게임 오브젝트에 타일맵 콜라이더 2D 컴포넌트를 부착하면 씬에서 위의 이미지와 같이 각 타일마다 콜라이더가 생겼음을 알 수 있다.

 

그림 8

 

타일맵에 콜라이더 컴포넌트를 붙인 상태로 다시 게임을 플레이해보면 떨어진 공이 바닥에 맞고 튕기는 것을 볼 수 있다.

 

 

컴포지트 콜라이더 2D 컴포넌트(Composite Collider 2D Component)

 

[그림 8]을 보면 타일맵 컴포넌트 2D를 이용해서 생성된 콜라이더가 각 타일마다 따로 생성되어 있는 것을 볼 수 있다. 이렇게 분할된 콜라이더는 퍼포먼스 상의 문제와 가끔 이동하는 캐릭터가 콜라이더에 끼어서 움직이지 못하게 되는 등의 문제가 발생할 수 있다.

 

그런 문제를 해결하기 위해서 제공되는 것이 컴포지트 콜라이더 2D 컴포넌트이다. 이 컴포넌트는 해당 컴포넌트가 붙어있는 게임 오브젝트의 하위에 존재하는 콜라이더들을 하나로 묶어주는 역할을 한다.

 

그림 9

 

컴포지트 콜라이더 2D 컴포넌트를 사용하기 위해서는 타일맵 콜라이더 2D 컴포넌트를 부착한 컴포넌트에 컴포지트 콜라이더 2D 컴포넌트를 부착하고 타일맵 콜라이더 2D 컴포넌트의 Used By Composite 프로퍼티를 체크해주면 된다.

 

그림 10

 

그렇게 하고 나서 씬 뷰에서 타일맵 게임 오브젝트를 선택해보면 초록색 콜라이더 박스가 타일마다 나누어지지 않고 하나로 합쳐져 있는 것을 확인할 수 있다.

 

그림 11

 

하지만 아직 설정이 다 끝나지 않았다. 플레이를 눌러보면 타일맵이 공과 함께 떨어지는 어이없는 상황이 발생한다. [그림 9]를 보면 그 이유를 조금 짐작할 수 있는데 컴포지트 콜라이더 2D 컴포넌트를 추가할 때, 리지드바디 2D 컴포넌트(Rigidbody 2D 컴포넌트)가 자동으로 추가된 것을 알 수 있는데, 리지드바디 컴포넌트는 게임 오브젝트가 외부의 힘이나 토크를 받아 사실적인 물리적인 운동을 보이도록 도와주는 컴포넌트이다.

 

그림 12

 

자동으로 추가된 리지드바디 2D 컴포넌트를 보면 바디 타입(Body Type)이 다이나믹(Dynamic)으로 설정있는 것을 알 수 있다. 즉 타일맵의 리지드바디가 고정된 것이 아니기 때문에 공과 함께 떨어지는 것이다.

 

그림 13
그림 14

 

바디 타입을 고정(Static)으로 변경하고 실행해보면 [그림 14]와 같이 타일맵이 떨어지지 않고 정상적으로 동작하는 것을 확인할 수 있다.

 

다만 컴포지트 콜라이더 2D를 사용하는 경우에 주의할 점은 하위에 있는 모든 콜라이더를 하나로 통합하기 때문에, 플랫폼 게임을 만들 때 벽 타일의 콜라이더와 바닥 타일의 콜라이더가 플레이어와 충돌 시 다른 동작을 하게 만들고 싶다면 벽 타일의 타일맵과 바닥 타일의 타일맵을 분리하거나, 캐릭터가 충돌한 방향을 검출해서 벽인지 바닥인지를 검출하는 등의 추가 작업이 필요하다.  

 


 

Tilemap (1) - 2D 게임의 기본 타일맵!

Tilemap (2) - 룰 타일로 타일맵 자동 연결하기

Tilemap (3) - 타일맵에 콜라이더 추가하기

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Tilemap (2) 

룰 타일로 타일맵 자동 연결하기

 

작성 기준 버전 :: 2019.1-2019.2

 

[이 포스트의 내용은 유튜브 영상으로도 시청하실 수 있습니다]

 

지난 섹션에서는 간단하게 타일맵을 만들고 사용하는 방법에 대해서 알아보았다. 이번 섹션에서는 룰 타일 기능을 이용한 동일 타일을 연달아 놓았을 때, 자동으로 연결되는 기능을 구현하는 방법을 알아보자.

 

타일의 자동 연결은 어떻게?

 

 

같은 타일을 놓으면 오른쪽 십자가처럼 자동으로 연결되기를 바랄 수 있다. 하지만 유니티 타일맵 기본 기능 만으로는 같은 타일을 옆에 놓아봤자 왼쪽 십자가처럼 끊어진 십자가만 놓아지고 오른쪽 십자가처럼 만들려면 직접 일일이 배치를 해야한다.

 

유니티 2D 엑스트라(Unity 2D Extra)

 

타일을 자동으로 연결해주는 기능은 기본 타일맵에서는 제공하지 않고, 유니티 테크놀러지에서 만들어서 깃허브에 올려둔 별도의 기능인 2D 엑스트라 임포트해서 사용해야 한다(링크에서 2D Extra를 다운로드 받으면 된다).

 

 

그리고 다운로드 받은 파일의 압축을 풀고 2d-extra-master 폴더를 프로젝트 뷰의 Assets 폴더 안에 넣어주면 된다.

 

룰 타일(Rule Tile)

 

유니티에서 같은 룰 타일을 근접 배치했을 때, 정해둔 규칙에 따라서 다른 스프라이트를 표시하도록 하는 것을 룰 타일(Rule Tile)이라고 부른다.

 

 

프로젝트 뷰에서 Create 버튼을 눌러보면 드롭다운 메뉴 최상단에 Tiles라는 새로운 항목이 생긴 것을 볼 수 있다. 이것은 방금 추가한 2D Extra 기능을 임포트하면서 생긴 것으로, Tiles 중에서 Rule Tile을 선택하면 새로운 룰 타일을 만들 수 있다.

 

  

룰 타일을 생성하고 선택해보면 위와 같은 화면이 표시된다.

 

 

룰 타일을 설정하는 순서로 먼저 디폴트 스프라이트와 디폴트 게임을 설정한다. 예제에서는 닫힌 타일을 기본 스프라이트로 정했고, 디폴트 게임 오브젝트로는 앞에서 만든 Wall 타일 팔레트를 설정했다.

 

  

아래의 Tiling Rule을 + 버튼을 클릭해서 추가하고 연결되어야 하는 경우의 수를 모두 정의해주면 된다. 약간은 반복성이 짙은 작업이지만, 모든 타일을 일일이 선택해서 작업하는 것보다는 한 번 타일 규칙을 설정하고 편하게 작업하는 것이다 좋다.

 

 

적절하게 타일링 규칙을 모두 설정했다면 설정한 룰 타일을 사용하고자 하는 타일 팔레트의 빈 칸에 드래그한다. 그러면 직접 만든 룰 타일이 팔레트에 포함된다.

 

 

그리고 씬 뷰에서 일반 타일과 룰 타일을 사용해서 타일을 그려보면 직접 정한 룰에 따라서 자동으로 타일이 연결되는 것을 확인할 수 있다.

 

 

 

타일링 규칙

 

타일 규칙

 

간단하게 룰 타일의 기능을 맛보았으니 이제 실제로 타일링 규칙들이 무엇을 의미하는지를 알아보자.

 

 

첫 번째 규칙은 초록색 화살표이다. 초록색 화살표는 해당 방향에 같은 룰 타일이 놓여져 있는 경우를 의미한다.

 

 

 

 

두 번째 규칙은 빨간색 엑스 표시이다. 이 표시는 해당 방향에 같을 룰 타일이 없는 경우를 의미한다.

룰 타일의 주요 규칙은 이 두 가지로 대부분 표현할 수 있다. 어느 방향에 같은 룰 타일이 있느냐 없느냐에 따라서 대부분의 경우를 구현할 수 있다.

 

방향규칙

 

하지만 모든 방향에 대한 경우를 일일이 구현하는 일은 굉장히 힘든 반복작업이기 때문에 룰 타일의 규칙에는 추가 방향 규칙 역시 제공한다.

 

Fixed

 

 

Fixed는 고정된 방향에만 적용하거나 방향에 상관이 없는 경우에 사용된다. 

 

 

대체로 모든 방향에 타일이 있는 경우나 십자형태로 배치된 가운데 블록처럼, 가운데 들어가는 타일에 주로 사용된다.

 

Rotated

 

 

Rotated는 중심을 기준으로 90도, 180도, 270도 회전시킨 방향에도 똑같이 적용하는 규칙이다.

 

  

주로 십자가 끝부분처럼 이미지가 회전되어 표현되어야 하는 경우에 사용된다.

 

MirrorX

 

 

MirrorX는 좌우 방향으로 대칭시켜주는 규칙이다. 왼쪽 타일과 오른쪽 타일이 같을 때 사용된다.

 

MirrorY

 

 

MirrorY는 상하 방향으로 대칭시켜주는 규칙이다.

 

 

위쪽 타일과 아래쪽 타일이 같아서 대칭 시켜줄 때 주로 사용된다.

 

MirrorXY

 

 

MirrorXY는 MirrorX 규칙과 MirrorY 규칙을 섞은 것으로 상하좌우 모두 대칭시켜주는 규칙이다.

 

  

모서리 타일에 주로 사용된다.

 

 

 

출력 규칙

 

싱글(Single)

 

 

타일이 얼마나 설치되든 같은 이미지만 사용하려고 할 때 사용된다. 너무 많이 사용되면 반복되는 타일이 많아짐으로써 배경이 단조롭게 보이는 단점이 있다.

 

랜덤(Random)

 

 

여러 타일을 섞어서 무작위로 출력하는 방법이다. Size를 늘려서 중간에 깨진 타일을 섞어서 출력한다던가 Shuffle을 Rotated로 넣어서 회전된 타일을 출력한다던가 하는 방식으로 사용할 수 있다. 타일맵에 무작위성을 줌으로써 타일맵의 단조로움을 줄여줄수 있다.

 

대신 무작위로 사용되는 타일은 일반 타일과 회전 타일 등과의 연속성을 잘 확인해야 한다. 일반 타일이 무작위 출력된 타일이나 회전된 타일과의 연결이 부자연스럽게 이어지면 플레이어들의 눈에 심하게 띄는 문제가 발생한다.

 

애니메이션(Animation)

 

 

여러 타일을 설정된 시간에 맞춰 순서대로 출력하여 애니메이션을 보여주는 타일의 설정이다. 주로 배경에 흐르는 폭포수 같은 효과를 줄 때 주로 사용된다.

 

 

사용시 주의점

 

2D 엑스트라는 아직 유니티 테크놀러지 측에서도 개선 중인 기술로 룰 타일을 사용할 때, 주의해야할 점이 있다.

 

 

이 문제는 심각한 이슈사항인데, 타일 팔레트에 룰 타일을 올려둔 채로 씬의 타일맵에 계속 그려보면서 타일링 룰을 수정하면 어느 시점부터 심각한 수준의 메모리 누수가 발생한다. 특히 유니티 엔진이 응답없음 상태가 되고 메모리 점유율이 계속 올라가는 상태라면, 유니티를 종료하고 다시 실행해도 실행하자마자 메모리 누수가 시작될 확률이 높다.

 

그렇기 때문에 타일맵과 룰 타일을 안정적으로 사용하고 싶다면, 룰 타일의 타일링 룰을 먼저 작성한 뒤 팔레트를 만들어서 룰 타일을 올리고 간단하게 씬에서 테스트한 뒤, 문제가 없다면 그대로 사용하고, 만약 타일링 룰을 수정해야 한다면, 현재 타일 팔레트를 삭제하고 타일링 룰을 수정한 뒤 다시 타일 팔레트를 만들 것을 권장한다.

 


 

Tilemap (1) - 2D 게임의 기본 타일맵!

Tilemap (2) - 룰 타일로 타일맵 자동 연결하기

Tilemap (3) - 타일맵에 콜라이더 추가하기

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Tilemap (1)

2D 게임의 기본 타일맵!

 

작성 기준 버전 :: 2019.1 - 2019.2

 

[이 포스트의 내용은 유튜브에서 영상으로도 시청하실 수 있습니다]

 

  

예전에 RPG메이커를 사용했을 때는 맵이 타일(Tile) 방식으로 이루어져 있어서 타일 팔레트를 가져와서 마치 그림 그리듯이 원하는 타일을 칠해주는 방식으로 맵을 만들 수 있었다.

 

유니티 엔진을 처음 배웠던 5 버전에서는 이러한 기능이 없어서 2D 맵 오브젝트를 직접 배치하거나 타일맵 기능을 직접 구현해야만 했었다. 하지만 유니티 2017.2 버전에서부터 타일맵 기능이 유니티에도 추가되었다. 맵오브젝트를 배치할 필요없이 그림 그리듯이 맵을 만들 수 있다는 것은 굉장한 장점이다. 

 

 

 

타일맵의 타일을 하나 추가해서 아래쪽 이미지와는 조금 다를 수 있다.

  

샘플용 간단한 타일맵 이미지를 다운받은 뒤, 타일맵의 사용법에 대해서 알아보자. 구글에서 적당한 리소스를 다운받아서 사용해도 좋다.

 

 

타일 팔레트(Tile Palette) 만들기

 

타일맵을 씬에 배치하기 이전에 먼저 타일맵을 색칠할 수 있는 타일의 종류를 모아둔 것을 만들어야 하는데 이것을 유니티 엔진에서는 타일 팔레트(Tile Palette)라고 부른다. 이 타일 팔레트를 만드는 방법에 대해서 배워보자.

 

타일 팔레트가 될 이미지 임포트 & 세팅

 

먼저 타일 팔레트에 들어갈 이미지를 임포트하고 타일맵에 사용하기 좋게 세팅해야 한다.

 

 

다운로드 받은 타일맵 이미지를 프로젝트에 임포트한다. 처음으로 임포트한 이미지는 대부분 설정이 위와 같을 것이다. 타일맵 이미지의 임포트 세팅을 적절하게 설정해주어야 한다. 

 

우선 Pixels Per Unit은 이미지의 픽셀을 몇 개를 단위로 유니티 엔진의 공간 상에서 1단위(유닛, Unit)로 표현할 것인가에 대한 설정이다. 유니티에서의 1단위는 보통 1m를 의미한다. 즉, 몇 개의 픽셀을 1m로 볼 것인가를 의미하는 셈이다. 타일맵 이미지를 열어서 확인 해보면 알겠지만 타일맵의 이미지는 한 칸당 128픽셀로 이루어져 있다. 한 칸을 1미터로 볼 것이기 때문에 Pixel Per Unit에 128을 입력해주자.

 

그 다음 설정은 Sprite Mode 값이다. 이 설정의 기본 값은 Single인데 이미지 한 장을 한 장의 스프라이트(Sprite)로 본다는 의미이다. 타일맵 이미지를 보면 알 수 있겠지만 타일맵 이미지는 한 장이 하나의 타일이 아니라 여러 장의 타일이 그려져 있는 것을 알 수 있다. 이 때문에 한 장의 이미지가 하나의 스프라이트가 아닌 그려진 타일의 수만큼의 스프라이트를 가져야한다는 것을 알 수 있다. 

 

 

Multiple로 설정해주자. 그 다음에는 이 이미지가 어떻게 나누어져야 하는지를 정하기 위해서 스프라이트 에디터(Sprite Editor) 버튼을 클릭한다.

 

 

 

그러면 스프라이트 에디터 창이 열리는데 기본적으로 타일맵 이미지가 하나의 스프라이트로 이루어지고 있음을 확인할 수 있다.

 

 

이미지를 여러 개의 스프라이트로 나누기 위해서 스프라이트 에디터 창의 상단 메뉴 중에서 슬라이스(Slice)를 선택하고 자동(Autometic)으로 되어 있는 타입을 Grid by Cell Count로 바꾼다.

 

 

 

그리고 컬럼(Column)과 로우(Row)를 각각 5와 3으로 변경하고 슬라이스 버튼을 누른다.

 

 

 

그렇게 하면 하나의 스프라이트로 되어 있던 타일맵 이미지가 여러 개의 스프라이트로 나누어지는 것을 볼 수 있다. 상단 바의 Apply 버튼을 누르고 적용한다.

 

 

 

프로젝트 뷰에서도 이 모습을 확인할 수 있다.

 

타일 팔레트 만들기

 

 

타일 팔레트는 상단 메뉴바에서 [Window>2D>Tile Palette] 항목을 선택한다.

 

 

그렇게 하면 위의 이미지와 같이 타일 팔레트 뷰가 열린다. 여기서 Create New Palette 버튼을 누르고

 

 

팔레트의 이름을 정하고 Create 버튼을 누른 뒤 저장하면 빈 타일 팔레트가 생성된다.

 

 

그 다음 타일로 만들고자 하는 스프라이트를 타일 팔레트로 드래그 하고 저장하면 타일맵 에셋들이 프로젝트 뷰에 생성되는 것을 볼 수 있다.

 

 

 

그리고 타일 팔레트에도 추가한 타일틀이 보여지는 것을 확인할 수 있다. 여기서 이 원하는 타일을 선택하고 씬에 배치된 타일맵에 타일을 그리면 된다.

 

 

 

타일맵 생성

 

 

우선 타일맵을 생성하기 위해서는 Create>2D>Tilemap을 선택하면 된다. 이 생성 과정의 경우에는 하이어라키(Heirarchy) 뷰에서 우클릭을 하거나 하이어라키 뷰 상단의 Create 메뉴 버튼, 혹은 상단 메뉴바의 GameObject 메뉴를 선택해서도 똑같이 만들 수 있다.

 

 

타일맵을 생성하면 위의 이미지와 같이 게임씬에 타일맵을 그리기 쉽게 격자선을 그려주는 그리드(Grid) 컴포넌트가 부착된 게임 오브젝트가 생성된다.

 

 

그리고 자식 게임 오브젝트로는 타일맵 컴포넌트(Tilemap Component)와 타일맵 렌더러 컴포넌트(Tilemap Renderer Component)가 부착된 게임 오브젝트가 생성된다. 앞서 만든 타일 팔레트에서 타일을 선택해서 이 타일맵 게임 오브젝트에 타일을 그려서 게임 맵을 만들면 된다. 그리드 아래에 여러 타일맵 게임 오브젝트를 넣어서 여러 층의 타일맵을 겹쳐서 맵을 만들 수도 있다.

 

타일맵 그려보기

 

 

 

타일맵이 만들어졌으면 타일 팔레트에서 타일을 선택해서 맵을 그려보자. 클릭하고 드래그하면 맵이 손쉽게 그려진다. 그리고 시프트(Shift) 키를 누르고 클릭 & 드래그하면 그려진 타일들이 지워진다.

 

 

 

추가로 [ ] 대괄호 키를 누르면 타일을 회전시킬 수 있다.

 


 

Tilemap (1) - 2D 게임의 기본 타일맵!

Tilemap (2) - 룰 타일로 타일맵 자동 연결하기

Tilemap (3) - 타일맵에 콜라이더 추가하기 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Prefab 

게임 오브젝트를 에셋화 하기

 

작성 기준 버전 :: 2019.1.4f1

 

[본 포스트의 내용은 유튜브 영상을 통해서 시청하실 수도 있습니다]

 

유니티에서 게임 오브젝트는 씬에 배치될 수 있는 오브젝트를 의미한다. 이 게임 오브젝트에 어떤 컴포넌트가 붙는가에 따라서 그 게임 오브젝트의 역할이 결정되는데, 씬에 하나만 배치되는 오브젝트는 컴포넌트를 직접 부착해서 배치할 수는 있지만 똑같은 오브젝트를 많이 배치해야 되는 경우에 매번 배치할 때마다 필요한 컴포넌트를 부착하는 작업을 해야한다면 이것은 매우 비효율적인 작업이 된다. 

 

일일이 게임 오브젝트를 생성한 다음 컴포넌트를 붙이는 비효율에서 벗어나기 위해서 제일 처음 만들어진 게임 오브젝트를 복사해서 배치할 수도 있는데, 이것은 또 다른 비효율적인 작업에 봉착하게 된다. 만약 이렇게 붙여넣은 오브젝트들의 크기를 전부 2배로 키워야 한다면? 그럼 붙여넣은 게임 오브젝트들을 일일이 찾아서 스케일 값을 바꿔주어야 한다. 이것 역시 심각하게 비효율적인 작업이다.

 

이러한 예시 이외에 어떤 게임 오브젝트를 게임이 진행하는 도중에 생성해서 배치해야 된다면, 코드 상에서 빈 게임 오브젝트를 생성하고, 거기에 필요한 컴포넌트를 붙여서 일일이 초기화해서 배치를 하는 것 역시 비효율적이다.

 

 

비효율적인 작업들 1 : 새 오브젝트마다 손수 컴포넌트 붙이고 설정하기

 

앞서 제시한 예시들을 하나씩 따라가보자.

 

 

우리는 이제 씬에 이른바 "Elegance Black Box"라고 명명된 검은색의 Black Box 컴포넌트가 부착된 상자를 여러 개 배치하려고 한다. 이 멋진 검은 상자를 만들기 위해서 우리는 다음과 같은 작업을 해야한다.

 

 

먼저 새 상자를 만든다.

 

 

새 상자의 이름을 "Elegance Black Box"로 변경한다.

 

 

그 다음 머티리얼에 검은 색 머티리얼을 넣고 Black Box 컴포넌트를 붙여준다(사실 따로 순서를 진행할 수도 있지만 그만큼 번거롭고 지루해지기 때문에 그냥 합쳤다).

 

자 총 4단계의 과정을 거쳤다. 이 작업을 만들고자 하는 "Elegance Black Box"의 갯수만큼 반복하면 된다. 고작 4단계인데 이렇게 번거롭다. 만약 더 복잡한 구조의 게임 오브젝트라면 어떻겠는가?

 

 

비효율적인 작업들 2 : 배치된 게임 오브젝트 복제하기

 

 

유니티 엔진에서는 복제하고자 하는 게임 오브젝트를 선택하고 우클릭하여 [Duplicate] 항목을 선택하거나 [Ctrl + D] 단축키를 눌러서 복제할 수 있다.

 

 

와! 일일이 새 게임 오브젝트를 만들고 컴포넌트를 붙이는 작업을 하지 않아도 된다! 혁명적인가? 분명 여기까지는 혁명적이다. 하지만 원수같은 기획자들이 "Elegance Black Box"를 좀 더 우아하게 강조하기 위해서 크기를 25% 키우자고 주장했다.

 

 

그나마 예시에서는 갯수가 적고 하이어라키 뷰에서 오브젝트가 흩어져 있지 않아서 모두 선택해서 빠르게 해결했다. 하지만 하이어라키 뷰에서 다른 게임 오브젝트 밑에 숨어있다거나 흩어져있다면 일일이 찾아서 수정해야 한다. 물론 하이어라키 뷰의 검색 기능을 이용하면 훌륭하게 해결할 수 있을 지도 모른다. 그러나 이런 검색 작업 역시 비효율적인것은 사실이다.

 

 

비효율적인 작업들 3 : 코드에서 동적으로 생성하기

 

이번에는 동료 디자이너가 "멋진 검은 상자가 게임 중에 동적으로 생성되면 좋겠는데!"라고 말했다. 

 

public static BlackBox CreateNewBlackBox()

{

    var newBox = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent<BlackBox>();

    newBox.name = "Elegance Black Box";

    newBox.GetComponent<Renderer>().material = Resources.Load<Material>("M_Black");

    return newBox;

}

 

거기에 당신은 위와 같이 블랙 박스를 생성하는 코드를 만들어 냈다. 이러면 끝난 것일까? 아니다. 디자이너가 블랙 박스에 대해서 수정사항을 가지고 올 때마다 당신은 코드를 수정해야 한다. 거기에 컴파일 시간은 덤이다! 그리고 지금은 간단한 오브젝트라 코드가 몇 줄 되지 않지만 복잡한 오브젝트면 코드의 양이 늘어나고 거기에 더불어 버그의 확률도 함께 상승한다.

 

 

 

우리의 구세주 프리팹

 

이러한 모든 문제를 해결하기 위해서 있는 것이 바로 프리팹이다. 프리팹은 게임 오브젝트와 거기에 붙여진 컴포넌트와 그 프로퍼티들을 에셋의 형태로 저장하는 것이다.

 

프리팹 만들기

 

 

 

프리팹을 만드는 방법은 아주 간단하다. 하이어라키 뷰에서 프리팹으로 만들고자 하는 게임 오브젝트를 선택해서 프로젝트 뷰로 끌어다 놓기만 하면 된다. 프리팹이 된 게임 오브젝트는 앞의 아이콘이 무채색 육면체에서 파란 육면체로 바뀐다.

 

배치된 게임 오브젝트 한꺼번에 변경하기

 

이번에도 아까 전처럼 씬에 배치된 모든 블랙 박스의 크기를 변경하고 싶을 수 있다. 프리팹으로는 이런 작업이 아주 간단하다.

 

 

프로젝트 뷰에서 원본 프리팹을 선택하고 프리팹의 크기를 변경해주면 씬에 배치된 모든 프리팹 인스턴스의 크기가 함께 변경된다. 하지만 이 방법은 씬에 배치된 각각의 인스턴스의 프로퍼티가 수정된 상태라면 적용되지 않으니 주의해야 한다.

 

프리팹 인스턴스에서 편집

 

 

위 예시에서는 프리팹 원본에서 수정된 것을 프리팹 인스턴스로 적용되는 내용이었다. 반대로 씬에 배치된 프리팹 인스턴스를 수정하고 이것을 원본 프리팹에 적용할 수도 있다. 씬에 배치된 프리팹 인스턴스 게임 오브젝트를 선택하면 일반 게임 오브젝트와는 다르게 인스펙터 뷰의 게임 오브젝트의 이름 아래에 Prefab : Open, Select, Override 버튼을 볼 수 있다.

 

 

여기서 Open 버튼을 선택하면 선택된 프리팹의 원본만을 수정할 수 있는 전용 씬으로 이동된다. 여기서는 프로젝트 뷰에서는 보이지 않는 프리팹 원본의 깊은 자식 오브젝트까지 열어서 수정할 수 있게 된다. 또한 수정된 프리팹의 내용은 자동으로 저장되며 하이어라키 뷰의 프리팹 아이콘 옆의 < 버튼을 클릭하면 다시 원래 씬으로 돌아올 수 있다.

 

원본 프리팹을 더블 클릭하거나 씬에 배치된 프리팹 인스턴스 옆의 > 버튼을 클릭해도 프리팹 수정 씬으로 들어올 수 있다.

 

 

Select 버튼을 클릭하면 프로젝트 뷰의 원본 프리팹이 바로 선택된다.

 

 

Override 버튼은 만약 프리팹 인스턴스에 원본 인스턴스와 달라진 점이 있다면 내용이 나타난다. 여기서 Revert All을 선택하면 프리팹 인스턴스의 변경 사항이 초기화되고 프리팹 원본 값으로 돌아간다. Apply All을 선택하면 프리팹 인스턴스의 수정 사항이 반대로 프리팹 원본에 덮어 씌워진다.

 

프리팹 인스턴스화

 

프로젝트 뷰에 존재하는 프리팹 원본은 에셋 상태로 이 상태 그대로는 게임 씬에서 보거나 사용할 수 없다. 이것을 게임 씬에 배치하고 사용할 수 있게 생성하는 과정을 인스턴스화라고 한다. 프리팹 인스턴스화는 게임 오브젝트의 Instantiate() 함수를 이용해서 할 수 있다.

 

프로젝트 뷰에 있는 게임 오브젝트는 크게 두 가지 방법으로 가져올 수 있다.

 

Resources 폴더에서 가져오기

 

 

첫 번째 방법은 Resources 폴더에서 가져오는 것이다. 이 방법은 어느 경로이든 무관하게 가져오고자 하는 프리팹이 프로젝트 뷰에서 Resources 폴더 안에 들어있기만 하면 된다. 단, Resources 폴더에 들어있는 파일들은 게임이 실행되면 무조건 메모리에 적재되기 때문에 메모리 이슈를 일으키고 싶지 않다면, 필요한 에셋만을 Resources 폴더에 넣어둘 것을 권장한다.

 

public static BlackBox CreateNewBlackBox()

{

    var boxPrefab = Resources.Load<BlackBox>("Elegance Black Box");

    return Instantiate(boxPrefab);

}

 

그 다음 Resources.Load() 함수로 Resources 폴더 안의 프리팹을 가져와서 Instantiate() 함수로 씬에 생성할 수 있다.

 

씬에 배치된 게임 오브젝트의 컴포넌트의 프로퍼티로 참조하기

 

public class BoxSpawn : MonoBehaviour

{

    [SerializeField]

    private GameObject boxPrefab;

 

    private void Start()

    {

        Instantiate(boxPrefab);

    }

}

 

두 번째 방법은 씬에 배치된 게임 오브젝트에 부착된 컴포넌트의 프로퍼티로 프리팹 원본을 참조하고 있다가 생성하는 방법이다.

 

 

씬에 Box Spawner 게임 오브젝트를 만들고 위에서 작성한 Box Spawn 컴포넌트를 부착하고 Box Prefab 프로퍼티에 프리팹을 할당해주면 된다. 그러면 게임이 시작되면 박스 스포너가 블랙 박스를 생성하는 것을 확인할 수 있다.

 

기타

 

위에서 제시한 방법 이외에도 에셋 번들에서 가져와서 생성하는 방법 등 다른 기능과 연계된 심화 방법들이 존재한다.

 

 

프리팹의 장점

 

게임 오브젝트가 프리팹화됨으로써 얻을 수 있는 장점은 굉장히 많다. 첫 번째는 재사용이 굉장히 편하다는 점이고, 씬에 흩어져서 배치된 프리팹의 인스턴스들을 한꺼번에 수정하기도 쉽다. 그리고 프로그래머가 컴포넌트만 제대로 만들어준다면, 게임 디자이너들이 프로그래머에게 요청하지 않고도 손쉽게 게임 요소들을 수정할 수 있다는 점이 제일 큰 장점이다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts