From 36cfe1d92322cb24503dfe2490e0f1ac1a072473 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=82=B0?= Date: Fri, 29 Aug 2025 17:16:48 +0900 Subject: [PATCH] =?UTF-8?q?Exit,=20Entry=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20emotion=20=ED=91=9C=ED=98=84=20=EC=95=A1?= =?UTF-8?q?=EC=85=98,=20=EB=A7=8C=EC=A1=B1=EB=8F=84=20=ED=8F=89=EA=B0=80?= =?UTF-8?q?=20=EC=95=A1=EC=85=98,=20=EB=A7=88=EC=BB=A4=20=ED=83=90?= =?UTF-8?q?=EC=83=89-=EB=93=B1=EB=A1=9D=20=EC=95=A1=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80,=20=EB=A7=88=EC=BB=A4=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Restaurant/Environments/PointMarker.meta | 8 ++ .../PointMarker/PointMarker.prefab | 103 ++++++++++++++++++ .../PointMarker/PointMarker.prefab.meta | 7 ++ .../AI/Common/Actions/ExpressEmotion.cs | 53 +++++++++ .../AI/Common/Actions/ExpressEmotion.cs.meta | 3 + .../Common/Actions/LookAtInteractionTarget.cs | 2 +- .../Common/Actions/SearchAndRegisterMarker.cs | 33 ++++++ .../Actions/SearchAndRegisterMarker.cs.meta | 3 + .../Customer/Actions/SatisfactionEvaluator.cs | 31 ++++++ .../Actions/SatisfactionEvaluator.cs.meta | 3 + .../Customer/Actions/StartRestaurantOrder.cs | 2 +- .../Character/Core/CharacterInteraction.cs | 2 +- .../Environment/IEnvironmentPointProvider.cs | 20 ++++ .../IEnvironmentPointProvider.cs.meta | 3 + .../Environment/PositionProvider.meta | 3 + .../EnvironmentPointMarker.cs | 36 ++++++ .../EnvironmentPointMarker.cs.meta | 3 + .../RestaurantEnvironmentPointQueryEvent.cs | 15 +++ ...staurantEnvironmentPointQueryEvent.cs.meta | 3 + .../Restaurant/Event/RestaurantEventBase.cs | 39 +++++++ .../Event/RestaurantEventBase.cs.meta | 3 + .../Restaurant/Event/RestaurantEvents.cs | 1 + .../Event/RestaurantInteractionEvents.cs | 81 +++++--------- .../FlowStates/RestaurantEnvironmentState.cs | 34 ++++++ 24 files changed, 434 insertions(+), 57 deletions(-) create mode 100644 Assets/_DDD/Restaurant/Environments/PointMarker.meta create mode 100644 Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab create mode 100644 Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs create mode 100644 Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs create mode 100644 Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs create mode 100644 Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs create mode 100644 Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs create mode 100644 Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs create mode 100644 Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs.meta create mode 100644 Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs create mode 100644 Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs.meta diff --git a/Assets/_DDD/Restaurant/Environments/PointMarker.meta b/Assets/_DDD/Restaurant/Environments/PointMarker.meta new file mode 100644 index 000000000..ee47e304f --- /dev/null +++ b/Assets/_DDD/Restaurant/Environments/PointMarker.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1f7569e20bdc77e429d3e140c38b7185 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab b/Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab new file mode 100644 index 000000000..d59e7e33b --- /dev/null +++ b/Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab @@ -0,0 +1,103 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &4103096974375017811 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3697702677815423220} + - component: {fileID: 3761059052922690693} + - component: {fileID: 7433508832753786351} + m_Layer: 7 + m_Name: PointMarker + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3697702677815423220 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4103096974375017811} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &3761059052922690693 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4103096974375017811} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 9dfc825aed78fcd4ba02077103263b40, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 21300000, guid: 22cbc31c0f91548f096d10d462447973, type: 3} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 0.41, y: 3.41} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 1 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!114 &7433508832753786351 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4103096974375017811} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 01f8d593287c4672a63146e6b4905db5, type: 3} + m_Name: + m_EditorClassIdentifier: + _pointType: 0 diff --git a/Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab.meta b/Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab.meta new file mode 100644 index 000000000..28c315929 --- /dev/null +++ b/Assets/_DDD/Restaurant/Environments/PointMarker/PointMarker.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 186d28777ccbc484780568f74c110ff7 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs new file mode 100644 index 000000000..e668ae601 --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs @@ -0,0 +1,53 @@ +using Opsive.BehaviorDesigner.Runtime.Tasks; +using Opsive.BehaviorDesigner.Runtime.Tasks.Actions; +using Unity.VisualScripting; +using UnityEngine; + +namespace DDD.Restaurant +{ + public enum EmotionType + { + Angry, + Satisfied, + } + + public class ExpressEmotion : Action + { + public interface IEmotionVisual + { + bool HasEmotionAvailable(EmotionType emotionType); + void ShowEmotion(EmotionType emotionType); + void EndEmotion(); + } + + //이를 파생해서 기본값을 주거나, 바로 사용하면 될 듯 + [SerializeField] protected string _emotionBlackboardKey; + + private IEmotionVisual _emotionVisual; + + public override void OnStart() + { + var currentEmotion = (EmotionType)m_BehaviorTree.GetVariable(_emotionBlackboardKey).Value; + + _emotionVisual = gameObject.GetComponentInChildren(); + if (_emotionVisual == null) + { + Debug.LogWarning($"[{GetType().Name}] Emotion Interface가 없습니다. 게임오브젝트 해시코드: {gameObject.GetHashCode()}"); + return; + } + + if (!_emotionVisual.HasEmotionAvailable(currentEmotion)) + { + Debug.LogWarning($"[{GetType().Name}] {nameof(currentEmotion)}이 없습니다. 게임오브젝트 해시코드: {gameObject.GetHashCode()}"); + return; + } + + _emotionVisual.ShowEmotion(currentEmotion); + } + + public override void OnEnd() + { + _emotionVisual?.EndEmotion(); + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs.meta b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs.meta new file mode 100644 index 000000000..c5ab560c0 --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/ExpressEmotion.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c30f2fbe7c3d4b05bf0cd92810314db5 +timeCreated: 1756447956 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/LookAtInteractionTarget.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/LookAtInteractionTarget.cs index 4805bfbbe..cb7b1f014 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/LookAtInteractionTarget.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/LookAtInteractionTarget.cs @@ -37,7 +37,7 @@ public override void OnStart() _isLooking = false; var blackboard = gameObject.GetComponent(); - _cachedTarget = blackboard.GetBlackboardValue(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); + _cachedTarget = m_BehaviorTree.GetVariable(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)).Value; } public override TaskStatus OnUpdate() diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs new file mode 100644 index 000000000..96fcccc6c --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs @@ -0,0 +1,33 @@ +using Opsive.BehaviorDesigner.Runtime.Tasks; +using Opsive.BehaviorDesigner.Runtime.Tasks.Actions; +using UnityEngine; + +namespace DDD.Restaurant +{ + public class SearchAndRegisterMarker : Action + { + [SerializeField] private PointType _pointType; + private string _markerBlackboardKey; + private bool _isRegistered; + + public override void OnStart() + { + var environmentState = RestaurantState.Instance?.EnvironmentState; + if (environmentState == null) return; + var pointProviders = environmentState.GetPointProviderByType(_pointType); + foreach (var pointProvider in pointProviders) + { + if (!pointProvider.IsSupportsType(_pointType)) continue; + _isRegistered = RestaurantEvents.EnvironmentPointQueryEvent.RequestEvent(gameObject, pointProvider.GetGameObject(), _pointType); + // 사실 이런 일은 없어야 함 + if (!_isRegistered) continue; + m_BehaviorTree.SetVariableValue(_markerBlackboardKey, pointProvider.GetGameObject()); + } + } + + public override TaskStatus OnUpdate() + { + return _isRegistered ? TaskStatus.Success : TaskStatus.Failure; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs.meta b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs.meta new file mode 100644 index 000000000..f4d475d9d --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Common/Actions/SearchAndRegisterMarker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cdd22f2712964a81b4a55f95c605ae13 +timeCreated: 1756454016 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs new file mode 100644 index 000000000..8ed3a21e0 --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs @@ -0,0 +1,31 @@ +using Opsive.BehaviorDesigner.Runtime.Tasks; +using Opsive.BehaviorDesigner.Runtime.Tasks.Actions; +using Opsive.GraphDesigner.Runtime; +using UnityEngine; + +namespace DDD.Restaurant +{ + public enum EvaluationStep + { + FoodSatisfactionCheck, + FavoriteTasteCheck, + } + + [NodeDescription("만족도 평가 테스크")] + public class SatisfactionEvaluator : Action + { + [SerializeField] private string _satisfactionBlackboardKey; + [SerializeField] private EvaluationStep _evaluationStep; + public override void OnStart() + { + var currentSatisfaction = CalculateSatisfaction(); + m_BehaviorTree.SetVariableValue(_satisfactionBlackboardKey, (int)currentSatisfaction); + } + + //TODO 만족도 계산? + private EmotionType CalculateSatisfaction() + { + return EmotionType.Satisfied; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs.meta b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs.meta new file mode 100644 index 000000000..3392daacc --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/SatisfactionEvaluator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9ada80a75a61473394d6ab301a4daeaf +timeCreated: 1756449593 \ No newline at end of file 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 ba29130bd..c471f6b78 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/AI/Customer/Actions/StartRestaurantOrder.cs @@ -66,7 +66,7 @@ public override TaskStatus OnUpdate() return TaskStatus.Failure; } - RestaurantEvents.InteractionEvent.RequestInteraction(_interactor.GetInteractorGameObject(), currentInteractable.GetInteractableGameObject(), currentInteractable.GetInteractionType()); + RestaurantEvents.InteractionEvent.RequestEvent(_interactor.GetInteractorGameObject(), currentInteractable.GetInteractableGameObject(), currentInteractable.GetInteractionType()); if (_targetOrderType == RestaurantOrderType.Busy) { diff --git a/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs b/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs index ee8e89e6b..1aafd2e0f 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Character/Core/CharacterInteraction.cs @@ -42,7 +42,7 @@ protected void TryInteraction(IInteractable interactable, ScriptableObject paylo var causer = gameObject; var target = interactable.GetInteractableGameObject(); var interactionType = _nearestInteractable.GetInteractionType(); - RestaurantEvents.InteractionEvent.RequestInteraction(causer, target, interactionType, payload); + RestaurantEvents.InteractionEvent.RequestEvent(causer, target, interactionType, payload); } public IInteractionSolver GetInteractionSolver(InteractionType interactionType) diff --git a/Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs b/Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs new file mode 100644 index 000000000..f09354275 --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs @@ -0,0 +1,20 @@ +using System; +using UnityEngine; +using UnityEngine.Splines; + +namespace DDD.Restaurant +{ + public enum PointType + { + Entry, + Exit, + } + + public interface IEnvironmentPointProvider + { + bool IsSupportsType(PointType pointType); + Vector3 GetPosition(); + + GameObject GetGameObject(); + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs.meta b/Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs.meta new file mode 100644 index 000000000..1f28a6279 --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Environment/IEnvironmentPointProvider.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2f01a9fb897547f4bd10c39acade7489 +timeCreated: 1756445406 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider.meta b/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider.meta new file mode 100644 index 000000000..17ce30822 --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 82eedd995f09472a9e3c6b93eeecf79f +timeCreated: 1756445877 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs b/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs new file mode 100644 index 000000000..592ca3f0f --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs @@ -0,0 +1,36 @@ +using UnityEngine; + +namespace DDD.Restaurant +{ + public class EnvironmentPointMarker : MonoBehaviour, IEnvironmentPointProvider + { + [SerializeField] PointType _pointType; + + private void Start() + { + var environmentState = RestaurantState.Instance?.EnvironmentState; + environmentState?.RegisterPointProvider(this); + } + + private void OnDisable() + { + var environmentState = RestaurantState.Instance?.EnvironmentState; + environmentState?.UnRegisterPointProvider(this); + } + + public bool IsSupportsType(PointType pointType) + { + return _pointType == pointType; + } + + public Vector3 GetPosition() + { + return transform.position; + } + + public GameObject GetGameObject() + { + return gameObject; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs.meta b/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs.meta new file mode 100644 index 000000000..044bf26ff --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Environment/PositionProvider/EnvironmentPointMarker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 01f8d593287c4672a63146e6b4905db5 +timeCreated: 1756446387 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs new file mode 100644 index 000000000..b68c26f1b --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs @@ -0,0 +1,15 @@ +using UnityEngine; + +namespace DDD.Restaurant +{ + public class RestaurantEnvironmentPointQueryEvent : RestaurantEventBase + { + protected override bool EventSolve(GameObject causer, GameObject target, PointType eventType, ScriptableObject payload) + { + if (!target.TryGetComponent(out IEnvironmentPointProvider provider)) return false; + if (!provider.IsSupportsType(eventType)) return false; + + return true; + } + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs.meta b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs.meta new file mode 100644 index 000000000..55939787b --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEnvironmentPointQueryEvent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 17b28cfc7a5a4d43a050d247e22004dc +timeCreated: 1756453073 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs new file mode 100644 index 000000000..48636f5b1 --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs @@ -0,0 +1,39 @@ +using System; +using UnityEngine; + +namespace DDD.Restaurant +{ + public abstract class RestaurantEventBase : IEvent where T : Enum + { + protected GameObject Causer; + protected GameObject Target; + protected T EventType; + protected ScriptableObject Payload; + protected bool EventResult = false; + + protected RestaurantEventBase MakeInteractionEvent(GameObject causer, GameObject target, + T eventType, + ScriptableObject payload = null) + { + Causer = causer; + Target = target; + EventType = eventType; + Payload = payload; + return this; + } + + public bool RequestEvent(GameObject causer, GameObject target, T eventType, + ScriptableObject payload = null, bool shouldBroadcastAfterSolve = true) + { + var evt = MakeInteractionEvent(causer, target, eventType, payload); + // Solve event directly. 이벤트 처리는 여기서 하고, 이벤트 호출로는 이런 이벤트가 호출되었고 결과가 어떻다는 거 전파하는 식으로. + evt.EventResult = EventSolve(causer, target, eventType, payload); + + EventBus.Broadcast(evt); // 이벤트 결과를 이거 받아서 처리하면 될듯. + return evt.EventResult; + } + + protected abstract bool EventSolve(GameObject causer, GameObject target, T eventType, + ScriptableObject payload); + } +} \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs.meta b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs.meta new file mode 100644 index 000000000..7803a8d5b --- /dev/null +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fa6f80fbb0ca4c2ba33616a9f070bced +timeCreated: 1756452619 \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEvents.cs b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEvents.cs index 19d3c4f8c..b135bcc60 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEvents.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEvents.cs @@ -9,6 +9,7 @@ public static class RestaurantEvents public static TodayMenuRemovedEvent TodayMenuRemovedEvent = new(); public static RestaurantInteractionEvent InteractionEvent = new(); + public static RestaurantEnvironmentPointQueryEvent EnvironmentPointQueryEvent = new(); } #region RestaurantInteractionEvents diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs index f006c3e85..c0924b4d5 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs @@ -8,74 +8,47 @@ public static class RestaurantInteractionEventSolvers { public static Dictionary TypeToSolver = new() { - {InteractionType.RestaurantManagement, typeof(RestaurantManagementSolver)}, - {InteractionType.RestaurantOrder, typeof(RestaurantOrderSolver)}, - {InteractionType.RestaurantCook, typeof(RestaurantCookSolver)} + { InteractionType.RestaurantManagement, typeof(RestaurantManagementSolver) }, + { InteractionType.RestaurantOrder, typeof(RestaurantOrderSolver) }, + { InteractionType.RestaurantCook, typeof(RestaurantCookSolver) } }; + public static Dictionary TypeToPlayerSolver = new() { - {InteractionType.RestaurantOrder, typeof(RestaurantOrderPlayerSolver)}, + { InteractionType.RestaurantOrder, typeof(RestaurantOrderPlayerSolver) }, }; } - - public class RestaurantInteractionEvent : IEvent + + public class RestaurantInteractionEvent : RestaurantEventBase { - public GameObject Causer; - public GameObject Target; - public InteractionType InteractionType; - public ScriptableObject Payload; - public bool EventResult = false; - - public RestaurantInteractionEvent MakeInteractionEvent(GameObject causer, GameObject target, InteractionType interactionType, - ScriptableObject payload = null) + protected override bool EventSolve(GameObject causer, GameObject target, InteractionType interactionType, + ScriptableObject payload) { - Causer = causer; - Target = target; - InteractionType = interactionType; - Payload = payload; - return this; - } - - public bool RequestInteraction(GameObject causer, GameObject target, InteractionType interactionType, - ScriptableObject payload = null, bool shouldBroadcastAfterSolve = true) - { - if (interactionType == InteractionType.None) + if (!RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(interactionType, out var solverType)) { return false; } - - var evt = MakeInteractionEvent(causer, target, interactionType, payload); - evt.EventResult = false; - // Solve event directly. 이벤트 처리는 여기서 하고, 이벤트 호출로는 이런 이벤트가 호출되었고 결과가 어떻다는 거 전파하는 식으로. - if (RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(interactionType, out var solverType)) + + Component solverComponent = causer.GetComponent(solverType); + IInteractionSolver solver = solverComponent as IInteractionSolver; + IInteractor interactor = causer.GetComponent(); + IInteractable interactable = target.GetComponent(); + + // Cast solverComponent to IInteractable + if (solver is not null && interactor is not null) { - Component solverComponent = causer.GetComponent(solverType); - IInteractionSolver solver = solverComponent as IInteractionSolver; - IInteractor interactor = causer.GetComponent(); - IInteractable interactable = target.GetComponent(); + bool canExecute = solver.CanExecuteInteraction(interactor, interactable, payload); + if (canExecute) + { + return solver.ExecuteInteraction(interactor, interactable, payload); + } - // Cast solverComponent to IInteractable - if (solver is not null && interactor is not null) - { - bool canExecute = solver.CanExecuteInteraction(interactor, interactable, payload); - if (canExecute) - { - evt.EventResult = solver.ExecuteInteraction(interactor, interactable, payload); - } - else - { - evt.EventResult = false; - } - } - else - { - // Should not reach here! - Debug.Assert(false, "Solver Component or Interactor is null"); - } + return false; } - EventBus.Broadcast(evt);// 이벤트 결과를 이거 받아서 처리하면 될듯. - return evt.EventResult; + // Should not reach here! + Debug.Assert(false, "Solver Component or Interactor is null"); + return false; } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantEnvironmentState.cs b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantEnvironmentState.cs index afb94720d..e860b3463 100644 --- a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantEnvironmentState.cs +++ b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantEnvironmentState.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using DDD.Restaurant; using UnityEngine; namespace DDD @@ -24,6 +25,7 @@ public class RestaurantEnvironmentState : ScriptableObject // 인터랙션 가능한 객체(IInteractable)를 관리하기 위한 리스트 (런타임 전용) private readonly List _registeredInteractables = new List(); + private readonly List _registeredPointProviders = new List(); /// /// 인터랙션 가능한 객체를 등록합니다 @@ -35,6 +37,13 @@ public void RegisterInteractable(IInteractable interactable) _registeredInteractables.Add(interactable); } + public void RegisterPointProvider(IEnvironmentPointProvider provider) + { + if (provider == null) return; + if (_registeredPointProviders.Contains(provider)) return; + _registeredPointProviders.Add(provider); + } + /// /// 인터랙션 가능한 객체를 해제합니다 /// @@ -44,6 +53,12 @@ public void UnregisterInteractable(IInteractable interactable) _registeredInteractables.Remove(interactable); } + public void UnRegisterPointProvider(IEnvironmentPointProvider provider) + { + if (provider == null) return; + _registeredPointProviders.Remove(provider); + } + /// /// 특정 InteractionType에 해당하는 인터랙션 객체들을 반환합니다 /// @@ -61,6 +76,19 @@ public List GetInteractablesByType(InteractionType interactionTyp } return result; } + + public List GetPointProviderByType(PointType pointType) + { + var result = new List(); + // null 또는 Destroyed 오브젝트 정리 + _registeredPointProviders.RemoveAll(item => item == null || (item as UnityEngine.Object) == null); + foreach (var provider in _registeredPointProviders) + { + if (!provider.IsSupportsType(pointType)) continue; + result.Add(provider); + } + return result; + } /// /// 모든 등록된 인터랙션 객체들을 반환합니다 @@ -70,5 +98,11 @@ public List GetAllInteractables() _registeredInteractables.RemoveAll(item => item == null || (item as UnityEngine.Object) == null); return new List(_registeredInteractables); } + + public List GetAllPointProviders() + { + _registeredPointProviders.RemoveAll(item => item == null || (item as UnityEngine.Object) == null); + return new List(_registeredPointProviders); + } } } \ No newline at end of file