Exit, Entry 이벤트 추가, emotion 표현 액션, 만족도 평가 액션, 마커 탐색-등록 액션 추가, 마커 컴포넌트 추가
This commit is contained in:
parent
f9bb1fb262
commit
36cfe1d923
8
Assets/_DDD/Restaurant/Environments/PointMarker.meta
Normal file
8
Assets/_DDD/Restaurant/Environments/PointMarker.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f7569e20bdc77e429d3e140c38b7185
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 186d28777ccbc484780568f74c110ff7
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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<int>(_emotionBlackboardKey).Value;
|
||||
|
||||
_emotionVisual = gameObject.GetComponentInChildren<IEmotionVisual>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c30f2fbe7c3d4b05bf0cd92810314db5
|
||||
timeCreated: 1756447956
|
@ -37,7 +37,7 @@ public override void OnStart()
|
||||
_isLooking = false;
|
||||
|
||||
var blackboard = gameObject.GetComponent<IAISharedBlackboard>();
|
||||
_cachedTarget = blackboard.GetBlackboardValue<GameObject>(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget));
|
||||
_cachedTarget = m_BehaviorTree.GetVariable<GameObject>(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)).Value;
|
||||
}
|
||||
|
||||
public override TaskStatus OnUpdate()
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdd22f2712964a81b4a55f95c605ae13
|
||||
timeCreated: 1756454016
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ada80a75a61473394d6ab301a4daeaf
|
||||
timeCreated: 1756449593
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2f01a9fb897547f4bd10c39acade7489
|
||||
timeCreated: 1756445406
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82eedd995f09472a9e3c6b93eeecf79f
|
||||
timeCreated: 1756445877
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01f8d593287c4672a63146e6b4905db5
|
||||
timeCreated: 1756446387
|
@ -0,0 +1,15 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
public class RestaurantEnvironmentPointQueryEvent : RestaurantEventBase<PointType>
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17b28cfc7a5a4d43a050d247e22004dc
|
||||
timeCreated: 1756453073
|
39
Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs
Normal file
39
Assets/_DDD/_Scripts/Restaurant/Event/RestaurantEventBase.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD.Restaurant
|
||||
{
|
||||
public abstract class RestaurantEventBase<T> : IEvent where T : Enum
|
||||
{
|
||||
protected GameObject Causer;
|
||||
protected GameObject Target;
|
||||
protected T EventType;
|
||||
protected ScriptableObject Payload;
|
||||
protected bool EventResult = false;
|
||||
|
||||
protected RestaurantEventBase<T> 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa6f80fbb0ca4c2ba33616a9f070bced
|
||||
timeCreated: 1756452619
|
@ -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
|
||||
|
@ -8,74 +8,47 @@ public static class RestaurantInteractionEventSolvers
|
||||
{
|
||||
public static Dictionary<InteractionType, Type> 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<InteractionType, Type> TypeToPlayerSolver = new()
|
||||
{
|
||||
{InteractionType.RestaurantOrder, typeof(RestaurantOrderPlayerSolver)},
|
||||
{ InteractionType.RestaurantOrder, typeof(RestaurantOrderPlayerSolver) },
|
||||
};
|
||||
}
|
||||
|
||||
public class RestaurantInteractionEvent : IEvent
|
||||
|
||||
public class RestaurantInteractionEvent : RestaurantEventBase<InteractionType>
|
||||
{
|
||||
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<IInteractor>();
|
||||
IInteractable interactable = target.GetComponent<IInteractable>();
|
||||
|
||||
// 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<IInteractor>();
|
||||
IInteractable interactable = target.GetComponent<IInteractable>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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<IInteractable> _registeredInteractables = new List<IInteractable>();
|
||||
private readonly List<IEnvironmentPointProvider> _registeredPointProviders = new List<IEnvironmentPointProvider>();
|
||||
|
||||
/// <summary>
|
||||
/// 인터랙션 가능한 객체를 등록합니다
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 인터랙션 가능한 객체를 해제합니다
|
||||
/// </summary>
|
||||
@ -44,6 +53,12 @@ public void UnregisterInteractable(IInteractable interactable)
|
||||
_registeredInteractables.Remove(interactable);
|
||||
}
|
||||
|
||||
public void UnRegisterPointProvider(IEnvironmentPointProvider provider)
|
||||
{
|
||||
if (provider == null) return;
|
||||
_registeredPointProviders.Remove(provider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 InteractionType에 해당하는 인터랙션 객체들을 반환합니다
|
||||
/// </summary>
|
||||
@ -61,6 +76,19 @@ public List<IInteractable> GetInteractablesByType(InteractionType interactionTyp
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<IEnvironmentPointProvider> GetPointProviderByType(PointType pointType)
|
||||
{
|
||||
var result = new List<IEnvironmentPointProvider>();
|
||||
// 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모든 등록된 인터랙션 객체들을 반환합니다
|
||||
@ -70,5 +98,11 @@ public List<IInteractable> GetAllInteractables()
|
||||
_registeredInteractables.RemoveAll(item => item == null || (item as UnityEngine.Object) == null);
|
||||
return new List<IInteractable>(_registeredInteractables);
|
||||
}
|
||||
|
||||
public List<IEnvironmentPointProvider> GetAllPointProviders()
|
||||
{
|
||||
_registeredPointProviders.RemoveAll(item => item == null || (item as UnityEngine.Object) == null);
|
||||
return new List<IEnvironmentPointProvider>(_registeredPointProviders);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user