커스터머 타입에 따른 비헤이비어 트리 설정

This commit is contained in:
Jeonghyeon Ha 2025-08-19 20:00:37 +09:00
parent edd2184890
commit 1c89abcb4b
19 changed files with 157 additions and 16 deletions

View File

@ -30,6 +30,8 @@
- `async`/`await`는 신중하게 사용하십시오. 대부분의 엔진 API 호출에는 Unity 메인 스레드 동기화가 필요합니다. - `async`/`await`는 신중하게 사용하십시오. 대부분의 엔진 API 호출에는 Unity 메인 스레드 동기화가 필요합니다.
- 거대한 모놀리식 구조보다 작은, 역할에 집중된 컴포넌트 구성을 선호합니다. 프로젝트의 DDD 경계를 준수하십시오. - 거대한 모놀리식 구조보다 작은, 역할에 집중된 컴포넌트 구성을 선호합니다. 프로젝트의 DDD 경계를 준수하십시오.
- null 체크와 가드 절을 추가하고, 개발 빌드에서는 명확한 메시지와 함께 빠르게 실패하도록 하십시오. - null 체크와 가드 절을 추가하고, 개발 빌드에서는 명확한 메시지와 함께 빠르게 실패하도록 하십시오.
- 코드는 간결하게 유지하십시오.
- 예외처리 및 로깅은 반드시 필요한 곳에만 적용하십시오.
## Addressables 및 리소스 ## Addressables 및 리소스
- `Addressables.LoadAssetAsync<T>`로 로드하고, 사용 후 핸들을 해제하여 누수를 방지하십시오. - `Addressables.LoadAssetAsync<T>`로 로드하고, 사용 후 핸들을 해제하여 누수를 방지하십시오.

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 610118169ab644240a59a4518e65f582
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cd5ed79d16c6e4d87bb643565305b83d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 93d283fa648ee4e53aee0a7c04ebaa56
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/Opsive/ImportStatus.asset (Stored with Git LFS)

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 07ee80a9ed00a4e418b7d5e5075667da
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 031547555da064a688454887f8eab0ce
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 18b1db2fc46ab4e9fa180d0f3a9443b5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3cb7910be3ff64fe8ba49368e324cd76
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -8,6 +8,14 @@ PrefabInstance:
serializedVersion: 3 serializedVersion: 3
m_TransformParent: {fileID: 0} m_TransformParent: {fileID: 0}
m_Modifications: m_Modifications:
- target: {fileID: 3854744934792897056, guid: ceeea618d8ee23642a0e56b3f963448c, type: 3}
propertyPath: m_Subtree
value:
objectReference: {fileID: 0}
- target: {fileID: 3854744934792897056, guid: ceeea618d8ee23642a0e56b3f963448c, type: 3}
propertyPath: m_GraphName
value: CustomerBehavior
objectReference: {fileID: 0}
- target: {fileID: 3971935000603232885, guid: ceeea618d8ee23642a0e56b3f963448c, type: 3} - target: {fileID: 3971935000603232885, guid: ceeea618d8ee23642a0e56b3f963448c, type: 3}
propertyPath: m_LocalPosition.x propertyPath: m_LocalPosition.x
value: 0 value: 0
@ -122,4 +130,3 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: b242c4f65b2734841840c89dfab1500b, type: 3} m_Script: {fileID: 11500000, guid: b242c4f65b2734841840c89dfab1500b, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_interactionType: 0

View File

@ -105,6 +105,9 @@ PrefabInstance:
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3} - targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
insertIndex: -1 insertIndex: -1
addedObject: {fileID: 8626078465432105892} addedObject: {fileID: 8626078465432105892}
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
insertIndex: -1
addedObject: {fileID: 3854744934792897056}
m_SourcePrefab: {fileID: 100100000, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3} m_SourcePrefab: {fileID: 100100000, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
--- !u!1 &7462519206451630147 stripped --- !u!1 &7462519206451630147 stripped
GameObject: GameObject:
@ -214,3 +217,33 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 8bb787bf70c7c134d9a6a049beb7f66a, type: 3} m_Script: {fileID: 11500000, guid: 8bb787bf70c7c134d9a6a049beb7f66a, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
--- !u!114 &3854744934792897056
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7462519206451630147}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cdaa3305fa954c45a80c9662aa6f425, type: 3}
m_Name:
m_EditorClassIdentifier:
m_GraphName: NPC
m_Index: 0
m_Data:
m_TaskData: []
m_EventTaskData: []
m_SharedVariableData: []
m_DisabledEventNodesData: []
m_DisabledLogicNodesData: []
m_UniqueID: -1885404201
m_LogicNodePropertiesData: []
m_EventNodePropertiesData: []
m_GroupPropertiesData: []
m_StartWhenEnabled: 1
m_PauseWhenDisabled: 0
m_UpdateMode: 0
m_EvaluationType: 0
m_MaxEvaluationCount: 1
m_Subtree: {fileID: 0}

View File

@ -1,4 +1,7 @@
using System.Threading.Tasks;
using Opsive.BehaviorDesigner.Runtime;
using UnityEngine; using UnityEngine;
using UnityEngine.AddressableAssets;
namespace DDD namespace DDD
{ {
@ -6,13 +9,44 @@ public class CustomerCharacter : RestaurantNpcCharacter, ICustomerInitializer
{ {
private CustomerData _customerData; private CustomerData _customerData;
public void Initialize(CustomerData customerData) public async void Initialize(CustomerData customerData)
{ {
_customerData = customerData; _customerData = customerData;
// TODO : 손님 생성 로직 추가 // 스킨 설정
_spineController.SetSkin(_customerData.SpineSkinKey); _spineController.SetSkin(_customerData.SpineSkinKey);
// _behaviorTree.EnableBehavior();
// CustomerType에 따른 behavior tree subtree 할당
await InitializeBehaviorTree();
}
private async Task InitializeBehaviorTree()
{
var customerData = RestaurantData.Instance.CustomerData;
if (customerData?.CustomerBehaviorData?.TryGetValue(_customerData.CustomerType, out var subtreeReference) != true)
{
Debug.LogError($"[CustomerCharacter] No behavior data found for CustomerType: {_customerData.CustomerType}");
return;
}
try
{
var subtree = await subtreeReference.LoadAssetAsync<Subtree>().Task;
if (subtree != null)
{
_behaviorTree.Subgraph = subtree;
_behaviorTree.StartBehavior();
}
else
{
Debug.LogError($"[CustomerCharacter] Failed to load subtree for CustomerType: {_customerData.CustomerType}");
}
}
catch (System.Exception e)
{
Debug.LogError($"[CustomerCharacter] Error loading subtree for CustomerType {_customerData.CustomerType}: {e.Message}");
}
} }
} }
} }

View File

@ -1,17 +1,18 @@
using Opsive.BehaviorDesigner.Runtime;
using UnityEngine; using UnityEngine;
namespace DDD namespace DDD
{ {
// [RequireComponent(typeof(BehaviorTree))] [RequireComponent(typeof(BehaviorTree))]
public class RestaurantNpcCharacter : RestaurantCharacter public class RestaurantNpcCharacter : RestaurantCharacter
{ {
// protected BehaviorTree _behaviorTree; protected BehaviorTree _behaviorTree;
protected override void Awake() protected override void Awake()
{ {
base.Awake(); base.Awake();
// _behaviorTree = GetComponent<BehaviorTree>(); _behaviorTree = GetComponent<BehaviorTree>();
} }
} }
} }

View File

@ -1,6 +1,6 @@
using UnityEngine; using UnityEngine;
using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.ResourceProviders; using UnityEngine.Rendering;
namespace DDD namespace DDD
{ {
@ -8,7 +8,9 @@ namespace DDD
public class RestaurantCustomerData : ScriptableObject public class RestaurantCustomerData : ScriptableObject
{ {
[SerializeField] private AssetReferenceGameObject _customerPrefab; [SerializeField] private AssetReferenceGameObject _customerPrefab;
public AssetReferenceGameObject CustomerPrefab => _customerPrefab; public AssetReferenceGameObject CustomerPrefab => _customerPrefab;
[SerializeField] private SerializedDictionary<CustomerType, AssetReference> _customerBehaviorData;
public SerializedDictionary<CustomerType, AssetReference> CustomerBehaviorData => _customerBehaviorData;
} }
} }

BIN
ProjectSettings/ProjectSettings.asset (Stored with Git LFS)

Binary file not shown.