Resources 

프로젝트 뷰에서 리소스 바로 가져오기

 

작성 기준 버전 :: 2019.2

 

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

 

 

유니티 엔진에 아직 숙달되지 않은 개발자들은 초반에 작업할 때, 위의 이미지와 같이 프로젝트 뷰에서 직접 인스펙터 뷰의 프로퍼티에 드래그&드롭으로 리소스를 할당해주는 방식을 사용할 것이다.

 

이렇게 드래그&드롭으로 리소스를 할당하는 방법은 매우 직관적이고 간편한 방법이지만, 지금처럼 하나의 오브젝트가 아닌 10개의 오브젝트를 세팅해야한다면 어떨까? 

 

이렇게 네 종류의 리소스를 하나의 게임 오브젝트에 끼워넣는 작업에 네 번의 드래그&드롭 작업을 했으니 10개의 게임 오브젝트에 세팅 작업을 하려면 무려 40번의 드래그&드롭 작업을 해야한다.

 

거기에 만약 작업할 게임 오브젝트의 수가 리그 오브 레전드의 챔피언 숫자처럼 100개가 넘어간다면 400번이 넘는 반복 작업을 해야할 것이다.

 

생각만 해도 아득해지고 손목이 아파오는 작업이다.

 

그리고 이렇게 프로젝트 뷰에서 인스펙터 뷰의 프로퍼티로 끌어다가 할당하는 작업은 일종의 정적인 할당에 가깝기 때문에 처음부터 끝까지 수동으로 사람의 손을 거쳐야만 해서 생각보다 많은 작업 시간을 소모하게 만든다.

 

그래서 이런 반복 작업에 대해서 프로그래머들이 말하는게 있다.

 

"10번만 반복해야해도 자동화시켜라."

 

하지만 지금처럼 손으로 끌어다 놓는 방법은 어떻게 해도 자동화가 불가능할 것이다.

 

그럼 이 문제를 해결하기 위해서 프로젝트에 포함된 애셋을 프로젝트 뷰에서 가져오는 방법을 알아야 한다.

 

 

프로젝트 뷰에 Resources라는 이름의 폴더를 만들고 아까 게임 오브젝트에 할당해줬던 애셋들을 생성한 폴더 안으로 이동시킨다.

 

void Start()

{

    prefab = Resources.Load<GameObject>("prefab");

    material = Resources.Load<Material>("material");

    texture2D = Resources.Load<Texture2D>("texture");

    textAsset = Resources.Load<TextAsset>("text");

}

 

Resources.Load 함수를 사용하면 Resources 폴더 안에 들어있는 애셋들을 스크립트에서 불러와서 사용할 수 있게 된다. 그리고 <> 괄호 안에는 게임 오브젝트는 GameObject, 머티리얼은 Material, 텍스쳐는 Texture2D, 텍스트 파일은 TextAsset과 같이 해당 애셋의 타입에 맞는 클래스 이름을 넣어주면 된다.

 

그리고 매개변수로는 Resources 폴더 아래에 있는 애셋의 경로를 넣어주면 되는데, 지금의 예시에서는 애셋들이 폴더 바로 아래에 있어서 애셋 파일의 이름만 넣어주면 된다. 예를 들어서 만약 애셋 종류별로 폴더를 나눠서 정리하기로 해서 texture 애셋을 Texture 폴더 안에 넣기로 했다면, "Texture/texture"로 경로를 적어주면 된다.

 

 

코드를 모두 작성하면 자동으로 할당되는지 테스트 해보기 위해서 이미 모든 프로퍼티가 할당되어 있는 컴포넌트를 삭제하고 새로 컴포넌트를 붙여서 프로퍼티를 비워준다.

 

그 다음 플레이 버튼을 눌러서 게임을 시작해보면 플레이가 시작되는 순간에 비어있던 프로퍼티들이 Resources 폴더 안에서 불러온 애셋들로 채워지는 것을 볼 수 있다.

 

사실 이 Resources 폴더는 유니티 엔진의 예약 폴더라는 것으로 Resources 클래스를 이용하면 유니티 프로젝트에 포함된 Resources라는 이름의 폴더에 접근할 수 있게 해주는 기능이다.

 

 

이 Resources 폴더가 어디에 있든 이렇게 A 폴더 아래에 있든 B 폴더 아래에 있든 Resources.Load 함수를 사용하면 언제든지 그 아래에 있는 애셋을 가지고 올 수 있다. 게다가 A 폴더와 B 폴더, 둘 다 Resources 폴더를 가지고 있어도 무리없이 하나의 Resources 폴더처럼 동작한다.

 
이렇게 편리하게 프로젝트 안에 있는 애셋을 불러올 수 있는 기능이지만, 한 가지 명심해야할 점이 있다. Resources 폴더에 들어있는 애셋들은 게임이 실행되면 무조건 메모리에 적재된다.
 
그렇기 때문에 게임이 과도한 메모리를 소모하는 문제를 발생시키고 싶지 않다면, 비교적으로 메모리를 적게 소모하면서 빠르고 손쉽게 가져와야하는 애셋만을 Resources 폴더에 넣어둘 것을 권장한다.

 

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

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

 

에셋스토어

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

 

반응형

C++ 코드 생성자에서 콘텐츠 브라우저의 클래스와 리소스 불러오기

 

작성 기준 버전 :: 4.21.1

 

게임을 제작하는 과정에서 객체를 초기화할 때, 프로젝트에 포함된 다른 클래스나 오브젝트, 리소스를 가져와야하는 경우가 종종 생긴다.

 

 

그런 경우 블루프린트의 이벤트 그래프에서 작업하는 경우라면 위의 이미지와 같이 콘텐츠 브라우저에 있는 리소스나 블루프린트 클래스 등을 곧바로 선택할 수 있지만, C++ 코드에서는 직접 경로를 지정해서 코드를 작성해야 한다.

 

단, C++ 코드에서 직접 경로를 지정해서 리소스나 블루프린트 클래스를 가져올 때, 주의할 점은 리소스나 블루프린트 클래스의 경로나 파일명이 자주 바뀌는 상황을 피하는 게 좋다. 경로를 지정한 이후에 경로가 바뀌지 않을 것이 확실하다면 C++ 코드로 경로를 지정해서 가져오는게 낫겠지만 자주 바뀌는 상황이라면 바뀐 리소스를 불러오는 모든 코드를 일일이 찾아서 수정하고 컴파일하는 문제가 발생한다.

 

그렇기 때문에, 경로나 리소스의 파일명이 자주 바뀔 상황이라면 위의 이미지처럼 블루프린트를 이용해서 초기화를 진행하거나, 별도의 기능을 만들어서 일일이 경로를 지정하고 바꾸는 작업을 자동화시키는 것이 좋다.

 

우선 C++ 코드에서 콘텐츠 브라우저의 리소스나 블루프린트 클래스를 가져오기 위해서는 다음의 헤더를 전처리기로 포함시켜주어야 한다.

 

#include "UObject/ConstructorHelpers.h"

 

ConstructorHelpers는 생성자에 도움을 주는 클래스로 생성자에서 콘텐츠 브라우저의 리소스나 블루프린트 클래스를 불러오는 작업을 도와주는 기능들을 가지고 있다. ConstructorHelpers는 생성자에서 사용되는 기능이기 때문에 생성자 이외의 장소에서 ConstructorHelpers를 사용하려고 시도하면 컴파일 에러가 발생하게 된다.

 

 

C++ 코드에서 블루프린트 클래스 가져오기

 

콘텐츠 브라우저 패널에 Blueprints 폴더 안에 TestBlueprintClass라는 이름의 APawn 클래스를 상속받은 블루프린트 클래스가 있다고 가정할 때, 그것을 C++ 코드에 가져오기 위해서는 다음 예시와 같이 코드를 작성하면 된다.

 

static ConstructorHelpers::FClassFinder<APawn> BPClass(TEXT("/Game/Blueprints/TestBlueprintClass"));
if (BPClass.Succeeded() && BPClass.Class != NULL)
{
    // 가져온 BPClass.Class를 통한 작업
}

 

FString 경로를 통해서 불러오는 것이니 만큼, 오타나 변경된 경로나 파일명으로 인해서, 클래스가 제대로 불러와지지 않는 경우가 발생할 수 있기 때문에, Succeeded() 함수와 Class의 NULL 체크를 통해서 성공적으로 클래스가 불러와졌는지 체크하고 사용해야 한다.

 

클래스 탐색자(Class Finder)는 성공적으로 블루프린트 클래스를 가져온 경우, Class 멤버 변수 안에 TSubclassOf<T> 타입으로 해당 클래스를 가지고 있게 된다. 이것을 이용해서 필요한 작업을 진행하면 된다.

 

 

C++ 코드에서 리소스 가져오기

 

이번에 알아볼 것은 C++ 코드에서 콘텐츠 브라우저 패널의 리소스를 가져오는 과정이다. 리소스의 종류는 여러가지가 될 수 있는데 대표적인 것으로는 스태틱 메시나 텍스처를 예로 들 수 있다.

 

아래의 예시코드는 드롭된 아이템의 메시가 아이템의 종류에 따라서 달라진다는 가정하에 만들어졌다. 콘텐츠 브라우저의 Item/StaticMesh 폴더 안에 SM_Helmet 이라는 이름을 가진 헬멧 모양의 스태틱 메시가 있을 때, FObjectFinder를 통해서 가져올 수 있다.

 

DropItemStaticMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DropItemMesh"));
RootComponent = DropItemStaticMeshComponent;

 

static ConstructorHelpers::FObjectFinder<UStaticMesh> HelmetStaticMesh(TEXT("/Game/Item/StaticMesh/SM_Helmet"));
if (HelmetStaticMesh.Succeeded() && HelmetStaticMesh.Object != nullptr)
{
    DropItemStaticMeshComponent->SetStaticMesh(HelmetStaticMesh.Object);
}

 

FObjectFinder를 통해서 가져온 오브젝트 역시 Succeeded() 함수와 Object 변수의 null 체크를 통해서 리소스가 제대로 불러와졌는지 체크를 한 뒤 사용해야 한다.

 

 

 

 

 

C++ 코드에서 C++ 클래스 가져오기

 

C++ 코드에서 블루프린트 클래스가 아닌 직접 작성한 C++ 클래스를 가져와서 사용하고 싶을 수도 있다. 예를 들어 게임 모드 클래스에서 기본 폰이나 기본 플레이어 컨트롤러를 설정하려고 할 때, C++로 작성한 폰 클래스나 플레이어 컨트롤러 클래스를 기반으로 블루프린트 클래스를 생성해서 넣어주는게 아니라 C++ 클래스를 곧바로 코드에서 넣어주고자 한다면 다음 예시 코드와 같이 작성하면 된다.

 

AYourProjectGameMode::AYourProjectGameMode()
{
    PlayerControllerClass = AYourCustomPlayerController::StaticClass();
}

 

StaticClass() 함수를 이용하면 런타임 중에 해당 클래스를 나타내는 UClass를 얻어낼 수 있다.

 

[투네이션]

 

-

 

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