PART 6 - 강의 1/3

Smart Object 개요와 설정

UE5 Smart Object 시스템의 구조, SmartObjectDefinition, Slot 설정을 학습합니다

01

Smart Object 시스템 개요

환경 상호작용의 데이터 중심 프레임워크

Smart Object는 UE5.0부터 도입된 시스템으로, AI와 환경 오브젝트 간의 상호작용을 데이터 기반으로 정의합니다. 의자에 앉기, 레버 당기기, 아이템 줍기 등의 행동을 체계적으로 관리합니다.

Smart Object 구성요소
SmartObjectDefinition (에셋) SmartObjectComponent (액터) Slot (상호작용 지점) SmartObjectSubsystem (관리)
C++// Smart Object 플러그인 활성화 // Edit → Plugins → Smart Objects 활성화 // Build.cs에 모듈 추가: // "SmartObjectsModule" // Smart Object 핵심 클래스 // USmartObjectDefinition - 상호작용 정의 (DataAsset) // ├── Slots: 상호작용 지점 배열 // │ ├── ActivityTags: 활동 태그 // │ ├── BehaviorDefinition: 실행할 행동 // │ └── UserTagFilter: 사용자 필터 // └── DefaultBehaviorDefinitions: 기본 행동 // USmartObjectComponent - 액터에 부착 // ├── RegisteredDefinition: 정의 에셋 참조 // └── 월드 위치/회전 제공 // USmartObjectSubsystem - 월드 서브시스템 // ├── 모든 Smart Object 관리 // ├── 검색/Claim/Use API // └── 런타임 라이프사이클 관리 // Smart Object 활성화 조건 // Project Settings → Game → Smart Objects // DefaultSmartObjectCollectionClass: 자동 설정됨
구조

Smart Object 시스템은 "정의(Definition) - 인스턴스(Component) - 관리(Subsystem)"의 3계층 구조입니다. 정의는 에셋으로 재사용하고, 컴포넌트로 월드에 배치하며, 서브시스템이 전체를 관리합니다.

02

SmartObjectDefinition 에셋

상호작용 정의 데이터 에셋 구성

USmartObjectDefinition은 Smart Object의 설계도입니다. 하나의 Definition에 여러 Slot을 정의하여, 벤치(2인석), 식탁(4인석) 등 다중 사용자 오브젝트를 구현합니다.

C++// SmartObjectDefinition 에셋 생성 // Content Browser → Add → Smart Object → Smart Object Definition // Slot 설정 // USmartObjectSlotDefinition struct FSmartObjectSlotDefinition { // Slot ID (자동 생성) FSmartObjectSlotDefinitionID ID; // 상대 위치/회전 (오브젝트 기준) FTransform Offset; // Activity Tags - Slot이 제공하는 활동 FGameplayTagContainer ActivityTags; // 예: "Activity.Sit", "Activity.Eat" // User Tag Filter - 사용 가능한 사용자 조건 FSmartObjectUserTagFilter UserTagFilter; // 예: "NPC.Civilian"만 사용 가능 // Behavior Definition - 실행할 행동 TArray<USmartObjectBehaviorDefinition*> BehaviorDefinitions; // AI용: USmartObjectGameplayBehaviorDefinition // BT용: 특정 BT Task와 연동 }; // 예시: 벤치 Definition // SmartObjectDefinition: SO_Bench // Slot 0: (Offset: 좌측) Activity: "Sit" // Slot 1: (Offset: 우측) Activity: "Sit" // DefaultBehavior: GameplayBehavior_Sit // 예시: 작업대 Definition // SmartObjectDefinition: SO_Workbench // Slot 0: (Offset: 전방) Activity: "Craft" // UserFilter: "NPC.Craftsman" // Slot 1: (Offset: 측면) Activity: "Watch" // UserFilter: 없음 (누구나) // C++에서 Definition 접근 USmartObjectDefinition* Definition = LoadObject<USmartObjectDefinition>( nullptr, TEXT("/Game/AI/SmartObjects/SO_Bench")); const TArray<FSmartObjectSlotDefinition>& Slots = Definition->GetSlots(); for (const FSmartObjectSlotDefinition& Slot : Slots) { UE_LOG(LogAI, Log, TEXT("Slot Tags: %s"), *Slot.ActivityTags.ToString()); }

Slot의 Offset은 Smart Object Component의 Transform 기준 상대 좌표입니다. 에디터에서 미리보기로 Slot 위치를 시각적으로 확인하며 조정할 수 있습니다.

03

SmartObjectComponent 설정

액터에 Smart Object 기능 부여

USmartObjectComponent를 액터에 추가하고 Definition 에셋을 연결하면, 해당 액터가 Smart Object로 동작합니다. 컴포넌트는 자동으로 SmartObjectSubsystem에 등록됩니다.

C++// C++에서 SmartObjectComponent 추가 UCLASS() class ABenchActor : public AActor { GENERATED_BODY() public: ABenchActor() { // Static Mesh (시각적 벤치) MeshComp = CreateDefaultSubobject<UStaticMeshComponent>( TEXT("BenchMesh")); RootComponent = MeshComp; // Smart Object Component SmartObjectComp = CreateDefaultSubobject <USmartObjectComponent>(TEXT("SmartObject")); } protected: UPROPERTY(VisibleAnywhere) UStaticMeshComponent* MeshComp; UPROPERTY(VisibleAnywhere) USmartObjectComponent* SmartObjectComp; // Details에서 DefinitionAsset 설정 }; // 블루프린트에서 설정 // 1. 액터에 SmartObjectComponent 추가 // 2. Details → SmartObjectDefinition 설정 // 3. 레벨에 배치 → 자동 등록 // 런타임 활성화/비활성화 SmartObjectComp->SetSmartObjectEnabled(true); // 활성화 SmartObjectComp->SetSmartObjectEnabled(false); // 비활성화 // 비활성화 시 Claimed/Used 상태의 Slot은 해제됨 // SmartObject Collection // SmartObjectCollection 액터가 레벨에 자동 생성 // 해당 레벨의 모든 Smart Object를 수집 // 스트리밍 레벨 지원 - 레벨 로드/언로드 시 자동 관리 // SmartObject 태그로 필터링 // 컴포넌트에 GameplayTag를 추가하여 // 검색 시 특정 유형의 SmartObject만 찾을 수 있음 SmartObjectComp->GetMutableTags().AddTag( FGameplayTag::RequestGameplayTag( FName("SmartObject.Indoor")));
주의

SmartObjectComponent를 비활성화하면 현재 사용 중인 Slot도 강제 해제됩니다. AI가 앉아있는 벤치를 비활성화하면 갑자기 일어나므로, 사용 상태를 확인 후 비활성화하세요.

04

Gameplay Tags와 Smart Object

태그 기반 검색과 필터링

Smart Object는 Gameplay Tags를 핵심 필터링 메커니즘으로 사용합니다. Activity Tags, User Tags, Object Tags의 조합으로 적절한 Smart Object와 Slot을 매칭합니다.

C++// Tag 기반 검색 구조 // 1. ActivityTags: Slot이 제공하는 활동 // "Activity.Sit", "Activity.Eat", "Activity.Sleep" // AI가 "앉을 곳"을 찾을 때 "Activity.Sit" 태그로 검색 // 2. UserTagFilter: Slot 사용 조건 // Slot에 설정: "NPC.Guard" 필요 // → Guard 태그가 없는 NPC는 이 Slot 사용 불가 // 3. Object Tags: SmartObject 자체의 분류 // "SmartObject.Indoor", "SmartObject.Tavern" // → 실내 오브젝트만 검색, 주점 오브젝트만 검색 // Smart Object 검색 요청 FSmartObjectRequestFilter Filter; // Activity 필터: "앉기" 활동을 제공하는 Slot Filter.ActivityRequirements.RequiredTags.AddTag( FGameplayTag::RequestGameplayTag( FName("Activity.Sit"))); // User 태그 설정 (AI의 자격) FSmartObjectActorUserData UserData; UserData.UserTags.AddTag( FGameplayTag::RequestGameplayTag( FName("NPC.Civilian"))); // 검색 실행 USmartObjectSubsystem* SOSubsystem = USmartObjectSubsystem::GetCurrent(GetWorld()); FSmartObjectRequest Request( AIController->GetPawn()->GetActorLocation(), Filter); Request.SetSearchRadius(2000.f); TArray<FSmartObjectRequestResult> Results; SOSubsystem->FindSmartObjects(Request, Results); for (const FSmartObjectRequestResult& Result : Results) { UE_LOG(LogAI, Log, TEXT("Found SO: %s"), *Result.SmartObjectHandle.ToString()); }
설계

Gameplay Tags를 계층적으로 설계하세요. "Activity.Social.Sit", "Activity.Social.Talk", "Activity.Work.Craft" 처럼 구조화하면, "Activity.Social" 태그로 모든 사교 활동을 한 번에 검색할 수 있습니다.

SUMMARY

핵심 요약

  • Smart Object는 Definition(에셋) - Component(액터) - Subsystem(관리)의 3계층 구조이다
  • SmartObjectDefinition에 여러 Slot을 정의하여 다중 사용자 오브젝트를 구현한다
  • SmartObjectComponent를 액터에 추가하면 자동으로 SmartObjectSubsystem에 등록된다
  • Gameplay Tags(Activity/User/Object)로 적절한 Smart Object와 Slot을 매칭한다
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: Smart Object 배치

USmartObjectDefinition을 만들고 SmartObjectComponent를 Actor에 부착하세요. 슬롯을 3개 설정하고, 각 슬롯에 다른 Activity Tag를 할당하여 AI가 해당 슬롯을 사용하는지 확인합니다.

실습 2: Smart Object 검색

USmartObjectSubsystem의 FindSmartObjects()로 주변 Smart Object를 검색하세요. FSmartObjectRequestFilter로 특정 태그의 슬롯만 필터링하고, 결과를 Blackboard에 저장합니다.

심화 과제

벤치(앉기 2슬롯 + 서서 대화 1슬롯) 같은 복합 Smart Object를 설계하세요. 슬롯별 접근 방향(Direction)과 사전 조건(UserTagFilter)을 설정하고, 여러 AI가 동시에 사용하는 시나리오를 테스트합니다.