diff --git a/Assets/_DDD/_Scripts/GameEvent/InteractionSubsystem.cs b/Assets/_DDD/_Scripts/GameEvent/InteractionSubsystem.cs index c5b79395d..1085117d3 100644 --- a/Assets/_DDD/_Scripts/GameEvent/InteractionSubsystem.cs +++ b/Assets/_DDD/_Scripts/GameEvent/InteractionSubsystem.cs @@ -3,11 +3,22 @@ namespace DDD { - public interface IInteractionSubsystemObject where T : Enum + public interface IInteractionSubsystemObject + { + Type GetSubsystemEnumType(); + void InitializeSubsystem(); + bool CanInteract(); + bool OnInteracted(IInteractor interactor, ScriptableObject payloadSo = null); + } + public interface IInteractionSubsystemObject : IInteractionSubsystemObject where T : Enum { T GetInteractionSubsystemType(); } - public interface IInteractionSubsystemSolver where T : Enum + + public interface IInteractionSubsystemSolver + { + } + public interface IInteractionSubsystemSolver : IInteractionSubsystemSolver where T : Enum { bool ExecuteInteractionSubsystem(IInteractor interactor, IInteractable interactable, ScriptableObject payloadSo = null); bool CanExecuteInteractionSubsystem(IInteractor interactor = null, IInteractable interactable = null, diff --git a/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacter.cs b/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacter.cs index 0772089b6..45c56de5d 100644 --- a/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacter.cs +++ b/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacter.cs @@ -23,7 +23,7 @@ protected virtual void Start() var flag = typeToSolver.Key; if (flag == InteractionType.None) continue; - if ((_interactionComponent.InteractionType & flag) == 0) continue; + if ((_interactionComponent.AvailableInteractions & flag) == 0) continue; if (!TryGetComponent(typeToSolver.Value, out _)) { diff --git a/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacterInteraction.cs b/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacterInteraction.cs index c4745fafd..3db7a4412 100644 --- a/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacterInteraction.cs +++ b/Assets/_DDD/_Scripts/RestaurantCharacter/Core/RestaurantCharacterInteraction.cs @@ -6,10 +6,10 @@ namespace DDD { public class RestaurantCharacterInteraction : MonoBehaviour, IInteractor, IEventHandler { - [EnumToggleButtons, SerializeField] protected InteractionType _interactionType; + [EnumToggleButtons, SerializeField] protected InteractionType _availableInteractions; [SerializeField, ReadOnly] protected Collider[] _nearColliders = new Collider[10]; - public InteractionType InteractionType => _interactionType; + public InteractionType AvailableInteractions => _availableInteractions; protected IInteractable _nearestInteractable; protected IInteractable _previousInteractable; diff --git a/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteraction.cs b/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteraction.cs deleted file mode 100644 index d39dd3d8f..000000000 --- a/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteraction.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using UnityEngine; - -namespace DDD -{ - [Flags] - public enum RestaurantOrderInteractionType : uint - { - // None = 0u, - WaitCustomer = 0, - // WaitCustomer = 1u << 0, - // WaitOrder = 1u << 1, - // WaitServe = 1u << 2, - // All = 0xFFFFFFFFu - } - public class RestaurantOrderInteraction : RestaurantInteractionComponent, IInteractionSubsystemObject - { - [SerializeField] protected RestaurantOrderInteractionType _initialOrderInteractionType = RestaurantOrderInteractionType.WaitCustomer; - private RestaurantOrderInteractionType _currentRestaurantOrderInteractionType; - - // EDITOR - private void Reset() - { - SetInteractionTypeToRestaurantOrder(); - } - private void OnValidate() - { - SetInteractionTypeToRestaurantOrder(); - } - // ~EDITOR - - private void Start() - { - _currentRestaurantOrderInteractionType = _initialOrderInteractionType; - } - - private void SetInteractionTypeToRestaurantOrder() - { - _interactionType = InteractionType.RestaurantOrder; - } - public override InteractionType GetInteractionType() - { - return InteractionType.RestaurantOrder; - } - public override bool CanInteract() - { - // 현재 RestaurantOrderInteractionType를 수행할 수 있는지? - if (GetInteractionSubsystemType() == RestaurantOrderInteractionType.WaitCustomer) - { - // Check WaitCustomer - return true; - } - - return false; - } - - public override bool OnInteracted(IInteractor interactor, ScriptableObject payloadSo = null) - { - // _currentRestaurantOrderInteractionType에 따라 동작이 달라지겠지 - if (GetInteractionSubsystemType() == RestaurantOrderInteractionType.WaitCustomer) - { - // DO WAIT CUSTOMER - } - return base.OnInteracted(interactor, payloadSo); - } - - public override void InitializeInteraction(InteractionType interactionType) - { - // RestaurantOrderInteractionType에 따른 동작들을 초기화 - // Initialize WaitCustomer actions - base.InitializeInteraction(interactionType); - } - - public RestaurantOrderInteractionType GetInteractionSubsystemType() - { - return _currentRestaurantOrderInteractionType; - } - } -} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteractionSubsystem.cs b/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteractionSubsystem.cs new file mode 100644 index 000000000..40b619387 --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteractionSubsystem.cs @@ -0,0 +1,59 @@ +using System; +using UnityEngine; + +namespace DDD +{ + [Flags] + public enum RestaurantOrderType : uint + { + Wait = 0, + Order = 1u << 0, + Serve = 1u << 1, + } + + public class RestaurantOrderInteractionSubsystem : MonoBehaviour, IInteractionSubsystemObject + { + [SerializeField] protected RestaurantOrderType orderType = RestaurantOrderType.Wait; + private RestaurantOrderType currentRestaurantOrderType; + + public Type GetSubsystemEnumType() => typeof(RestaurantOrderType); + + private void Start() + { + currentRestaurantOrderType = orderType; + } + + public bool CanInteract() + { + // 현재 RestaurantOrderInteractionType를 수행할 수 있는지? + if (GetInteractionSubsystemType() == RestaurantOrderType.Wait) + { + Debug.Assert(false); // TODO + // Check WaitCustomer + return true; + } + return false; + } + + public bool OnInteracted(IInteractor interactor, ScriptableObject payloadSo = null) + { + // _currentRestaurantOrderInteractionType에 따라 동작이 달라지겠지 + if (GetInteractionSubsystemType() == RestaurantOrderType.Wait) + { + // DO WAIT CUSTOMER + } + + return true; + } + + public void InitializeSubsystem() + { + + } + + public RestaurantOrderType GetInteractionSubsystemType() + { + return currentRestaurantOrderType; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteraction.cs.meta b/Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteractionSubsystem.cs.meta similarity index 100% rename from Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteraction.cs.meta rename to Assets/_DDD/_Scripts/RestaurantEnvironment/Interactions/RestaurantOrderInteractionSubsystem.cs.meta diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/RestaurantInteractionComponent.cs b/Assets/_DDD/_Scripts/RestaurantEvent/RestaurantInteractionComponent.cs index d88aefe9c..72090e59d 100644 --- a/Assets/_DDD/_Scripts/RestaurantEvent/RestaurantInteractionComponent.cs +++ b/Assets/_DDD/_Scripts/RestaurantEvent/RestaurantInteractionComponent.cs @@ -1,19 +1,49 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; using UnityEngine; +using Sirenix.OdinInspector; namespace DDD { + public static class RestaurantInteractionSubsystems + { + public static Dictionary TypeToSubsystem = new() + { + {InteractionType.RestaurantOrder, typeof(RestaurantOrderInteractionSubsystem)} + }; + } + public class RestaurantInteractionComponent : MonoBehaviour, IInteractable { + // Single interaction type + [ValueDropdown("GetAllInteractionTypes")] [SerializeField] protected InteractionType _interactionType = InteractionType.None; [SerializeField] protected InteractionExecutionParameters _executionParameters = new InteractionExecutionParameters(1f); [SerializeField] protected InteractionDisplayParameters _displayParameters = new InteractionDisplayParameters(""); [SerializeField] protected GameFlowState _interactionAvailableFlows; [SerializeField] private Transform[] _aiInteractionPoints; - + + private Dictionary _subsystems = new(); + + private static IEnumerable GetAllInteractionTypes() + { + return System.Enum.GetValues(typeof(InteractionType)) + .Cast() + .Where(x => x != InteractionType.All); // All은 제외 + } + public virtual bool CanInteract() { - return !IsInteractionHidden(); + bool isInteractionVisible = !IsInteractionHidden(); + bool hasValidSubsystem = true; + if (HasSubsystem(_interactionType)) + { + hasValidSubsystem = GetSubsystem(_interactionType).CanInteract(); + } + return isInteractionVisible && hasValidSubsystem; } public virtual bool IsInteractionHidden() @@ -31,6 +61,10 @@ public virtual bool OnInteracted(IInteractor interactor, ScriptableObject payloa } bool interactionResult = RestaurantInteractionEvents.RestaurantInteraction.RequestInteraction(interactor.GetInteractorGameObject(), GetInteractableGameObject(), GetInteractionType(), payloadSo, true); + if (HasSubsystem(_interactionType)) + { + interactionResult &= GetSubsystem(_interactionType).OnInteracted(interactor, payloadSo); + } return interactionResult; } @@ -47,6 +81,33 @@ public GameObject GetInteractableGameObject() public virtual void InitializeInteraction(InteractionType interactionType) { _interactionType = interactionType; + + InitializeSubsystems(); + } + + private void InitializeSubsystems() + { + // Initialize Interaction Subsystems + bool hasSubsystemType = RestaurantInteractionSubsystems.TypeToSubsystem.TryGetValue(_interactionType, out var subsystemType); + if (!hasSubsystemType) return; + + var subsystem = gameObject.GetComponent(subsystemType) as IInteractionSubsystemObject; + if (subsystem == null) + { + subsystem = gameObject.AddComponent(subsystemType) as IInteractionSubsystemObject; + } + _subsystems.Add(_interactionType, subsystem); + subsystem?.InitializeSubsystem(); + } + + private bool HasSubsystem(InteractionType interactionType) + { + return _subsystems.ContainsKey(interactionType); + } + + private IInteractionSubsystemObject GetSubsystem(InteractionType interactionType) + { + return _subsystems.GetValueOrDefault(interactionType) as IInteractionSubsystemObject; } // 새로운 스트럭트 기반 메서드들 diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrderSolver.cs b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrderSolver.cs index 3f8089dee..38bfe2d87 100644 --- a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrderSolver.cs +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrderSolver.cs @@ -1,48 +1,56 @@ +using System; +using System.Collections.Generic; +using DDD.RestaurantOrders; using UnityEngine; namespace DDD { - public class RestaurantOrderSolver : MonoBehaviour, IInteractionSolver, IInteractionSubsystemSolver + public static class RestaurantOrderSolvers { + public static Dictionary TypeToOrderSolver = new() + { + { RestaurantOrderType.Wait, typeof(RestaurantOrderSolver_Wait) }, + { RestaurantOrderType.Order, typeof(RestaurantOrderSolver_Order) }, + { RestaurantOrderType.Serve, typeof(RestaurantOrderSolver_Serve) } + }; + } + + public class RestaurantOrderSolver : MonoBehaviour, IInteractionSolver + { + private Dictionary> _solvers = new(); + + private void Start() + { + foreach (var orderSolver in RestaurantOrderSolvers.TypeToOrderSolver) + { + var solver = (IInteractionSubsystemSolver)gameObject.AddComponent(orderSolver.Value); + _solvers.Add(orderSolver.Key, solver); + } + } + public bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject payloadSo = null) { - return ExecuteInteractionSubsystem(interactor, interactable, payloadSo); + return TryGetSolver(interactable, out var solver) && + solver.ExecuteInteractionSubsystem(interactor, interactable, payloadSo); } public bool CanExecuteInteraction(IInteractor interactor = null, IInteractable interactable = null, ScriptableObject payloadSo = null) { - return CanExecuteInteractionSubsystem(interactor, interactable, payloadSo); + return TryGetSolver(interactable, out var solver) && + solver.CanExecuteInteractionSubsystem(interactor, interactable, payloadSo); } - public bool ExecuteInteractionSubsystem(IInteractor interactor, IInteractable interactable, ScriptableObject payloadSo = null) + // Solver를 가져오는 공통 로직 + private bool TryGetSolver(IInteractable interactable, out IInteractionSubsystemSolver solver) { - if (interactable is IInteractionSubsystemObject subsystem) - { - RestaurantOrderInteractionType interactionType = subsystem.GetInteractionSubsystemType(); - // Can I solve this interaction type? - if (interactionType == RestaurantOrderInteractionType.WaitCustomer) - { - // DO SOMETHING!!! - return true; - } - } - return false; - } - - public bool CanExecuteInteractionSubsystem(IInteractor interactor = null, IInteractable interactable = null, - ScriptableObject payloadSo = null) - { - if (interactable is IInteractionSubsystemObject subsystem) - { - RestaurantOrderInteractionType interactionType = subsystem.GetInteractionSubsystemType(); - // Can I solve this interaction type? - if (interactionType == RestaurantOrderInteractionType.WaitCustomer) - { - return true; - } - } - return false; + solver = null; + + if (interactable is not IInteractionSubsystemObject subsystem) + return false; + + var type = subsystem.GetInteractionSubsystemType(); + return _solvers.TryGetValue(type, out solver); } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders.meta b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders.meta new file mode 100644 index 000000000..9518f5240 --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0a7eea23af674c2aa6ffc20bd5801efb +timeCreated: 1755672003 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs new file mode 100644 index 000000000..edee1940d --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace DDD.RestaurantOrders +{ + public class RestaurantOrderSolver_Order : MonoBehaviour, IInteractionSubsystemSolver + { + 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; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs.meta b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs.meta new file mode 100644 index 000000000..a47a2ccd0 --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3afc1759b02e4230967b3b72fe354ea3 +timeCreated: 1755672492 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Serve.cs b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Serve.cs new file mode 100644 index 000000000..263c65494 --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Serve.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace DDD.RestaurantOrders +{ + public class RestaurantOrderSolver_Serve : MonoBehaviour, IInteractionSubsystemSolver + { + 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; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Serve.cs.meta b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Serve.cs.meta new file mode 100644 index 000000000..3186c427f --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Serve.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4df15c40347044648623d5932bb0724e +timeCreated: 1755672501 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs new file mode 100644 index 000000000..14f6f77d9 --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs @@ -0,0 +1,19 @@ +using UnityEngine; + +namespace DDD.RestaurantOrders +{ + public class RestaurantOrderSolver_Wait : MonoBehaviour, IInteractionSubsystemSolver + { + 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; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs.meta b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs.meta new file mode 100644 index 000000000..3e85dc4c2 --- /dev/null +++ b/Assets/_DDD/_Scripts/RestaurantEvent/Solvers/RestaurantOrders/RestaurantOrderSolver_Wait.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cc81a22ff98a4b42b45ad27219ec05fa +timeCreated: 1755672371 \ No newline at end of file