이 기능은 실험단계이므로, 사용해 보면서 피드백을 제공하고 에픽에서 구상 중인 부분을 살펴볼 수 있습니다. 현재 커스텀 인벤토리 및 아이템을 사용하는 프로젝트는 퍼블리싱할 수 없습니다.
실험단계에서 생성된 에셋은 이전 버전과의 호환성이 보장되지 않는다는 점에 유의하세요. 실험단계 기능의 API는 변경될 수 있으며, 에픽게임즈의 재량에 따라 전체 실험단계 기능 또는 특정 기능이 제거될 수도 있습니다. 이 기능으로 작업을 시작하기 전에 알려진 문제 목록을 확인해 보세요.
이 튜토리얼에서는 플레이어가 커스텀 아이템을 줍고 주운 아이템을 플레이어 인벤토리에 추가할 수 있게 하는 커스텀 '아이템 픽업' 상호작용 가능 컴포넌트를 만드는 방법을 알아봅니다.
시작하기 전에
이 튜토리얼을 성공적으로 완료하기 위해서는 UEFN, 씬 그래프, Verse 코드를 익숙하게 다룰 수 있어야 합니다.
프로젝트 구성하기
다음 단계를 따라 프로젝트를 구성하고 커스텀 인벤토리 및 아이템을 활성화합니다.
UEFN을 열고 원하는 섬 템플릿에서 프로젝트를 생성합니다. 섬 템플릿에서, 평면 영역에서 작업하려면 기본(Blank) 프로젝트를 사용할 수 있습니다. 새 프로젝트를 명명하고 생성(Create)을 클릭하여 에디터에서 엽니다.
툴바에서 프로젝트(Project)를 클릭하고 프로젝트 세팅(Project Settings)을 선택합니다.
실험 단계 액세스(Experimental Access) 섹션으로 스크롤을 내리고 커스텀 아이템 및 인벤토리(Custom Items and Inventory) 체크 박스를 선택합니다.
Verse 코드 작성
interactable_component는 일반 상호작용 처리에 사용되는 씬 그래프 컴포넌트입니다. 기본적으로 플레이어는 입력 키를 눌러 해당 컴포넌트를 보유한 엔티티와 상호작용할 수 있습니다. 해당 컴포넌트를 커스터마이징하려면 다음 단계를 따릅니다.
interactable_component는 엔티티에 상호작용할 mesh_component가 있어야 합니다. 오브젝트는 무언가 엔티티와 상호작용하려는 경우에 확인할 수 있는 콜리전이 필요합니다.
커스텀 상호작용 가능 컴포넌트를 추가할 엔티티를 선택합니다. 디테일(Details) 패널에서 +컴포넌트(+Component)를 클릭하고 새 Verse 컴포넌트(New Verse Component)를 선택합니다. Verse 컴포넌트 생성(Create Verse Component) 창이 열립니다.
Verse 익스플로러로 새 Verse 파일을 추가하여 Verse 컴포넌트를 만들 수도 있습니다.
템플릿 선택(Choose a Template)에서 씬 그래프 컴포넌트(Scene Graph Component)를 선택합니다.
하단의 컴포넌트 이름(Component Name) 필드에 item_interactable_component를 입력합니다. 그런 다음 생성을 클릭합니다.
메뉴 바에서 Verse > Verse 익스플로러(Verse Explorer)를 클릭합니다. 새 Verse 컴포넌트를 찾아 우클릭한 후 Visual Studio Code에서 열기(Open in Visual Studio Code)를 선택합니다.
새 Verse 파일에서 기존 코드를 삭제합니다. 이 튜토리얼에서는 완전히 새로 작성할 것입니다. 먼저 필수 모듈을 추가합니다. 아래 스니펫에서 복사해 붙여넣을 수 있습니다.
Verseusing { /Verse.org/Simulation } using { /Verse.org/SceneGraph } using { /UnrealEngine.com/Itemization }다음으로, 지정한 플레이어로부터 루트 인벤토리를 구하는 헬퍼 함수를 추가합니다.
VerseGetInventoryRoot(Agent:agent)<decides><transacts>:inventory_component = Inventory := (for (I : Agent.FindDescendantComponents(inventory_component)) { I })[0]새 커스텀 컴포넌트를 생성하기 전에 클래스 스코프 밖에 새 메시지 타입 상수를 선언해야 합니다. 이 메시지는 함수가 아이템의
item_details_component에서 이름을 구할 수 없을 때의 기본값입니다. 일반적으로 이 메시지 타입은 Verse 파일의 최하단에 작성됩니다.VerseDefaultInteractionMessage<localizes>:message = "Interact"interactable_component로부터 상속받는 신규 씬 그래프를 정의합니다. 이것이item_interactable_component입니다.Verseitem_interactable_component := class(interactable_component) :선택 사항으로
cancelable변수를 추가합니다. 플레이어가 아이템과 상호작용하는 시점을 알기 위해서는 이 커스텀 컴포넌트가 이벤트를 구독해야 합니다. 이 변수는 해당 구독에 대한 레퍼런스를 저장하며, 필요한 경우 취소합니다.Versevar SucceededEventHandler : ?cancelable = false다음으로
OnAddedToScene함수를 오버라이드해, 해당 컴포넌트를 보유한 엔티티의 부모가 변경될 경우(예: 월드에 배치) 선택 사항 변수를 설정하도록 합니다.SucceededEvent의 구독 함수를 호출하도록SucceededEventHandler를 설정합니다. 이는 상호작용 발생 시 트리거될OnSucceededEvent함수도 정의합니다.VerseOnAddedToScene<override>():void = if(not SucceededEventHandler?): set SucceededEventHandler = option{SucceededEvent.Subscribe(OnSucceededEvent)}SucceededEvent구독은 아이템을 줍고 나면 정리해야 합니다. 그렇지 않으면 아이템이 인벤토리에 들어간 후 다른 코드를 방해할 수 있습니다. 정리는OnRemovingFromScene함수를 오버라이드하면 됩니다. 해당 함수는 아이템 엔티티 부모가 변경되면 활성화됩니다. 여기에 사용하면 이벤트 구독을cancel()합니다. 성공하면SucceededEventHandler도 무효화됩니다.VerseOnRemovingFromScene<override>():void = if(SucceededEventHandler?.Cancel()): set SucceededEventHandler = false10단계에서
OnSucceededEvent함수가SucceededEvent를 구독했지만, 아직 코드에는 존재하지 않습니다. 그러므로 동일한 시그니처로 새로운 함수를 작성해야 합니다. 6단계에서는 헬퍼 함수GetInventoryRoot[]를 사용해 상호작용하는 플레이어로부터 루트 인벤토리를 얻었습니다. 이제AddItemDistribute()함수를 호출하여 이 컴포넌트를 보유한 엔티티를 제공합니다.VerseOnSucceededEvent(Agent:agent):void = if(PickupInventory := GetInventoryRoot[Agent]): if(PickupInventory.AddItemDistribute(Entity).GetSuccess[]):이 컴포넌트에 필요한 코드의 마지막 부분은
InteractMessage[]함수의 오버라이드입니다. 이 함수는 플레이어가 아이템을 줍기 전 아이템을 보고 있을 때 화면에 표시되는 메시지를 반환합니다. 또한, 해당 컴포넌트를 보유한 엔티티가item_details_component를 가지고 있는지 확인합니다. 가지고 있다면 아이템의 이름을 가져옵니다. 또는, 어떤 이유로 엔티티에item_details_component가 없거나 제거되었다면 앞서 선언한DefaultInteractionMessage를 사용합니다.VerseInteractMessage<override>(Agent:agent)<reads><decides>:message = if(Details := Entity.GetComponent[item_details_component]): Details.Name else: DefaultInteractionMessage
프리팹 구성하기
이제 item_interactable_component를 작성했으니, 이를 시연할 예시 아이템을 만들 수 있습니다. 씬 그래프 프리팹을 생성해 새 컴포넌트를 어태치하려면 다음 단계를 따릅니다.
콘텐츠 브라우저(Content Browser)를 우클릭하고, 컨텍스트 메뉴에서 엔티티 프리팹 정의(Entity Prefab Definition)를 선택합니다. 새 프리팹의 이름을 Item_Cube로 지정합니다.
새로운 프리팹을 열고, 디테일 패널에서 +컴포넌트를 클릭해 다음 컴포넌트를 추가합니다.
item_componentitem_details_component- 이 컴포넌트의 필드를 작성합니다.이름(Name)
설명(Description)
짧은 설명(Short Description)
mesh_component- 큐브 프리미티브 또는 다른 큐브를 선택합니다.item_interactable_component
아래 동영상은 item_interactable_component 실제 사용 사례를 보여 줍니다. 플레이어가 생성한 Item_Cube 프리팹과 상호작용하면 플레이어 인벤토리에 아이템이 추가됩니다.
다음은 이 튜토리얼의 전체 스크립트입니다.
using { /Verse.org/Simulation }
using { /Verse.org/SceneGraph }
using { /UnrealEngine.com/Itemization }
# This function returns the first subentity with an inventory_component. Use this to get the root inventory of an agent.
GetInventoryRoot(Agent:agent)<decides><transacts>:inventory_component =
Inventory := (for (I : Agent.FindDescendantComponents(inventory_component)) { I })[0]