손님 비헤이비어 트리 초안 작성
This commit is contained in:
parent
5efc97f64d
commit
8f56d99bf7
@ -136,7 +136,7 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
_interactionType: 1
|
||||
_executionParameters:
|
||||
_holdTime: 1
|
||||
_holdTime: 0.1
|
||||
_displayParameters:
|
||||
_messageKey:
|
||||
_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:
|
||||
_interactionType: 1
|
||||
_executionParameters:
|
||||
_holdTime: 1
|
||||
_holdTime: 0
|
||||
_displayParameters:
|
||||
_messageKey:
|
||||
_interactionAvailableFlows: 1
|
||||
_aiInteractionPoints: []
|
||||
autoInitialize: 1
|
||||
--- !u!114 &4545680930728379745
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -377,3 +378,4 @@ MonoBehaviour:
|
||||
m_Script: {fileID: 11500000, guid: 1235f6bde9304d8f85079f2777bd4b3c, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
_managementType: 0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -234,10 +234,18 @@ MonoBehaviour:
|
||||
m_Data:
|
||||
m_TaskData: []
|
||||
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_DisabledLogicNodesData: []
|
||||
m_UniqueID: -1885404201
|
||||
m_UniqueID: 1495981264
|
||||
m_LogicNodePropertiesData: []
|
||||
m_EventNodePropertiesData: []
|
||||
m_GroupPropertiesData: []
|
||||
|
@ -366,6 +366,9 @@ PrefabInstance:
|
||||
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 8993310060139522557}
|
||||
- targetCorrespondingSourceObject: {fileID: 5259510642736920361, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: -6848683434426724985}
|
||||
- targetCorrespondingSourceObject: {fileID: 6791841979869644848, guid: 3db3fc62639929c4ba6031ca4ae6600c, type: 3}
|
||||
insertIndex: -1
|
||||
addedObject: {fileID: 662634663174340165}
|
||||
@ -461,6 +464,36 @@ MonoBehaviour:
|
||||
m_EditorClassIdentifier:
|
||||
blockOutlineAndGlow: 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
|
||||
Transform:
|
||||
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
|
||||
{
|
||||
[RequireComponent(typeof(RestaurantCustomerAiComponent))]
|
||||
public class CustomerCharacter : RestaurantNpcCharacter, ICustomerInitializer
|
||||
{
|
||||
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;
|
||||
restaurantCustomerAi.InitializeAi(_customerData);
|
||||
|
||||
// 스킨 설정
|
||||
_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
|
||||
{
|
||||
[RequireComponent(typeof(BehaviorTree))]
|
||||
[RequireComponent(typeof(RestaurantNpcMovement))]
|
||||
public class RestaurantNpcCharacter : RestaurantCharacter
|
||||
{
|
||||
protected BehaviorTree _behaviorTree;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
_behaviorTree = GetComponent<BehaviorTree>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
[RequireComponent(typeof(RestaurantPlayerMovement))]
|
||||
public class RestaurantPlayerCharacter : RestaurantCharacter
|
||||
{
|
||||
protected override async void Awake()
|
||||
|
@ -27,6 +27,9 @@ public override Task InitializeController()
|
||||
{
|
||||
_restaurantCustomerStateSo = RestaurantState.Instance.CustomerState;
|
||||
_restaurantRunStateSo = RestaurantState.Instance.RunState;
|
||||
|
||||
_iCustomerFactory ??= new CustomerFactory();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@ -41,6 +44,9 @@ public override async Task OnReadyNewFlow(GameFlowState newFlowState)
|
||||
{
|
||||
if (newFlowState == GameFlowState.RunRestaurant)
|
||||
{
|
||||
_iCustomerFactory.LoadAssets();
|
||||
await _restaurantCustomerStateSo.LoadCustomerBehaviorData();
|
||||
|
||||
_cts?.Cancel();
|
||||
_cts?.Dispose();
|
||||
_cts = new CancellationTokenSource();
|
||||
@ -52,6 +58,9 @@ public override Task OnExitCurrentFlow(GameFlowState exitingFlowState)
|
||||
{
|
||||
if (exitingFlowState == GameFlowState.RunRestaurant)
|
||||
{
|
||||
_iCustomerFactory.UnloadAssets();
|
||||
_restaurantCustomerStateSo.UnloadCustomerBehaviorData();
|
||||
|
||||
_cts?.Cancel();
|
||||
_cts?.Dispose();
|
||||
_cts = null;
|
||||
@ -61,8 +70,6 @@ public override Task OnExitCurrentFlow(GameFlowState exitingFlowState)
|
||||
|
||||
private async Task StartSpawnLoopAsync(CancellationToken token)
|
||||
{
|
||||
_iCustomerFactory ??= new CustomerFactory();
|
||||
|
||||
var currentGameLevel = GameState.Instance.LevelState.Level;
|
||||
_levelDataSo ??= DataManager.Instance.GetDataSo<LevelDataSo>();
|
||||
_customerDataSo ??= DataManager.Instance.GetDataSo<CustomerDataSo>();
|
||||
@ -115,7 +122,7 @@ SpawnSchedule MakeSchedule() => scheduleBuilder.Build(new SpawnScheduleBuildArgs
|
||||
{
|
||||
var rotation = Quaternion.identity;
|
||||
|
||||
_ = _iCustomerFactory.CreateAsync(new CustomerSpawnArgs
|
||||
await _iCustomerFactory.CreateAsync(new CustomerSpawnArgs
|
||||
{
|
||||
CustomerData = customerData,
|
||||
Position = _restaurantRunStateSo.SpawnPoint,
|
||||
|
@ -1,11 +1,15 @@
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public interface ICustomerFactory
|
||||
{
|
||||
Task<GameObject> CreateAsync(CustomerSpawnArgs args);
|
||||
void LoadAssets();
|
||||
void UnloadAssets();
|
||||
}
|
||||
|
||||
public interface ICustomerInitializer
|
||||
@ -24,26 +28,14 @@ public struct CustomerSpawnArgs
|
||||
public class CustomerFactory : ICustomerFactory
|
||||
{
|
||||
private GameObject _customerPrefab;
|
||||
private AsyncOperationHandle<GameObject> _customerPrefabHandle;
|
||||
|
||||
public async Task<GameObject> CreateAsync(CustomerSpawnArgs args)
|
||||
{
|
||||
if (!_customerPrefab)
|
||||
{
|
||||
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 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;
|
||||
Debug.LogError("[CustomerFactory] Customer prefab is not loaded. Call LoadAssets() first.");
|
||||
await LoadCustomerAsset();
|
||||
}
|
||||
|
||||
var newCustomer = Object.Instantiate(_customerPrefab, args.Position, args.Rotation, args.Parent);
|
||||
@ -54,5 +46,47 @@ public async Task<GameObject> CreateAsync(CustomerSpawnArgs args)
|
||||
}
|
||||
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,
|
||||
Order = 1u << 1,
|
||||
Serve = 1u << 2,
|
||||
Busy = 1u << 3,
|
||||
Dirty = 1u << 4,
|
||||
}
|
||||
|
||||
public class RestaurantOrderInteractionSubsystem : MonoBehaviour, IInteractionSubsystemObject<RestaurantOrderType>
|
||||
|
@ -12,7 +12,9 @@ public static class RestaurantOrderSolvers
|
||||
{ RestaurantOrderType.Wait, typeof(RestaurantOrderSolver_Wait) },
|
||||
{ RestaurantOrderType.Reserved, typeof(RestaurantOrderSolver_Reserved) },
|
||||
{ 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 UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
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