개발단에 가입하여 베르의 게임 개발 유튜브를 후원해주세요!

 

베르의 게임 개발 유튜브

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다! 게임 개발에 도움이 되는 강좌들을 올리는 채널입니다! [투네이션 후원] https://toon.at/donate/637735212761460238 [유니티 어필리에이트

www.youtube.com

 

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다!

이번에는 유니티 2020에서 추가된 Properties 기능에 대해서 알아봅시다.

 

사용 엔진 버전 : 2020.3

 

타임라인

0:00 인트로

0:08 인스펙터에서 여러 개의 오브젝트를 컨테이너에 담기

0:26 1. 일일이 집어넣기

0:43 2. 인스펙터 잠그기

1:13 3. Properties 이용하기

1:45 아웃트로

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번에는 유니티 에디터의 Properties 기능에 대해서 알아보겠습니다.

인스펙터에서 여러 개의 오브젝트를 컨테이너에 담기

유니티에서는 에디터의 인스펙터에서 오브젝트를 담을 컨테이너를 이렇게 스크립트에서 리스트나 배열로 만들 수 있습니다.

스크립트에서 만든 리스트나 배열은 에디터에서 이렇게 보여지죠.

그리고 이 컨테이너에 씬 안에 있는 오브젝트를 끌어넣을 수 있습니다.

1. 일일이 집어넣기

그런데 한꺼번에 여러 개의 오브젝트를 넣기 위해서 여러 오브젝트를 선택하면 컴포넌트가 붙어있는 오브젝트의 선택이 풀리면서 인스펙터에서 사라집니다.

그래서 인스펙터를 잠그는 방법을 몰랐을 때는 오브젝트를 하나하나 선택해서 일일이 집어넣을 수 밖에 없었죠.

2. 인스펙터 잠그기

하지만 인스펙터 뷰 우측 상단에 있는 자물쇠 모양 버튼을 클릭하면 인스펙터가 잠기면서 지금 선택한 오브젝트로 인스펙터가 고정됩니다.

그러면 다른 오브젝트를 선택해도 인스펙터가 바뀌지 않고 여러 오브젝트를 한꺼번에 컨테이너에 넣을 수 있게 되죠.

하지만 인스펙터 잠금을 푸는 것을 깜빡하면 다른 오브젝트를 변경하기 위해 선택해도 인스펙터가 변경되지 않아서 헤매게 되는 실수가 발생합니다.

그래서 작업이 끝나면 인스펙터 잠금을 일일이 풀어줘야 한다는 단점도 있습니다.

3. Properties

이 모든 단점을 해결하기 위한 기능이 바로 Properties입니다.

이 기능은 2020 버전에 추가된 기능으로 게임 오브젝트에 우클릭하고 제일 아래의 [Properties...] 항목을 선택하면 Properties 창이 열리며 인스펙터에서 보이는 것과 동일한 내용을 볼 수 있게 됩니다.

여기서는 다른 오브젝트를 선택해도 Properties 창의 내용이 바뀌지 않습니다.

그래서 여러 오브젝트를 선택해서 컨테이너로 한 번에 넣어줄 수 있습니다.

그리고 작업이 끝나면 어떤 잠금을 푼다던가 하는 일에 신경쓰지 않고 그냥 Properties 창을 꺼버리면 됩니다.

아웃트로

이번 영상에서는 유니티 에디터의 Properties 기능에 대해서 알아보았습니다.

이 강좌는 시청자 여러분들의 시청과 후원으로 제작되었습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

개발단에 가입하여 베르의 게임 개발 유튜브를 후원해주세요!

 

베르의 게임 개발 유튜브

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다! 게임 개발에 도움이 되는 강좌들을 올리는 채널입니다! [투네이션 후원] https://toon.at/donate/637735212761460238 [유니티 어필리에이트

www.youtube.com

 

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다!

이번에는 유니티 프로젝트를 생성하고, 저장/불러오기하는 방법을 알아보겠습니다!

 

사용 엔진 버전 : 2020.3

 

타임라인

0:00 인트로

0:11 프로젝트 생성

2:09 프로젝트 저장

3:33 프로젝트 불러오기

4:25 아웃트로

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번에는 유니티 엔진을 설치한 이후에 프로젝트를 생성하고, 저장/불러오기 하는 방법에 대해서 알아보겠습니다.

프로젝트 생성

먼저 유니티 프로젝트를 생성하는 방법을 알아보겠습니다.

유니티 엔진 설치 강좌를 따라서 유니티 엔진을 설치했다면 유니티 허브를 실행합니다.

유니티 허브의 화면에서 새 프로젝트를 생성하기 위해서는 프로젝트 탭의 파란색 [새 프로젝트] 버튼을 클릭하면 됩니다.

[새 프로젝트] 버튼을 클릭하면 프로젝트 생성 단계로 넘어갈 수 있습니다.

프로젝트 생성 단계에서는 여러 가지를 결정할 수 있는데 먼저 상단의 에디터 버전을 선택하면 지금 만드는 프로젝트의 유니티 버전을 고를 수 있습니다.

여기에는 여러분이 컴퓨터에 설치해둔 모든 버전의 유니티 에디터가 표시되는데, 저는 지금 2020.3 버전만 설치해둔 상태라 이 버전만 보입니다.

유니티 에디터를 설치하면서 이야기 했듯이 보통의 경우에는 최신 버전의 LTS를 선택해주는게 가장 안정적입니다.

그 다음엔 템플릿입니다.

어떤 게임을 만들 것인지에 따라서 선택하면 되는데 가장 기본적인 템플릿은 2D와 3D입니다.

2D 게임을 만들 계획이라면 2D 템플릿을 선택하고, 3D 게임을 만들 계획이라면 3D 템플릿을 선택합니다.

보통은 템플릿 중에서 2D 템플릿과 3D 템플릿처럼 코어라고 표시된 템플릿을 선택해서 사용하면 됩니다.

코어 템플릿에는 2D와 3D 템플릿 이 외에도 VR 템플릿, AR 템플릿, 3D 모바일 템플릿, 2D 모바일 템플릿이 있습니다.

그 외의 템플릿들은 유니티의 기능을 배우거나 확인해보기 위한 샘플이나 학습 템플릿들입니다.

그 다음에는 프로젝트의 이름을 정하면 됩니다.

기본 이름은 My project로 지정되는데 같은 이름이 있다면 뒤에 넘버링이 추가됩니다.

다만 기본 이름을 사용하면 프로젝트가 많이 쌓이게 되었을 때 어떤게 어떤 프로젝트인지 찾기가 어려워지기 때문에 항상 프로젝트의 이름을 알아보기 쉽게 정하는 습관을 만들도록 합시다.

프로젝트 위치는 여러분이 찾기 쉬운 위치나 깃의 로컬 리포지토리가 될 곳을 지정해주면 됩니다.

이제 프로젝트 생성 버튼을 누르면 새로운 프로젝트가 생성됩니다.

프로젝트 저장

새로 만든 프로젝트의 생성이 완료되면 유니티 엔진 에디터가 실행됩니다.

유니티 에디터에서 작업한 것 중에 스크립트, 프리팹, 텍스처, 머티리얼 같은 에셋들은 프로젝트 뷰에서 보이고 게임의 레벨이라고 할 수 있는 씬의 내부에 배치된 오브젝트들은 씬 뷰와 하이어라키 뷰를 통해서 볼 수 있습니다.

프로젝트 뷰에서 에셋에 대한 작업은 대부분 수정 사항들이 곧바로 자동 저장되기 때문에 따로 신경쓸 필요는 거의 없습니다.

하지만 씬에서의 작업은 따로 저장하지 않고 잘못 끄면 작업 내용들이 전부 날아가버리는 문제가 발생할 수 있기 때문에 신경을 써주는 것이 좋습니다.

이렇게 씬에 오브젝트를 추가하거나 변경 사항이 생기면 하이어라키 뷰에서 씬의 이름 옆에 *모양이 표시되며 저장되지 않은 변경 사항이 있음을 알려줍니다.

앞에서도 말했다시피 저장을 제때하지 않으면 작업한 내용을 날리게 될 수 있으니 에디터를 종료하기 직전이나, 작업 내용이 만족스러워서 날아가면 안된다 싶은 생각이 드는 순간에는 항상 [Ctrl + S] 단축키를 눌러서 씬의 변경 사항을 저장해줍니다.

아니면 상단 메뉴 바에서 [File > Save] 항목을 선택해서 저장할 수도 있습니다.

추가로 에디터에서 게임이 플레이되고 있는 도중에는 씬의 변경사항을 저장할 수 없고 플레이 중에 수정한 내용은 플레이가 중단되면 바로 게임이 플레이되기 전으로 초기화 되기 때문에 씬에서 작업을 하기 전에는 게임이 플pre레이 중이 아닌지 잘 확인해야 합니다.

프로젝트 불러오기

그 다음에는 프로젝트를 다시 불러오는 방법을 배우기 위해 우선은 유니티 에디터를 종료하겠습니다.

그리고 다시 유니티 허브를 실행합니다.

프로젝트 목록의 최상단에 방금 전에 만든 프로젝트가 표시되는 것을 볼 수 있습니다.

여기서 원하는 프로젝트를 선택하면 이전에 작업하던 프로젝트를 다시 열어서 작업을 이어나갈 수 있습니다.

보통은 가장 최근에 실행한 프로젝트를 위로 오게 정렬을 하기 때문에 프로젝트를 오래동안 켜지 않으면 아래 쪽에 프로젝트가 내려가 있을 수도 있는데 그럴 때는 아래로 내려가서 프로젝트를 찾거나 검색을 이용해서 찾을 수 있습니다.

다만 가끔은 이 목록에서 프로젝트가 사라지는 경우도 있는데 그럴 때는 열기 버튼을 클릭하고 [열려는 프로젝트 선택] 대화상자에서 프로젝트를 직접 찾아서 선택해주면 됩니다.

아웃트로

이번 영상에서는 새 프로젝트 생성과 프로젝트 저장, 프로젝트를 다시 불러오는 방법에 대해서 알아보았습니다.

이 강좌는 구독자 여러분들의 시청과 후원으로 제작되었습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

인스펙터 커스텀 버튼 만들기

 

작성 기준 버전 :: 2018.3.2f1

 

유니티 엔진에서 게임을 제작할 때, 모든 작업을 일일이 수작업으로 진행하면 개발 시간이 길어진다. 특히 같은 오브젝트를 여러 개 생성하고 각각 다른 수치를 입력하는 반복적인 세팅 작업의 경우에는 꽤나 큰 시간 낭비를 초래한다.

 

여러 개의 오브젝트를 생성하는데, 그 오브젝트들에 입력되어야 하는 설정이 일정한 규칙을 가지고 있거나, 설정될 값들에 대한 테이블을 미리 가지고 있다면, 오브젝트를 일일이 생성하고 설정 값을 입력하는 것보다, 버튼을 누르면 자동으로 모든 오브젝트들을 생성하고 일정한 규칙에 따라서 설정 값을 세팅하거나 테이블에서 설정 값을 가져와서 세팅하도록 만드는 것이 많은 시간을 절약할 수 있다.

 

이런 커스텀 버튼을 만드는 데도 작업 시간이 소모되겠지만, 일일이 오브젝트를 생성하고 값을 세팅하는 작업 시간이 누적되면 커스텀 버튼을 만드는 데 드는 누적 시간을 빠르게 추월할 것이다. 그리고 이런 종류의 버튼은 만들어두면 다른 프로젝트에서도 충분히 재활용할 수 있기 때문에 인스펙터 커스텀 버튼을 만드는데 시간을 투자할 가치가 있다.

 

 

예제

 

이번 예제에서는 한 오브젝트를 기준으로 그 오브젝트의 forward 방향으로 distance 거리마다 cubeCount 개의 큐브 오브젝트를 배치하는 인스펙터 커스텀 버튼을 만드는 작업을 해볼 것이다.

 

 

위의 작업은 수작업으로 진행할 경우, cubeCount 횟수만큼 반복 작업을 해야하며, 나중에 중심 오브젝트를 추가로 배치할 계획이면 다시 그 추가배치 횟수 * cubeCount 만큼 작업 횟수가 폭발적으로 증가한다.

 

이런 큐브 생성 작업을 버튼 클릭 한 번에 자동으로 처리해주는 인스펙터 커스텀 버튼을 만들어 보자.

 

우선 CubeGenerator 클래스를 생성하고 다음과 같은 코드를 작성한다.

 

public class CubeGenerator : MonoBehaviour
{
    [SerializeField]
    private GameObject cubePrefab;
    [SerializeField]
    private float distance;
    [SerializeField]
    private int cubeCount;

    public void GenerateCubes()
    {

        if (transform.childCount != 0)
        {
            for (int i = transform.childCount - 1; i >= 0; i--)
            {
                DestroyImmediate(transform.GetChild(i).gameObject);
            }
        }


        for (int i = 0; i < cubeCount; i++)
        {
            var newCube = Instantiate(cubePrefab);
            newCube.transform.SetParent(gameObject.transform);
            newCube.transform.localPosition = new Vector3(0f, 0f, i * distance);
            newCube.transform.localRotation = Quaternion.identity;
        }
    }
}

 

코드를 모두 작성한 뒤에는 CubeGenerator 클래스를 CubeStandard 오브젝트에 컴포넌트로 추가하고 큐브 오브젝트를 프리팹화하여 Cube Prefab 프로퍼티에 추가해준다.

 

 

이 다음에는 커스텀 버튼을 추가하기 위해 CubeGenerteButton 클래스를 새로 추가한다. 인스펙터 창에 커스텀 버튼을 추가하는 기능은 유니티 에디터를 수정하는 것이기 때문에 UnityEditor 네임스페이스에 들어가는 기능을 사용해야한다. UnityEditor 네임스페이스의 기능을 사용하는 클래스는 반드시 Editor 폴더 아래에 들어가야 되기 때문에 Editor 폴더를 만들어서 그 안에 넣어준다.

 

 

그리고 아래와 같이 CubeGenerateButton의 코드를 작성한다.

 

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(CubeGenerator))]
public class CubeGenerateButton : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        CubeGenerator generator = (CubeGenerator)target;
        if (GUILayout.Button("Generate Cubes"))
        {
            generator.GenerateCubes();
        }
    }
}

 

코드를 저장하고 에디터로 돌아가면 CubeGenerator 컴포넌트 하단에 "Generate Cubes" 버튼이 생겨난 것을 확인할 수 있다.

 

 

distanse와 cubeCount 값을 수정하고 Generate Cubes 버튼을 누르면 설정된 값에 맞춰서 큐브가 생겨나는 것을 확인할 수 있다.

 

 

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

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

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 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

 

반응형

Inspector 뷰에서 공개된 enum의 값을 여러 개 선택 가능하게 하기


게임이나 프로그램을 제작할 때, 유닛이나 캐릭터, 객체의 상태를 표현하기 위한 방법 중 하나로 enum을 많이 사용한다. 정수나 문자열을 이용해서도 객체의 상태를 나타낼 수 있지만, 정수의 경우는 이 상태가 어떤 상태인지 직관적으로 알아보기 어려운 문제가 있고, 문자열의 경우에는 어떤 상태인지 알아보기 쉽지만, 정수형에 비해서 비교 연산 속도가 느리고, 비교하는 부분에서 오타가 발생할 경우 찾기 어려운 버그를 발생시킬 수도 있다.


public class Character : MonoBehaviour
{
    int state;
    // 주석이 없으면 캐릭터가 어떤 상태인지 알기 어렵다.
    public void CheckState()
    {
        switch (state)
        {
            case 0: // Jump
                break;

            case 1: // Attack
                break;

            case 2: // Move
                break;

            default:
                break;
        }
    }
}

비직관적인 정수형 상태 표현


public class Character : MonoBehaviour
{
    string state;

    // 정수형보다 비교가 느릴 수 밖에 없다.
    public void CheckState()
    {
        switch (state)
        {
            case "Jump": // Jump
                break;

            case "Attcak": // Attack 오타가 발생하면 버그가 발생하고 찾기 어려울 수 있다.
                break;

            case "Move": // Move
                break;

            default:
                break;
        }
    }
}

보기는 편하지만 느리고 오타에 의한 버그 발생 가능성이 높은 문자열 상태 표현





 

그에 비해서 enum 타입의 변수를 이용하면 정수를 사용한 것과 같은 비교 연산 속도와 문자열을 사용한 것과 같은 직관성을 가질 수 있다. 오타가 발생하면 그 즉시 신텍스 에러가 뜨는 것은 덤이다.


public enum ECharacterState
{
    Jump,
    Attack,
    Move,
}

public class Character : MonoBehaviour
{
    public ECharacterState state;
    // 알아보기 쉬우며 오타가 발생할 가능성을 차단해준다.
    public void CheckState()
    {
        switch (state)
        {
            case ECharacterState.Jump: // Jump
                break;

            case ECharacterState.Attack: // Attack
                break;

            case ECharacterState.Move: // Move
                break;

            default:
                break;
        }
    }
}


객체의 상태를 표시하는데 enum 타입을 사용하면 이렇게 여러가지 이점이 있다. 그리고 이런 enum 타입의 변수는 public이나 [SerializeField]로 설정하면 유니티 에디터의 Inspector 뷰에서 볼 수 있게 된다.



일반적인 경우라면 이것으로 충분하겠지만, 캐릭터의 상태의 경우에는 기획에 따라 다르겠지만, 여러 가지의 상태가 중첩되는 경우도 있을 수 있다. 예를 들자면, 점프하면서 공격한다는 상태도 있을 수 있고 점프하면서 이동한다는 상태도 있을 수 있다. 그 외의 경우 역시 가능하다. 중첩된 상태를 표현하기 위해서는 각 비트에 상태를 매핑해서 비트 연산을 하는 방법을 주로 사용한다. 즉, 각 상태의 값을 2의 n승으로 하여 해당 비트의 값이 1이면 그 캐릭터는 해당 상태인 것이다.


public enum ECharacterState
{
    Jump    = 0x00000001,   // 0001
    Attack  = 0x00000002,   // 0010
    Move    = 0x00000004,   // 0100
}

public class Character : MonoBehaviour
{
    public ECharacterState state;

    private void Start()
    {

        // or 연산을 통해 캐릭터의 state는 이동 중이면서 점프 중인 상태가 된다.

        state = ECharacterState.Move | ECharacterState.Jump;
    }

    public void CheckState()
    {

        // State에 Attack 상태를 and 연산하면 Attack 상태에 속하는 비트의 값만 검출할 수 있다.

        if ((state & ECharacterState.Attack) == ECharacterState.Attack)
        {
            // Attack 상태 처리
        }

        if ((state & ECharacterState.Jump) == ECharacterState.Jump)
        {
            // Jump 상태 처리
        }

        if ((state & ECharacterState.Move) == ECharacterState.Move)
        {
            // Move 상태 처리
        }
    }
}





이렇게 중첩이 가능한 상태의 경우에는 여러 개의 상태를 동시에 선택할 수 있어야 하는데 public이나 [SerializeField]로 공개된 enum 타입의 변수의 경우에 유니티 에디터에서 기본적으로는 하나의 값만을 선택할 수 있게 되어있다. 이런 기본적인 상태에서 중첩된 상태를 한 번에 선택하기 위해서는 단순한 방법으로는 중첩상태의 열거형을 일일이 만들어 주는 것이 있다.


public enum ECharacterState
{
    Jump                  = 0x00000001,   // 0001
    JumpAndAttack   = 0x00000003,   // 0011
    Attack                = 0x00000002,   // 0010
    AttackAndJump   = 0x00000006  // 0110
    Move                  = 0x00000004,   // 0100
    MoveAndJump     = 0x00000005,   // 0101
}



이렇게 중첩된 상태를 일일이 열거형에 추가해서 선택가능하게 만드는 방법이 있지만, 이것은 상태가 지금처럼 3가지 밖에 없는 간단한 상황에서만 가능한 방법일 것이다. 상태가 한 가지 한 가지 추가될 때마다 추가해야되는 중간 값이 엄청나게 많아져서 결국에는 드롭다운의 길이가 끝없이 늘어나는 것이 뻔히 예측될 것이다. 그리고 그렇게 중첩된 상태에 대한 상태가 늘어나면 어떤 상태를 넣었는지 확인하기 힘들어져서 이상하게 입력하게 될 수도 있다. 바로 위의 예시에서 보듯이 Jump And Attack과 Attack And Jump를 넣어버리게 되는 것처럼 말이다.(그리고 Attack And Jump의 값은 또 Attack And Move의 값이 입력되었다.)


이런 상황을 막기 위해서는 Inspector에서 enum 타입의 드롭다운에서 여러 개의 값을 선택 가능하게 만들어줘야 한다. 이런 방식의 예시로는 Inspector 뷰에 공개된 Light 컴포넌트의 Culling Mask 변수가 있다.


Light 컴포넌트의 Culling Mask는 빛을 받을 레이어를 골라서 선택할 수 있게 해준다.





위의 Culling Mask처럼 Inspector 뷰에서 원하는 상태를 여러 가지를 동시에 선택할 수 있다면 열거형에 끝없이 중첩된 상태를 추가할 필요는 없어질 것이다. 이러한 기능을 넣기 위해서는 에디터 기능을 약간 수정할 필요가 있다. 다음과 같이 EnumFlagsAttributeDrawer.cs와 EnumFlagsAttribute.cs 코드를 추가해보자. EnumFlagsAttributeDrawer의 경우, 에디터의 기능을 수정하는 코드기 때문에 Editor 폴더에 넣어주어야 한다.



using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(EnumFlagsAttribute))]
public class EnumFlagsAttributeDrawer : PropertyDrawer
{
    public override void OnGUI(Rect _position, SerializedProperty _property, GUIContent _label)
    {
        _property.intValue = EditorGUI.MaskField(_position, _label, _property.intValue, _property.enumNames);
    }
}

EnumFlagsAttributeDrawer.cs


using UnityEngine;

public class EnumFlagsAttribute : PropertyAttribute
{
    public EnumFlagsAttribute() { }
}

EnumFlagsAttribute.cs


public class Character : MonoBehaviour
{
    [EnumFlags]
    public ECharacterState state;
}






그리고 난 이후에 Inspector 뷰에서 여러 개의 값을 선택하고자 하는 enum 타입의 변수의 경우에 새롭게 추가해준 [EnumFlags] 어트리뷰트를 추가해주면아래의 이미지와 같이 우리가 추가한 enum 타입의 변수 역시 여러 개의 값을 선택할 수 있게 된다.



이렇게 여러 개의 값을 선택할 수 있게 사용하는 경우 Nothing은 0이고 Everything은 -1이다. 열거형에 값을 추가할 때는 각 열거형이 2의 n승이 되게 값을 정해줘야만 한다. 중간에 그 외의 값이 있으면 Inspector 뷰에서 선택한 값과 스크립트 상에서의 값이 일치하지 않는 버그가 발생할 수 있다.


public enum ECharacterState
{
    Jump    = 0x00000001,   // 0001
    Attack  = 0x00000002,   // 0010
    Move    = 0x00000004,   // 0100
}

EnumFlags를 사용해서 여러 값을 선택할 수 있게 하려면 중첩 상태를 제외하고 기본 상태만 2의 n승 값을 가지게 정의해줘야 한다.



참고 : https://answers.unity.com/questions/486694/default-editor-enum-as-flags-.html

반응형
  1. NaiveLight 2018.05.14 07:22

    좋은 글 잘 읽었습니다~
    그런데 중간에 enum으로 중복된 state를 표현하는 예에서 AttackAndJump가 아닌 AttackAndMove일 것 같네요.

    • wergia 2018.05.14 10:32 신고

      네 새벽시간에 글을 썼더니 약간 헷갈린것 같네요. ㅎㅎ

  2. Cargold 2018.05.17 16:58

    우와아아아앙!! 제가 딱 필요했던 정보네요!! 감사합니다!! ㄲㅑ핫!

    • Cargold 2020.06.16 16:51 신고

      뭔가 본 거 같은 글이다~ 싶었더니 제 덧글이 있었군요 ㅋㅋ
      2년이 지나니 가물가물해서 재검색했네요 ㅠㅠ

    • wergia 2020.06.22 23:44 신고

      ㅎㅎ 한 번 해봤던 것도 자주 해보지 않으면 까먹을 때가 있죠.

UnityEditor 네임스페이스를 사용할 때 주의할 점



유니티 엔진에는 유용한 기능이 아주 많지만, 그 모든 기능을 제작자가 필요로 하지는 않는다. 그와 마찬가지로 제작자가 필요로 하는 기능이지만 유니티 엔진에서는 제공하지 않을 수도 있다. 그럴 때에는 원하는 기능을 제작자가 직접 만들어내야 하는데, 그와 관련해서 가장 큰 도움을 주는 것들이 담겨 있는 것이 바로 UnityEditor 네임스페이스(namespace)이다. 여기에는 편리한 기능들이 상당히 많이 담겨 있지만 이 네임스페이스를 사용하기 위해서는 주의할 점들이 몇 가지 존재한다.


우선은 이 네임스페이스들의 기능들을 인게임의 기능에서는 사용하면 안된다는 것이다. UnityEditor 네임스페이스에는 찾아보면 쓸만한 기능이 몇 가지 있기 때문에 가끔 이 네임스페이스 안에 존재하는 기능들을 이용해서 인게임의 기능을 구현하려고 하는 사람들이 있다. 하지만 UnityEditor에서 제공하는 기능들은 철저하게 유니티 에디터를 사용자가 원하는 대로 커스터마이즈(Customizie)하는 것을 돕기 위해 지원되는 것으로 인게임에서 동작하는 코드에 집어넣고 게임을 빌드하려고 하면 유니티 에디터는 에러를 출력하고 빌드를 정지할 것이다.


두 번째로 주의할 점은, 이 UnityEditor 네임스페이스를 사용하기 위해서 using namespace UnityEditor; 선언을 한 스크립트는 Project 뷰에서 Editor 폴더 내에 모두 넣어두어야 한다는 것이다.



UnityEditor를 사용하는 cs파일을 Editor 폴더에 넣어주지 않는다면, 만든 에디터 기능을 사용하려고 할 때, 다음과 같은 에러 메시지를 출력하면서 기능이 작동하지 않을 것이다.


error CS0246: The type or namespace name `UnityEditor' could not be found. Are you missing a using directive or an assembly reference?


만약에 에디터로서의 기능이 아니라 게임 내에서 디버그 적인 요소로서 UnityEditor의 기능을 사용해야 한다면 그 기능을 사용하는 코드에는 다음 예시와 같이 전처리기 처리를 해주어야 한다.


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class UseUnityEditorClass : MonoBehaviour
{
    public void Function()
    {
#if UNITY_EDITOR
        // 유니티 에디터에서 Debug 용으로만 작동해야 하는 코드...
#endif
    }
}


반응형
  1. HiGaTsu Ryu 2022.03.21 18:23 신고

    감사합니다!!!!ㅠㅠ UnityEditor가 갑자기 왜 안되는지 모르겠어서 한참 삽질했네요..

+ Recent posts