스마트 오브젝트(Smart Objects) 는 레벨 내 배치되는 오브젝트로, AI 에이전트와 플레이어가 상호작용할 수 있다.
스마트 오브젝트는 상호작용에 필요한 모든 정보를 포함한다.
스마트 오브젝트는 글로벌 데이터베이스의 일부이며, 공간 파티셔닝 구조를 사용한다.
GameplayTag 및 에이전트 주변 검색 영역 같은 필터를 사용하여 런타임에서 스마트 오브젝트를 쿼리할 수 있다.
월드에 배치된 Actor가 AI Agent나 Player에게어떤 상호작용을 제공하는지어디에서 사용할 수 있는지사용 중인지사용하면 어떤 Behavior를 실행할지를 데이터로 노출하는 시스템이다.
Smart Object는 Level에 배치된 객체이며, AI Agent와 Player가 상호작용할 수 있고, 그 상호작용에 필요한 정보를 객체 안에 포함한다.
그냥 의자 Actor
= Mesh와 Collision만 있는 오브젝트
Smart Object가 붙은 의자 Actor
= AI가 앉을 수 있음
= 앉는 위치 Slot이 있음
= 사용 중이면 다른 AI가 같은 Slot을 못 씀
= 사용하면 앉기 Behavior가 실행됨
Smart Object는 단순히 Interact() 함수 하나를 호출하는 구조라기보다는,
AI나 시스템이 월드에서 사용 가능한 행동 지점을 검색하고, 예약하고, 사용하게 해주는 구조다.
구조
Runtime 구조
USmartObjectSubsystem : Smart Object를 검색, Claim, Use, Release하는 Runtime Subsystem
Smart Object 시스템의 중심은 SmartObjectSubsystem이다.
Agent는 주변에서 사용할 수 있는 Smart Object를 찾고, 사용 가능한 Slot을 Claim한 뒤, 그 Slot을 Use한다.
Agent
└─ Smart Object 검색
↓
USmartObjectSubsystem
└─ 조건에 맞는 Smart Object Result 반환
↓
Agent
└─ Slot Claim
↓
USmartObjectSubsystem
└─ Claim Handle 반환
↓
Agent
└─ Slot 위치로 이동
↓
Agent
└─ Use 호출
↓
USmartObjectSubsystem
└─ Behavior Definition 반환
Agent가 원하는 Smart Object Result를 선택하고 ClaimSmartObject를 호출하면, Subsystem은 Slot을 Claim하고, 성공하면 Claim Handle을 반환한다. Claim된 Slot은 Claim한 Agent가 해제하기 전까지 다른 Agent가 Claim할 수 없다.
Component 구조
USmartObjectComponent : Actor를 Smart Object로 등록하게 해주는 Component
UCLASS(...)
class USmartObjectComponent : public UActorComponent
Smart Object를 월드에 배치하려면 보통 Actor에 SmartObjectComponent를 붙인다.
BP_Chair
└─ SmartObjectComponent
└─ SmartObjectDefinition
USmartObjectComponent는 Smart Object Subsystem에 등록되어 있는지 확인하는 함수들을 제공한다.
Actor
└─ USmartObjectComponent
└─ Definition
Actor는 실제 월드에 있는 물체고,SmartObjectComponent는 이 Actor가 Smart Object로 쓰인다는 사실을 시스템에 알려주는 역할을 한다.
Definition 구조
USmartObjectDefinition : Smart Object의 공유 데이터 Asset
Smart Object Definition은 여러 Smart Object 인스턴스가 공유할 수 있는 DataAsset이다.SmartObjectDefinition은 런타임에서 여러 SmartObject 인스턴스가 공유할 수 있는 정보를 담는 DataAsset.
SmartObjectDefinition
├─ Slot 0
│ ├─ 위치 / 회전
│ ├─ 조건
│ └─ Behavior Definition
├─ Slot 1
│ ├─ 위치 / 회전
│ ├─ 조건
│ └─ Behavior Definition
└─ ...
예를 들어 벤치 하나에 세 명이 앉을 수 있다면, Smart Object Definition에는 Slot이 세 개 있을 수 있다.
SO_BenchSit
├─ Slot 0 : 왼쪽 앉는 위치
├─ Slot 1 : 중앙 앉는 위치
└─ Slot 2 : 오른쪽 앉는 위치
Smart Object Definition은 하나 이상의 Slot을 노출하고, 각 Slot은 부모 Anchor에 상대적인 위치와 회전, 그리고 Behavior Definition 같은 overridable property를 가질 수 있다.
Slot 구조
Slot : Smart Object를 실제로 사용하는 지점
Smart Object 하나가 여러 사용 지점을 가질 수 있기 때문에 Slot이 존재한다.
의자
└─ Slot 0 : 앉는 위치
벤치
├─ Slot 0 : 왼쪽 앉기
├─ Slot 1 : 중앙 앉기
└─ Slot 2 : 오른쪽 앉기
엄폐물
├─ Slot 0 : 왼쪽 엄폐
├─ Slot 1 : 중앙 엄폐
└─ Slot 2 : 오른쪽 엄폐
Slot은 단순 위치 정보만이 아니라, 사용 조건과 Behavior 데이터를 같이 가질 수 있다.
Slot
├─ Transform
├─ Tags / 조건
├─ User Required Tags
├─ Activity Tags
└─ Behavior Definition
Slot이 Claim되면 그 Slot은 다른 Agent가 동시에 사용할 수 없다.
즉 Slot은 Smart Object의 사용 가능 단위다.
Behavior Definition 구조
USmartObjectBehaviorDefinition : Smart Object를 사용했을 때 실행할 행동 정의
Smart Object는 사용 위치만 주는 시스템이 아니다.
Slot을 사용했을 때 어떤 행동을 실행할지 Behavior Definition으로 연결한다.
USmartObjectBehaviorDefinition은 Smart Object에 새로운 행동 프레임워크를 연결하기 위한 추상 클래스다.
SmartObject Slot
└─ Behavior Definition
└─ 실제 행동 데이터
예를 들면:
SO_Chair
└─ Slot 0
└─ GameplayBehavior_Sit
SO_Chest
└─ Slot 0
└─ GameplayBehavior_OpenChest
SO_Cover
└─ Slot 0
└─ GameplayBehavior_TakeCover
Behavior Definition은 “이 Slot을 사용하면 어떤 행동을 해야 하는가?”를 데이터로 제공한다.
Agent가 Use를 호출하면 Slot 상태가 Claimed에서 Occupied로 바뀌고, Subsystem이 Agent에게 Behavior Definition struct를 반환한다.
흐름
먼저 월드에 Smart Object로 사용할 Actor를 만든다.
BP_Chair
└─ SmartObjectComponent
Actor 자체는 그냥 의자, 상자, 문, 엄폐물, 작업대 같은 월드 오브젝트다.
여기에 SmartObjectComponent를 붙이면 Smart Object 시스템이 이 Actor를 관리할 수 있다.
Actor
└─ SmartObjectComponent
└─ SmartObjectDefinition
SmartObjectDefinition에서 이 오브젝트가 제공하는 Slot과 Behavior를 정의한다.
SO_ChairSit
├─ Slot 0
│ ├─ Transform : 앉는 위치
│ ├─ User Required Tags
│ └─ Behavior Definition : Sit
SmartObjectDefinition은 DataAsset처럼 여러 SmartObject 인스턴스가 공유할 수 있다. ([Epic Games Developers][4])
예를 들어 같은 의자 Actor가 여러 개 있어도, 동일한 SO_ChairSit Definition을 공유할 수 있다.
BP_Chair_A
└─ SmartObjectComponent
└─ SO_ChairSit
BP_Chair_B
└─ SmartObjectComponent
└─ SO_ChairSit
Agent는 SmartObjectSubsystem을 통해 주변에서 사용할 수 있는 Smart Object를 찾는다.
USmartObjectSubsystem* SmartObjectSubsystem = USmartObjectSubsystem::GetCurrent(World);
검색 조건에는 보통 위치, 반경, 태그, 사용자 조건 등이 들어간다.
Agent
└─ 주변에서 사용 가능한 Smart Object 검색
├─ 의자
├─ 엄폐물
├─ 작업대
└─ 조사 지점
Smart Object는 특히 AI가 “월드에 있는 어떤 지점을 사용할지” 고를 때 의미가 있다.
Agent는 검색 결과 중 사용할 Slot을 Claim한다.
SmartObjectSubsystem
└─ Slot 사용 가능 여부 확인
↓
Slot State = Claimed
↓
FSmartObjectClaimHandle 반환
Claim에 성공하면 Subsystem은 Claim Handle을 반환하고, Claim된 Slot은 해제되기 전까지 다른 Agent가 Claim할 수 없다.
Slot 상태
Available
→ Claimed
ClaimHandle은 이후 Use 또는 Release에 사용된다.
FSmartObjectClaimHandle
= 내가 이 Slot을 예약했다는 핸들
Claim한 뒤 바로 행동하는 것이 아니라, 보통 Agent는 Slot 위치로 이동한다.
Agent
└─ ClaimHandle로 Slot Transform 확인
↓
AI MoveTo
↓
Slot 위치 도착
예를 들어 경비병이 의자에 앉는다면:
의자 Slot Claim
→ 의자 앞 위치로 이동
→ 도착 후 Use
엄폐물이라면:
Cover Slot Claim
→ 엄폐 지점으로 이동
→ 도착 후 Use
Agent가 Slot에 도착하면 SmartObjectSubsystem에 Use를 호출한다.
SmartObjectSubsystem.Use(ClaimHandle)
Use가 호출되면 Slot 상태는 다음처럼 바뀐다.
Claimed
→ Occupied
Use 단계에서 Slot 상태가 Claimed에서 Occupied로 바뀌고, Subsystem이 Behavior Definition을 Agent에게 반환한다.
즉 Use는 단순한 함수 호출이 아니라:
이 Slot을 실제 사용 상태로 전환하고
이 Slot에서 실행할 Behavior 데이터를 가져오는 단계
다.
Use 결과로 받은 Behavior Definition을 기반으로 실제 행동을 실행한다.
Behavior Definition
├─ 애니메이션 실행
├─ Gameplay Ability 실행
├─ Gameplay Behavior 실행
├─ StateTree Task 실행
└─ 커스텀 C++ 로직 실행
예시:
의자 사용
→ Sit Behavior
→ 앉기 애니메이션 실행
상자 사용
→ OpenChest Behavior
→ 상자 열기
→ 아이템 획득
엄폐물 사용
→ TakeCover Behavior
→ 엄폐 상태 진입
Smart Object는 행동에 필요한 Slot과 Behavior 데이터를 제공한다.
사용이 끝나면 Slot을 Release한다.
Occupied
→ Available
Slot을 Release하지 않으면 해당 Slot은 계속 사용 중으로 남을 수 있다.
Agent가 의자에서 일어남
→ Slot Release
→ 다른 Agent가 다시 Claim 가능
즉 Smart Object는 “누가 쓰고 있는지”를 Slot 단위로 관리한다.
상태
Smart Object Slot은 아래와 같은 흐름으로 상태가 바뀐다.
Available
→ Claimed
→ Occupied
→ Available
Available
아무도 사용하지 않는 상태다.
다른 Agent가 검색 가능
Claim 가능
Claimed
어떤 Agent가 예약한 상태다.
Agent가 사용하겠다고 예약함
다른 Agent는 같은 Slot을 Claim할 수 없음
보통 이동 중인 상태
Occupied
실제로 사용 중인 상태다.
Agent가 Slot 위치에 도착함
Use 호출됨
Behavior 실행 중
이 구조 때문에 Smart Object는 여러 AI가 같은 오브젝트를 두고 충돌하지 않도록 관리하기 좋다.
GameplayTag와 Smart Object
Smart Object도 GameplayTag와 함께 쓰기 좋다.
Smart Object 종류
= SmartObject.Chair
= SmartObject.Cover
= SmartObject.GuardPost
Agent 조건
= Agent.Human
= Agent.Guard
= Agent.Worker
행동 조건
= Activity.Sit
= Activity.Investigate
= Activity.TakeCover
예를 들어:
경비병 Agent
└─ Agent.Guard 태그 보유
GuardPost Smart Object
└─ User Required Tags : Agent.Guard
이 경우 경비병만 해당 GuardPost Slot을 사용할 수 있다.
Smart Object는 GameplayTag를 “채널”로 쓰는 GameplayMessageRouter와는 다르게,
사용 가능 조건과 분류 체계에 사용한다.
GameplayMessageRouter의 GameplayTag
= 메시지 채널
Smart Object의 GameplayTag
= 검색 조건 / 사용자 조건 / 활동 분류 / Slot 조건
GameplayMessageRouter와 비교
GameplayMessageRouter는 이벤트를 전달하는 시스템이다.
발신자
└─ GameplayTag 채널로 Payload Broadcast
↓
수신자
└─ 같은 채널을 Listen
반면 Smart Object는 상호작용 가능한 월드 지점을 관리하는 시스템이다.
Agent
└─ 사용 가능한 Smart Object 검색
↓
SmartObjectSubsystem
└─ Slot Claim / Use / Release
↓
Behavior 실행
| 구분 | GameplayMessageRouter | Smart Object |
|---|---|---|
| 목적 | 시스템 간 메시지 전달 | 월드 상호작용 지점 관리 |
| 기준 | GameplayTag 채널 | SmartObjectDefinition / Slot / Tag |
| 데이터 | USTRUCT Payload | Slot, ClaimHandle, BehaviorDefinition |
| 주요 객체 | UGameplayMessageSubsystem | USmartObjectSubsystem |
| 사용 흐름 | Broadcast / RegisterListener | Find / Claim / Use / Release |
| 주 용도 | 이벤트 전달 | AI/Player가 오브젝트를 사용 |
| 결합도 | 발신자와 수신자 분리 | Agent와 월드 오브젝트 분리 |
| 대표 예 | 데미지 메시지, UI 알림 | 앉기, 엄폐, 조사, 작업대 사용 |
장점
AI와 월드 오브젝트의 결합도를 낮춘다.
AI가 특정 BP_Chair나 BP_CoverWall을 직접 알고 있을 필요 없이,
SmartObjectSubsystem을 통해 조건에 맞는 사용 지점을 찾으면 된다.
Slot 단위로 Claim / Use 상태를 관리하기 때문에
여러 AI가 같은 자원을 동시에 사용하는 문제도 줄일 수 있다.
Behavior Definition을 통해 행동 데이터를 분리할 수 있기 때문에,
오브젝트마다 코드로 Interact()를 직접 박는 것보다 데이터 중심으로 확장하기 좋다.
단점
단순 상호작용에는 과하다.
플레이어가 바라보고E키를 눌러 상자 하나 여는 정도라면IInteractableInterface나UInteractComponent가 더 단순하다.흐름 추적이 어려울 수 있다.
직접 함수 호출은Player → Chest.Interact()가 바로 보이지만, Smart Object는Find → Claim → Move → Use → Behavior로 나뉜다.Behavior와 Slot 설계를 같이 해야 한다.
Smart Object Definition만 만들어도 실제 행동이 나오지는 않는다. Slot을 어떻게 쓸지, Behavior를 어디서 실행할지, 사용 종료는 누가 Release할지까지 정해야 한다.AI 구조와 같이 엮일 때 복잡도가 오른다.
Behavior Tree, StateTree, Mass AI, GameplayBehavior, Ability System과 연결하면 강력하지만, 그만큼 추적해야 하는 시스템이 늘어난다.
쓰기 좋은 경우
Smart Object는 모든 상호작용을 대체하기 위한 시스템은 아니다.
잘 맞는 건 보통 이런 경우다.
- AI가 월드 오브젝트를 검색해서 사용해야 하는 경우
- 여러 AI가 같은 자원을 두고 경쟁할 수 있는 경우
- 오브젝트 하나에 여러 사용 위치가 필요한 경우
- 사용 중 / 예약 중 상태 관리가 필요한 경우
- 행동을 데이터 Asset으로 분리하고 싶은 경우
- NPC 생활 행동, 엄폐, 조사, 작업대, 경비 초소처럼 월드 행동 지점이 많은 경우
예를 들어 의자 앉기, 벤치 사용, 엄폐 지점, 경비 초소, 작업대, 소리 조사 지점 같은 건 Smart Object와 잘 맞는다.
반대로 owner가 분명한 단순 상호작용은 그냥 함수 호출이나 InteractComponent가 더 읽기 쉽다.
플레이어가 상자 보고 E 누름
→ InteractComponent가 더 단순
AI가 주변에서 빈 엄폐물을 찾아 사용함
→ Smart Object가 적합
정리
Smart Object는 “상호작용 가능한 Actor” 자체가 아니라,
월드에 배치된 오브젝트의 사용 지점과 행동 데이터를 시스템이 검색하고 점유하고 실행할 수 있게 만든 구조다.
Smart Object
= 월드 오브젝트가 제공하는 행동 지점
SmartObjectComponent
= Actor를 Smart Object로 등록하는 Component
SmartObjectDefinition
= Slot과 Behavior 데이터를 담는 공유 Asset
Slot
= 실제 사용 가능한 위치 / 예약 단위
ClaimHandle
= 이 Slot을 예약했다는 핸들
Behavior Definition
= 사용 시 실행할 행동 데이터
SmartObjectSubsystem
= Find / Claim / Use / Release를 관리하는 Runtime Subsystem'Unreal Engine' 카테고리의 다른 글
| GAS 2 (0) | 2026.06.16 |
|---|---|
| GAS 1 (0) | 2026.06.15 |
| GameplayMessageRouter Plugin 2 (1) | 2026.06.11 |
| GameplayMessageRouter Plugin 1 (0) | 2026.06.10 |
| Niagara (0) | 2026.05.20 |