diff --git a/Assets/_DDD/_Addressables/AI/Customer/Subtree/CustomerDefault.asset b/Assets/_DDD/_Addressables/AI/Customer/Subtree/CustomerDefault.asset index a793b242d..fdfd90ada 100644 --- a/Assets/_DDD/_Addressables/AI/Customer/Subtree/CustomerDefault.asset +++ b/Assets/_DDD/_Addressables/AI/Customer/Subtree/CustomerDefault.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:277f8b3b25cfe078e4838cab1222b85e5dae0bc036cb39e5f84b6e3b3fce1cd0 -size 68048 +oid sha256:4d98b77206ba374a44c488e0c83a0970ea49d46ab9e1802277e48352d9cc1a98 +size 66395 diff --git a/Assets/_DDD/_Addressables/AI/Customer/Subtree/OrderSubtree.asset b/Assets/_DDD/_Addressables/AI/Customer/Subtree/OrderSubtree.asset index 7e7bb95e0..6ff001db6 100644 --- a/Assets/_DDD/_Addressables/AI/Customer/Subtree/OrderSubtree.asset +++ b/Assets/_DDD/_Addressables/AI/Customer/Subtree/OrderSubtree.asset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6da8678bc90f664244b89aa26dc5c6b01c51567387ea3414b916fb27082f752b -size 16520 +oid sha256:28c1a3c2113f824ca9b3493aa71a73bffa3040160b830e2fde428b5c7bbe1610 +size 16553 diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs index b954d1bf7..0e5cd3b9d 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs @@ -8,12 +8,6 @@ public class StartRestaurantOrder : Action { [Tooltip("상호작용할 RestaurantOrderType")] [SerializeField] private RestaurantOrderType _targetOrderType = RestaurantOrderType.Wait; - [Tooltip("실제 상호작용 가능 여부를 확인하고 수행합니다")] - [SerializeField] private bool _requireCanInteract = true; - [Tooltip("성공 시 블랙보드에 현재 인터랙션 대상을 등록합니다")] - [SerializeField] private bool _registerOnBlackboard = true; - [Tooltip("성공 시 블랙보드에 현재 인터랙션 대상을 등록합니다")] - [SerializeField] private bool _UnregisterOnBlackboard = false; private IInteractor _interactor; private bool _isGetInteractor; @@ -28,29 +22,55 @@ public override void OnStart() public override TaskStatus OnUpdate() { - // 레스토랑 주문 인터랙션 후보를 가져옴 - TaskStatus targetSearchSuccess = RestaurantOrderAvailable.FindAvailableOrderInteractable(_requireCanInteract, _targetOrderType, out var - outInteractable); - if (targetSearchSuccess == TaskStatus.Failure) + var blackboard = gameObject.GetComponent(); + var target = blackboard?.GetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); + IInteractable currentInteractable = target?.GetComponent(); + + if (_targetOrderType == RestaurantOrderType.Wait) { + // 레스토랑 주문 인터랙션 후보를 가져옴 + TaskStatus targetSearchSuccess = RestaurantOrderAvailable.FindAvailableOrderInteractable(_targetOrderType, out currentInteractable); + if (targetSearchSuccess == TaskStatus.Failure) + { + return TaskStatus.Failure; + } + var customerBlackboard = gameObject.GetComponent(); + customerBlackboard?.SetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget), currentInteractable.GetInteractableGameObject()); + } + + // Check order type of the current interactable + if (currentInteractable is IInteractionSubsystemOwner subsystemOwner) + { + if (subsystemOwner.TryGetSubsystemEnumType(out var subsystemType)) + { + if (subsystemType != _targetOrderType) + { + Debug.LogWarning($"[{GetType().Name}] 상호작용할 RestaurantOrderType이 다릅니다: {subsystemType} != {_targetOrderType}"); + return TaskStatus.Failure; + } + } + else + { + return TaskStatus.Failure; + } + } + + + if (currentInteractable == null) + { + Debug.Assert(false); return TaskStatus.Failure; } // 상호작용 수행: 액션이 붙은 에이전트를 Interactor로 사용 - if (!_isGetInteractor || !_interactor.CanInteractTo(outInteractable)) + if (!_isGetInteractor) { return TaskStatus.Failure; } - RestaurantEvents.InteractionEvent.RequestInteraction(_interactor.GetInteractorGameObject(), outInteractable.gameObject, outInteractable.GetInteractionType()); + RestaurantEvents.InteractionEvent.RequestInteraction(_interactor.GetInteractorGameObject(), currentInteractable.GetInteractableGameObject(), currentInteractable.GetInteractionType()); - if (_registerOnBlackboard) - { - var customerBlackboard = gameObject.GetComponent(); - customerBlackboard?.SetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget), outInteractable.gameObject); - } - - if (_UnregisterOnBlackboard) + if (_targetOrderType == RestaurantOrderType.Busy) { var customerBlackboard = gameObject.GetComponent(); customerBlackboard?.SetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget), null); diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/WaitForPlayerInteraction.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/WaitForPlayerInteraction.cs index 30feb0826..c661a508d 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/WaitForPlayerInteraction.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/WaitForPlayerInteraction.cs @@ -9,8 +9,9 @@ namespace DDD.Restaurant public class WaitForPlayerInteraction : Action { [SerializeField] private RestaurantOrderType _targetOrderType; + [SerializeField] private RestaurantOrderType _nextOrderType; private IInteractionSubsystemObject _interactionSubsystem; - private bool _isGetInteractionSubsystem; + private bool _isSubsystemExist; public override void OnStart() { @@ -43,13 +44,19 @@ public override void OnStart() $"[{GetType().Name}]에서 {nameof(IInteractionSubsystemObject)}를 찾을 수 없습니다: {gameObject.name}"); return; } - - _isGetInteractionSubsystem = true; + + if (_interactionSubsystem?.GetInteractionSubsystemType() != _targetOrderType) + { + Debug.Log($"[{GetType().Name}] 다른 Order Type: {_interactionSubsystem?.GetInteractionSubsystemType()} != {_targetOrderType}"); + return; + } + + _isSubsystemExist = true; } public override TaskStatus OnUpdate() { - if (!_isGetInteractionSubsystem) return TaskStatus.Failure; + if (!_isSubsystemExist) return TaskStatus.Failure; TaskStatus result = CheckToSubsystemStatus(); if (result == TaskStatus.Success) Debug.Log($"[{GetType().Name}] Success"); @@ -58,9 +65,10 @@ public override TaskStatus OnUpdate() private TaskStatus CheckToSubsystemStatus() { - return _interactionSubsystem.GetInteractionSubsystemType() == _targetOrderType - ? TaskStatus.Running - : TaskStatus.Success; + var currentSubsystemType = _interactionSubsystem.GetInteractionSubsystemType(); + if (currentSubsystemType == _nextOrderType) + return TaskStatus.Success; + return TaskStatus.Running; } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Conditionals/RestaurantOrderAvailable.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Conditionals/RestaurantOrderAvailable.cs index da16bc590..1ee79b586 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Conditionals/RestaurantOrderAvailable.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Conditionals/RestaurantOrderAvailable.cs @@ -28,13 +28,13 @@ public bool CheckCanInteract public override TaskStatus OnUpdate() { - TaskStatus targetSearchSuccess = FindAvailableOrderInteractable(_checkCanInteract, _targetOrderType, out var + TaskStatus targetSearchSuccess = FindAvailableOrderInteractable(_targetOrderType, out var outInteractable); return targetSearchSuccess; } - public static TaskStatus FindAvailableOrderInteractable(bool checkCanInteract, T targetOrderType, out RestaurantInteractionComponent outInteractable) where T : Enum + public static TaskStatus FindAvailableOrderInteractable(RestaurantOrderType targetOrderType, out IInteractable outInteractable) { outInteractable = null; @@ -45,25 +45,17 @@ public static TaskStatus FindAvailableOrderInteractable(bool checkCanInteract } var interactables = environmentState.GetInteractablesByType(InteractionType.RestaurantOrder); - foreach (var interactable in interactables) { // 서브시스템에서 RestaurantOrderType을 가져와 비교 - outInteractable = interactable as RestaurantInteractionComponent; - if (outInteractable == null) continue; - if (!outInteractable.TryGetSubsystemObject(out var subsystem)) continue; - - if (EqualityComparer.Default.Equals(subsystem.GetInteractionSubsystemType(), targetOrderType)) + if (interactable is not IInteractionSubsystemOwner subsystemOwner) continue; + if (!subsystemOwner.TryGetSubsystemObject(out var subsystem)) continue; + if (subsystem.GetInteractionSubsystemType() == targetOrderType) { - // CheckCanInteract이 false면 타입만 맞으면 성공 - if (!checkCanInteract) - { - return TaskStatus.Success; - } - // CheckCanInteract이 true면 실제 인터랙션 가능 여부까지 확인 if (interactable.CanInteract()) { + outInteractable = interactable; return TaskStatus.Success; } } diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs b/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs index 21832e1ea..6053e032b 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/Player/PlayerInteraction.cs @@ -39,14 +39,17 @@ private Task Initialize() public override void InitializeSolvers() { - var typesToSolver = RestaurantInteractionEventSolvers.TypeToSolver; var playerSolver = RestaurantInteractionEventSolvers.TypeToPlayerSolver; - foreach(var pair in playerSolver) + Dictionary typesToSolver = new(); + foreach (var typeToSolver in RestaurantInteractionEventSolvers.TypeToSolver) { - typesToSolver.Remove(pair.Key); + typesToSolver.Add(typeToSolver.Key, typeToSolver.Value); + } + foreach (var typeToSolver in playerSolver) + { + typesToSolver[typeToSolver.Key] = typeToSolver.Value; } InitializeInteractionSolvers(typesToSolver); - InitializeInteractionSolvers(playerSolver); } protected override void OnDestroy() diff --git a/Assets/_DDD/_Scripts/Restaurant/Environment/IInteractionSubsystemOwner.cs b/Assets/_DDD/_Scripts/Restaurant/Environment/IInteractionSubsystemOwner.cs index bd99e64be..69d57ccec 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Environment/IInteractionSubsystemOwner.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Environment/IInteractionSubsystemOwner.cs @@ -6,5 +6,6 @@ namespace DDD public interface IInteractionSubsystemOwner { public bool TryGetSubsystemObject(out IInteractionSubsystemObject subsystemObject) where T : Enum; + public bool TryGetSubsystemEnumType(out T subsystemType) where T : Enum; } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Environment/Interactions/InteractionSubsystem_Order.cs b/Assets/_DDD/_Scripts/Restaurant/Environment/Interactions/InteractionSubsystem_Order.cs index fde3d3f3c..968306869 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Environment/Interactions/InteractionSubsystem_Order.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Environment/Interactions/InteractionSubsystem_Order.cs @@ -21,13 +21,7 @@ public interface IRestaurantOrderObject public class InteractionSubsystem_Order : MonoBehaviour, IInteractionSubsystemObject, IRestaurantOrderObject { - [FormerlySerializedAs("orderType")] [SerializeField] protected RestaurantOrderType _orderType = RestaurantOrderType.Wait; - private RestaurantOrderType _currentRestaurantOrderType; - - private void Start() - { - _currentRestaurantOrderType = _orderType; - } + [SerializeField] private RestaurantOrderType _currentRestaurantOrderType = RestaurantOrderType.Wait; public bool CanInteract() { @@ -58,7 +52,6 @@ public ScriptableObject GetPayload() public void InitializeSubsystem() { - _currentRestaurantOrderType = _orderType; } public RestaurantOrderType GetInteractionSubsystemType() diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs index 422daa866..f13b03a20 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionComponent.cs @@ -185,5 +185,20 @@ public bool TryGetSubsystemObject(out IInteractionSubsystemObject subsyste subsystemObject = null; return false; } + + public bool TryGetSubsystemEnumType(out T enumValue) where T : Enum + { + foreach (var interactionSubsystemObject in _subsystems.Values) + { + if (interactionSubsystemObject is IInteractionSubsystemObject subsystem) + { + enumValue = subsystem.GetInteractionSubsystemType(); + return true; + } + } + + enumValue = default; + return false; + } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs b/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs index 62dc989e4..536232103 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs @@ -7,8 +7,8 @@ public class RestaurantOrderSolver_Wait : MonoBehaviour, IInteractionSubsystemSo { public bool ExecuteInteractionSubsystem(IInteractor interactor, IInteractable interactable, ScriptableObject payload = null) { - if (CanExecuteInteractionSubsystem(interactor, interactable, payload) == false) return false; - + if (CanExecuteInteractionSubsystem(interactor, interactable, payload) == false) + return false; if (interactable is not IInteractionSubsystemOwner subsystemOwner) return false; if (!subsystemOwner.TryGetSubsystemObject(out var subsystem))