손님 비헤이비어 트리 초안 작성
This commit is contained in:
parent
5efc97f64d
commit
8f56d99bf7
@ -136,7 +136,7 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
_interactionType: 1
|
_interactionType: 1
|
||||||
_executionParameters:
|
_executionParameters:
|
||||||
_holdTime: 1
|
_holdTime: 0.1
|
||||||
_displayParameters:
|
_displayParameters:
|
||||||
_messageKey:
|
_messageKey:
|
||||||
_interactionAvailableFlows: 1
|
_interactionAvailableFlows: 1
|
||||||
|
BIN
Assets/_DDD/_Addressables/AI/Customer/Subtree/CustomerDefault.asset
(Stored with Git LFS)
BIN
Assets/_DDD/_Addressables/AI/Customer/Subtree/CustomerDefault.asset
(Stored with Git LFS)
Binary file not shown.
@ -120,11 +120,12 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
_interactionType: 1
|
_interactionType: 1
|
||||||
_executionParameters:
|
_executionParameters:
|
||||||
_holdTime: 1
|
_holdTime: 0
|
||||||
_displayParameters:
|
_displayParameters:
|
||||||
_messageKey:
|
_messageKey:
|
||||||
_interactionAvailableFlows: 1
|
_interactionAvailableFlows: 1
|
||||||
_aiInteractionPoints: []
|
_aiInteractionPoints: []
|
||||||
|
autoInitialize: 1
|
||||||
--- !u!114 &4545680930728379745
|
--- !u!114 &4545680930728379745
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -377,3 +378,4 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 1235f6bde9304d8f85079f2777bd4b3c, type: 3}
|
m_Script: {fileID: 11500000, guid: 1235f6bde9304d8f85079f2777bd4b3c, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
|
_managementType: 0
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -234,10 +234,18 @@ MonoBehaviour:
|
|||||||
m_Data:
|
m_Data:
|
||||||
m_TaskData: []
|
m_TaskData: []
|
||||||
m_EventTaskData: []
|
m_EventTaskData: []
|
||||||
m_SharedVariableData: []
|
m_SharedVariableData:
|
||||||
|
- m_ObjectType: 'Opsive.GraphDesigner.Runtime.Variables.SharedVariable`1[[UnityEngine.GameObject,
|
||||||
|
UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'
|
||||||
|
m_ValueHashes:
|
||||||
|
m_LongValueHashes: 0d00eb254f8d1b29baa620a07799d549a996976a4a64278927dafeacd28e0b00
|
||||||
|
m_ValuePositions: 000000000e0000000e0000000f000000
|
||||||
|
m_Values: 53656c6647616d654f626a65637402ffffffff
|
||||||
|
m_UnityObjects: []
|
||||||
|
m_Version: 3.4
|
||||||
m_DisabledEventNodesData: []
|
m_DisabledEventNodesData: []
|
||||||
m_DisabledLogicNodesData: []
|
m_DisabledLogicNodesData: []
|
||||||
m_UniqueID: -1885404201
|
m_UniqueID: 1495981264
|
||||||
m_LogicNodePropertiesData: []
|
m_LogicNodePropertiesData: []
|
||||||
m_EventNodePropertiesData: []
|
m_EventNodePropertiesData: []
|
||||||
m_GroupPropertiesData: []
|
m_GroupPropertiesData: []
|
||||||
|
@ -366,6 +366,9 @@ PrefabInstance:
|
|||||||
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 8993310060139522557}
|
addedObject: {fileID: 8993310060139522557}
|
||||||
|
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
||||||
|
insertIndex: -1
|
||||||
|
addedObject: {fileID: -6848683434426724985}
|
||||||
- targetCorrespondingSourceObject: {fileID: 6791841979869644848, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
- targetCorrespondingSourceObject: {fileID: 6791841979869644848, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
||||||
insertIndex: -1
|
insertIndex: -1
|
||||||
addedObject: {fileID: 662634663174340165}
|
addedObject: {fileID: 662634663174340165}
|
||||||
@ -461,6 +464,36 @@ MonoBehaviour:
|
|||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
blockOutlineAndGlow: 1
|
blockOutlineAndGlow: 1
|
||||||
blockOverlay: 1
|
blockOverlay: 1
|
||||||
|
--- !u!114 &-6848683434426724985
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 7316134055819320434}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 0cdaa3305fa954c45a80c9662aa6f425, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_GraphName: Behavior Tree
|
||||||
|
m_Index: 0
|
||||||
|
m_Data:
|
||||||
|
m_TaskData: []
|
||||||
|
m_EventTaskData: []
|
||||||
|
m_SharedVariableData: []
|
||||||
|
m_DisabledEventNodesData: []
|
||||||
|
m_DisabledLogicNodesData: []
|
||||||
|
m_UniqueID: 732308450
|
||||||
|
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}
|
||||||
--- !u!4 &7511707580127947132 stripped
|
--- !u!4 &7511707580127947132 stripped
|
||||||
Transform:
|
Transform:
|
||||||
m_CorrespondingSourceObject: {fileID: 4993183601549197863, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
m_CorrespondingSourceObject: {fileID: 4993183601549197863, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
||||||
|
BIN
Assets/_DDD/_Scripts/GenerateGoogleSheet/AutoCreated/So/EnvironmentDataSo.asset
(Stored with Git LFS)
BIN
Assets/_DDD/_Scripts/GenerateGoogleSheet/AutoCreated/So/EnvironmentDataSo.asset
(Stored with Git LFS)
Binary file not shown.
3
Assets/_DDD/_Scripts/RestaurantCharacter/AI.meta
Normal file
3
Assets/_DDD/_Scripts/RestaurantCharacter/AI.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1fed3b9fae5245cdbf255f627a82a1e6
|
||||||
|
timeCreated: 1755747969
|
@ -0,0 +1,57 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Opsive.BehaviorDesigner.Runtime;
|
||||||
|
using Unity.Entities;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
|
||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
[RequireComponent(typeof(BehaviorTree))]
|
||||||
|
[RequireComponent(typeof(RestaurantCustomerBlackboardComponent))]
|
||||||
|
public class RestaurantCustomerAiComponent : MonoBehaviour, IRestaurantCustomerAi
|
||||||
|
{
|
||||||
|
protected BehaviorTree _behaviorTree;
|
||||||
|
protected RestaurantCustomerBlackboardComponent _blackboardComponent;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
_behaviorTree = GetComponent<BehaviorTree>();
|
||||||
|
_blackboardComponent = GetComponent<RestaurantCustomerBlackboardComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitializeAi(CustomerData inCustomerData)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
InitializeAiInternal(inCustomerData);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// Log
|
||||||
|
Debug.LogError(e);
|
||||||
|
throw; // TODO 예외 처리
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task InitializeAiInternal(CustomerData inCustomerData)
|
||||||
|
{
|
||||||
|
var customerState = RestaurantState.Instance.CustomerState;
|
||||||
|
var subtree = customerState.GetLoadedSubtree(inCustomerData.CustomerType);
|
||||||
|
|
||||||
|
if (subtree == null)
|
||||||
|
{
|
||||||
|
Debug.LogError(
|
||||||
|
$"[CustomerCharacter] No preloaded subtree found for CustomerType: {inCustomerData.CustomerType}. Make sure CustomerBehaviorData is loaded.");
|
||||||
|
subtree = await customerState.GetOrLoadSubtree(inCustomerData.CustomerType);
|
||||||
|
}
|
||||||
|
|
||||||
|
_behaviorTree.Subgraph = subtree;
|
||||||
|
_blackboardComponent.InitializeWithBehaviorTree(subtree);
|
||||||
|
_blackboardComponent.SetCustomerData(inCustomerData);
|
||||||
|
// TODO : 1. Subtree - Action, Condition
|
||||||
|
// TODO : 2. Blackboard
|
||||||
|
_behaviorTree.StartBehavior();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: af69e82818254bfa9cabb2dbf9430850
|
||||||
|
timeCreated: 1755748000
|
@ -0,0 +1,21 @@
|
|||||||
|
using Opsive.BehaviorDesigner.Runtime;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
public class RestaurantCustomerBlackboardComponent : MonoBehaviour, IRestaurantCustomerBlackboard
|
||||||
|
{
|
||||||
|
private Subtree _subtree;
|
||||||
|
|
||||||
|
public void InitializeWithBehaviorTree(Subtree subtree)
|
||||||
|
{
|
||||||
|
_subtree = subtree;
|
||||||
|
_subtree.SetVariableValue(nameof(RestaurantCustomerBlackboardKey.SelfGameObject), gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCustomerData(CustomerData inCustomerData)
|
||||||
|
{
|
||||||
|
_subtree.SetVariableValue(nameof(RestaurantCustomerBlackboardKey.CustomerData), inCustomerData);;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 784c770c13244dc0a0804056065eaf92
|
||||||
|
timeCreated: 1755748886
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
public interface IRestaurantCustomerAi
|
||||||
|
{
|
||||||
|
void InitializeAi(CustomerData inCustomerData);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 308488f2a02448d3853514eff04711fa
|
||||||
|
timeCreated: 1755748296
|
@ -0,0 +1,13 @@
|
|||||||
|
namespace DDD
|
||||||
|
{
|
||||||
|
public enum RestaurantCustomerBlackboardKey
|
||||||
|
{
|
||||||
|
SelfGameObject,
|
||||||
|
CustomerData,
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IRestaurantCustomerBlackboard
|
||||||
|
{
|
||||||
|
void SetCustomerData(CustomerData inCustomerData);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a4f20d91da7045e4bc226be60254ef2b
|
||||||
|
timeCreated: 1755748894
|
@ -5,48 +5,25 @@
|
|||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
|
[RequireComponent(typeof(RestaurantCustomerAiComponent))]
|
||||||
public class CustomerCharacter : RestaurantNpcCharacter, ICustomerInitializer
|
public class CustomerCharacter : RestaurantNpcCharacter, ICustomerInitializer
|
||||||
{
|
{
|
||||||
private CustomerData _customerData;
|
private CustomerData _customerData;
|
||||||
|
protected IRestaurantCustomerAi restaurantCustomerAi;
|
||||||
public async void Initialize(CustomerData customerData)
|
|
||||||
|
protected override void Awake()
|
||||||
|
{
|
||||||
|
base.Awake();
|
||||||
|
restaurantCustomerAi = GetComponent<IRestaurantCustomerAi>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(CustomerData customerData)
|
||||||
{
|
{
|
||||||
_customerData = customerData;
|
_customerData = customerData;
|
||||||
|
restaurantCustomerAi.InitializeAi(_customerData);
|
||||||
|
|
||||||
// 스킨 설정
|
// 스킨 설정
|
||||||
_spineController.SetSkin(_customerData.SpineSkinKey);
|
_spineController.SetSkin(_customerData.SpineSkinKey);
|
||||||
|
|
||||||
// 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}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,16 +3,12 @@
|
|||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
[RequireComponent(typeof(BehaviorTree))]
|
[RequireComponent(typeof(RestaurantNpcMovement))]
|
||||||
public class RestaurantNpcCharacter : RestaurantCharacter
|
public class RestaurantNpcCharacter : RestaurantCharacter
|
||||||
{
|
{
|
||||||
protected BehaviorTree _behaviorTree;
|
|
||||||
|
|
||||||
protected override void Awake()
|
protected override void Awake()
|
||||||
{
|
{
|
||||||
base.Awake();
|
base.Awake();
|
||||||
|
|
||||||
_behaviorTree = GetComponent<BehaviorTree>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,8 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
|
[RequireComponent(typeof(RestaurantPlayerMovement))]
|
||||||
public class RestaurantPlayerCharacter : RestaurantCharacter
|
public class RestaurantPlayerCharacter : RestaurantCharacter
|
||||||
{
|
{
|
||||||
protected override async void Awake()
|
protected override async void Awake()
|
||||||
|
@ -27,6 +27,9 @@ public override Task InitializeController()
|
|||||||
{
|
{
|
||||||
_restaurantCustomerStateSo = RestaurantState.Instance.CustomerState;
|
_restaurantCustomerStateSo = RestaurantState.Instance.CustomerState;
|
||||||
_restaurantRunStateSo = RestaurantState.Instance.RunState;
|
_restaurantRunStateSo = RestaurantState.Instance.RunState;
|
||||||
|
|
||||||
|
_iCustomerFactory ??= new CustomerFactory();
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +44,9 @@ public override async Task OnReadyNewFlow(GameFlowState newFlowState)
|
|||||||
{
|
{
|
||||||
if (newFlowState == GameFlowState.RunRestaurant)
|
if (newFlowState == GameFlowState.RunRestaurant)
|
||||||
{
|
{
|
||||||
|
_iCustomerFactory.LoadAssets();
|
||||||
|
await _restaurantCustomerStateSo.LoadCustomerBehaviorData();
|
||||||
|
|
||||||
_cts?.Cancel();
|
_cts?.Cancel();
|
||||||
_cts?.Dispose();
|
_cts?.Dispose();
|
||||||
_cts = new CancellationTokenSource();
|
_cts = new CancellationTokenSource();
|
||||||
@ -52,6 +58,9 @@ public override Task OnExitCurrentFlow(GameFlowState exitingFlowState)
|
|||||||
{
|
{
|
||||||
if (exitingFlowState == GameFlowState.RunRestaurant)
|
if (exitingFlowState == GameFlowState.RunRestaurant)
|
||||||
{
|
{
|
||||||
|
_iCustomerFactory.UnloadAssets();
|
||||||
|
_restaurantCustomerStateSo.UnloadCustomerBehaviorData();
|
||||||
|
|
||||||
_cts?.Cancel();
|
_cts?.Cancel();
|
||||||
_cts?.Dispose();
|
_cts?.Dispose();
|
||||||
_cts = null;
|
_cts = null;
|
||||||
@ -61,8 +70,6 @@ public override Task OnExitCurrentFlow(GameFlowState exitingFlowState)
|
|||||||
|
|
||||||
private async Task StartSpawnLoopAsync(CancellationToken token)
|
private async Task StartSpawnLoopAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
_iCustomerFactory ??= new CustomerFactory();
|
|
||||||
|
|
||||||
var currentGameLevel = GameState.Instance.LevelState.Level;
|
var currentGameLevel = GameState.Instance.LevelState.Level;
|
||||||
_levelDataSo ??= DataManager.Instance.GetDataSo<LevelDataSo>();
|
_levelDataSo ??= DataManager.Instance.GetDataSo<LevelDataSo>();
|
||||||
_customerDataSo ??= DataManager.Instance.GetDataSo<CustomerDataSo>();
|
_customerDataSo ??= DataManager.Instance.GetDataSo<CustomerDataSo>();
|
||||||
@ -115,7 +122,7 @@ SpawnSchedule MakeSchedule() => scheduleBuilder.Build(new SpawnScheduleBuildArgs
|
|||||||
{
|
{
|
||||||
var rotation = Quaternion.identity;
|
var rotation = Quaternion.identity;
|
||||||
|
|
||||||
_ = _iCustomerFactory.CreateAsync(new CustomerSpawnArgs
|
await _iCustomerFactory.CreateAsync(new CustomerSpawnArgs
|
||||||
{
|
{
|
||||||
CustomerData = customerData,
|
CustomerData = customerData,
|
||||||
Position = _restaurantRunStateSo.SpawnPoint,
|
Position = _restaurantRunStateSo.SpawnPoint,
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public interface ICustomerFactory
|
public interface ICustomerFactory
|
||||||
{
|
{
|
||||||
Task<GameObject> CreateAsync(CustomerSpawnArgs args);
|
Task<GameObject> CreateAsync(CustomerSpawnArgs args);
|
||||||
|
void LoadAssets();
|
||||||
|
void UnloadAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ICustomerInitializer
|
public interface ICustomerInitializer
|
||||||
@ -24,26 +28,14 @@ public struct CustomerSpawnArgs
|
|||||||
public class CustomerFactory : ICustomerFactory
|
public class CustomerFactory : ICustomerFactory
|
||||||
{
|
{
|
||||||
private GameObject _customerPrefab;
|
private GameObject _customerPrefab;
|
||||||
|
private AsyncOperationHandle<GameObject> _customerPrefabHandle;
|
||||||
|
|
||||||
public async Task<GameObject> CreateAsync(CustomerSpawnArgs args)
|
public async Task<GameObject> CreateAsync(CustomerSpawnArgs args)
|
||||||
{
|
{
|
||||||
if (!_customerPrefab)
|
if (!_customerPrefab)
|
||||||
{
|
{
|
||||||
var customerDataAsset = RestaurantData.Instance ? RestaurantData.Instance.CustomerData : null;
|
Debug.LogError("[CustomerFactory] Customer prefab is not loaded. Call LoadAssets() first.");
|
||||||
if (customerDataAsset == null || customerDataAsset.CustomerPrefab == null)
|
await LoadCustomerAsset();
|
||||||
{
|
|
||||||
Debug.LogError("[CustomerFactory] RestaurantCustomerData or its CustomerPrefab reference is not set or not loaded.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var handle = customerDataAsset.CustomerPrefab.LoadAssetAsync<GameObject>();
|
|
||||||
await handle.Task;
|
|
||||||
if (handle.Result == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("[CustomerFactory] Failed to load customer prefab from AssetReference.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
_customerPrefab = handle.Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var newCustomer = Object.Instantiate(_customerPrefab, args.Position, args.Rotation, args.Parent);
|
var newCustomer = Object.Instantiate(_customerPrefab, args.Position, args.Rotation, args.Parent);
|
||||||
@ -54,5 +46,47 @@ public async Task<GameObject> CreateAsync(CustomerSpawnArgs args)
|
|||||||
}
|
}
|
||||||
return newCustomer;
|
return newCustomer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void LoadAssets()
|
||||||
|
{
|
||||||
|
await LoadCustomerAsset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadCustomerAsset()
|
||||||
|
{
|
||||||
|
if (_customerPrefab != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var customerDataAsset = RestaurantData.Instance ? RestaurantData.Instance.CustomerData : null;
|
||||||
|
if (customerDataAsset == null || customerDataAsset.CustomerPrefab == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[CustomerFactory] RestaurantCustomerData or its CustomerPrefab reference is not set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_customerPrefabHandle = customerDataAsset.CustomerPrefab.LoadAssetAsync<GameObject>();
|
||||||
|
await _customerPrefabHandle.Task;
|
||||||
|
|
||||||
|
if (_customerPrefabHandle.Result == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[CustomerFactory] Failed to load customer prefab from AssetReference.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_customerPrefab = _customerPrefabHandle.Result;
|
||||||
|
Debug.Log("[CustomerFactory] Customer prefab loaded successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnloadAssets()
|
||||||
|
{
|
||||||
|
if (_customerPrefabHandle.IsValid())
|
||||||
|
{
|
||||||
|
Addressables.Release(_customerPrefabHandle);
|
||||||
|
}
|
||||||
|
_customerPrefab = null;
|
||||||
|
Debug.Log("[CustomerFactory] Customer prefab unloaded.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,6 +10,8 @@ public enum RestaurantOrderType : uint
|
|||||||
Reserved = 1u,
|
Reserved = 1u,
|
||||||
Order = 1u << 1,
|
Order = 1u << 1,
|
||||||
Serve = 1u << 2,
|
Serve = 1u << 2,
|
||||||
|
Busy = 1u << 3,
|
||||||
|
Dirty = 1u << 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RestaurantOrderInteractionSubsystem : MonoBehaviour, IInteractionSubsystemObject<RestaurantOrderType>
|
public class RestaurantOrderInteractionSubsystem : MonoBehaviour, IInteractionSubsystemObject<RestaurantOrderType>
|
||||||
|
@ -12,7 +12,9 @@ public static class RestaurantOrderSolvers
|
|||||||
{ RestaurantOrderType.Wait, typeof(RestaurantOrderSolver_Wait) },
|
{ RestaurantOrderType.Wait, typeof(RestaurantOrderSolver_Wait) },
|
||||||
{ RestaurantOrderType.Reserved, typeof(RestaurantOrderSolver_Reserved) },
|
{ RestaurantOrderType.Reserved, typeof(RestaurantOrderSolver_Reserved) },
|
||||||
{ RestaurantOrderType.Order, typeof(RestaurantOrderSolver_Order) },
|
{ RestaurantOrderType.Order, typeof(RestaurantOrderSolver_Order) },
|
||||||
{ RestaurantOrderType.Serve, typeof(RestaurantOrderSolver_Serve) }
|
{ RestaurantOrderType.Serve, typeof(RestaurantOrderSolver_Serve) },
|
||||||
|
{ RestaurantOrderType.Busy, typeof(RestaurantOrderSolver_Busy) },
|
||||||
|
{ RestaurantOrderType.Dirty, typeof(RestaurantOrderSolver_Dirty) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DDD.RestaurantOrders
|
||||||
|
{
|
||||||
|
public class RestaurantOrderSolver_Busy : MonoBehaviour, IInteractionSubsystemSolver<RestaurantOrderType>
|
||||||
|
{
|
||||||
|
public bool ExecuteInteractionSubsystem(IInteractor interactor, IInteractable interactable, ScriptableObject payloadSo = null)
|
||||||
|
{
|
||||||
|
// TODO : DO SOMETHING!!!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanExecuteInteractionSubsystem(IInteractor interactor = null, IInteractable interactable = null,
|
||||||
|
ScriptableObject payloadSo = null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c185b3957ffe47088703be10e709ff66
|
||||||
|
timeCreated: 1755761370
|
@ -0,0 +1,19 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace DDD.RestaurantOrders
|
||||||
|
{
|
||||||
|
public class RestaurantOrderSolver_Dirty : MonoBehaviour, IInteractionSubsystemSolver<RestaurantOrderType>
|
||||||
|
{
|
||||||
|
public bool ExecuteInteractionSubsystem(IInteractor interactor, IInteractable interactable, ScriptableObject payloadSo = null)
|
||||||
|
{
|
||||||
|
// TODO : DO SOMETHING!!!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanExecuteInteractionSubsystem(IInteractor interactor = null, IInteractable interactable = null,
|
||||||
|
ScriptableObject payloadSo = null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b97bc6ce36df4e05a4d329f11daef43f
|
||||||
|
timeCreated: 1755761294
|
@ -1,9 +1,106 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Opsive.BehaviorDesigner.Runtime;
|
||||||
using Sirenix.OdinInspector;
|
using Sirenix.OdinInspector;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.AddressableAssets;
|
||||||
|
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||||
|
|
||||||
namespace DDD
|
namespace DDD
|
||||||
{
|
{
|
||||||
public class RestaurantCustomerState : ScriptableObject
|
public class RestaurantCustomerState : ScriptableObject
|
||||||
{
|
{
|
||||||
|
private Dictionary<CustomerType, Subtree> _loadedSubtrees = new Dictionary<CustomerType, Subtree>();
|
||||||
|
private Dictionary<CustomerType, AsyncOperationHandle<Subtree>> _subtreeHandles = new Dictionary<CustomerType, AsyncOperationHandle<Subtree>>();
|
||||||
|
|
||||||
|
public async Task LoadCustomerBehaviorData()
|
||||||
|
{
|
||||||
|
var customerData = RestaurantData.Instance?.CustomerData;
|
||||||
|
if (customerData?.CustomerBehaviorData == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[RestaurantCustomerState] RestaurantCustomerData or CustomerBehaviorData is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var loadTasks = new List<Task>();
|
||||||
|
foreach (var behaviorPair in customerData.CustomerBehaviorData)
|
||||||
|
{
|
||||||
|
var customerType = behaviorPair.Key;
|
||||||
|
var subtreeReference = behaviorPair.Value;
|
||||||
|
|
||||||
|
if (_loadedSubtrees.ContainsKey(customerType))
|
||||||
|
continue; // Already loaded
|
||||||
|
|
||||||
|
loadTasks.Add(LoadSubtreeAsync(customerType, subtreeReference));
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.WhenAll(loadTasks);
|
||||||
|
Debug.Log($"[RestaurantCustomerState] Loaded {_loadedSubtrees.Count} customer behavior subtrees");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadSubtreeAsync(CustomerType customerType, AssetReference subtreeReference)
|
||||||
|
{
|
||||||
|
var handle = Addressables.LoadAssetAsync<Subtree>(subtreeReference);
|
||||||
|
_subtreeHandles[customerType] = handle;
|
||||||
|
|
||||||
|
await handle.Task;
|
||||||
|
|
||||||
|
if (handle.Result != null)
|
||||||
|
{
|
||||||
|
_loadedSubtrees[customerType] = handle.Result;
|
||||||
|
Debug.Log($"[RestaurantCustomerState] Loaded subtree for {customerType}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError($"[RestaurantCustomerState] Failed to load subtree for {customerType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnloadCustomerBehaviorData()
|
||||||
|
{
|
||||||
|
foreach (var handle in _subtreeHandles.Values)
|
||||||
|
{
|
||||||
|
if (handle.IsValid())
|
||||||
|
{
|
||||||
|
Addressables.Release(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadedSubtrees.Clear();
|
||||||
|
_subtreeHandles.Clear();
|
||||||
|
Debug.Log("[RestaurantCustomerState] Unloaded all customer behavior subtrees");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Subtree GetLoadedSubtree(CustomerType customerType)
|
||||||
|
{
|
||||||
|
_loadedSubtrees.TryGetValue(customerType, out var subtree);
|
||||||
|
return subtree;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Subtree> GetOrLoadSubtree(CustomerType customerType)
|
||||||
|
{
|
||||||
|
if (IsSubtreeLoaded(customerType))
|
||||||
|
{
|
||||||
|
return GetLoadedSubtree(customerType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var customerData = RestaurantData.Instance?.CustomerData;
|
||||||
|
if (customerData?.CustomerBehaviorData == null ||
|
||||||
|
!customerData.CustomerBehaviorData.TryGetValue(customerType, out var subtreeReference))
|
||||||
|
{
|
||||||
|
Debug.LogError($"[RestaurantCustomerState] No behavior data found for {customerType}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
await LoadSubtreeAsync(customerType, subtreeReference);
|
||||||
|
return GetLoadedSubtree(customerType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSubtreeLoaded(CustomerType customerType)
|
||||||
|
{
|
||||||
|
return _loadedSubtrees.ContainsKey(customerType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
ProjectSettings/EditorBuildSettings.asset
(Stored with Git LFS)
BIN
ProjectSettings/EditorBuildSettings.asset
(Stored with Git LFS)
Binary file not shown.
Loading…
Reference in New Issue
Block a user