중첩상태 제거 및 플레이어-손님 OrderSolver 분배, 초기화 부분 리팩토링

This commit is contained in:
김산 2025-08-28 12:43:32 +09:00
parent 60205d3c00
commit 61fd509c96
12 changed files with 64 additions and 35 deletions

Binary file not shown.

Binary file not shown.

View File

@ -426,7 +426,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 81e01dd8c1cc3404d805400eba1bb4ae, type: 3} m_Script: {fileID: 11500000, guid: 81e01dd8c1cc3404d805400eba1bb4ae, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_availableInteractions: 5 _availableInteractions: 7
_nearColliders: _nearColliders:
- {fileID: 0} - {fileID: 0}
- {fileID: 0} - {fileID: 0}

View File

@ -10,7 +10,6 @@ public enum InteractionType : uint
None = 0u, None = 0u,
RestaurantManagement = 1u << 0, RestaurantManagement = 1u << 0,
RestaurantOrder = 1u << 1, RestaurantOrder = 1u << 1,
RestaurantMeal = 1u << 2,
RestaurantCook = 1u << 3, RestaurantCook = 1u << 3,
All = 0xFFFFFFFFu All = 0xFFFFFFFFu
} }

View File

@ -12,11 +12,7 @@ public class LookAtInteractionTarget : Action
{ {
[Header("Target Settings")] [Header("Target Settings")]
[Tooltip("InteractionPoints를 사용해 가장 적절한 지점을 바라봄")] [Tooltip("InteractionPoints를 사용해 가장 적절한 지점을 바라봄")]
[SerializeField] private bool useInteractionPoints = true; [SerializeField] private bool _useInteractionPoints = true;
[Header("Update Settings")]
[Tooltip("프레임마다 갱신하여 지속적으로 바라볼지 (Running 반환) 여부. 비활성화 시 1회만 시도하고 성공 처리")]
[SerializeField] private bool continuousUpdate = true;
// Visual 전용 컴포넌트(나중 구현)를 위한 최소 인터페이스 // Visual 전용 컴포넌트(나중 구현)를 위한 최소 인터페이스
// 실제 구현은 Spine/애니메이션 제어 컴포넌트에서 이 인터페이스를 구현하세요. // 실제 구현은 Spine/애니메이션 제어 컴포넌트에서 이 인터페이스를 구현하세요.
@ -69,8 +65,7 @@ public override TaskStatus OnUpdate()
_visual?.UpdateLookAt(_currentLookPosition); _visual?.UpdateLookAt(_currentLookPosition);
} }
// 연속 업데이트면 Running, 아니면 1회만 시도 후 Success 반환 return TaskStatus.Success;
return continuousUpdate ? TaskStatus.Running : TaskStatus.Success;
} }
public override void OnEnd() public override void OnEnd()
@ -87,7 +82,7 @@ public override void OnEnd()
private Vector3 CalculateLookPosition(GameObject target) private Vector3 CalculateLookPosition(GameObject target)
{ {
if (!useInteractionPoints) if (!_useInteractionPoints)
return target.transform.position; return target.transform.position;
if (target.TryGetComponent<RestaurantInteractionComponent>(out var ric)) if (target.TryGetComponent<RestaurantInteractionComponent>(out var ric))

View File

@ -8,15 +8,12 @@ namespace DDD.Restaurant
//차후 제네릭으로 변경 가능성 있음 //차후 제네릭으로 변경 가능성 있음
public class WaitForPlayerInteraction : Action public class WaitForPlayerInteraction : Action
{ {
[Tooltip("기다릴 상호작용 타입")] [SerializeField] private RestaurantOrderType _targetOrderType;
[SerializeField] private RestaurantMealType _targetOrderType = RestaurantMealType.WaitForOrder; private IInteractionSubsystemObject<RestaurantOrderType> _interactionSubsystem;
private IInteractionSubsystemObject<RestaurantMealType> _interactionSubsystem;
private bool _isGetInteractionSubsystem; private bool _isGetInteractionSubsystem;
public override void OnStart() public override void OnStart()
{ {
// 의자가 복합 상태를 가지게 될 경우
GameObject interactionTarget = null; GameObject interactionTarget = null;
if(!gameObject.TryGetComponent<IAISharedBlackboard>(out var sharedBlackboard)) return; if(!gameObject.TryGetComponent<IAISharedBlackboard>(out var sharedBlackboard)) return;
interactionTarget = sharedBlackboard.GetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget)); interactionTarget = sharedBlackboard.GetBlackboardGameObject(nameof(RestaurantCustomerBlackboardKey.CurrentInteractionTarget));

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using UnityEngine; using UnityEngine;
@ -99,5 +100,27 @@ public bool CanInteractTo(IInteractable interactable, ScriptableObject payloadSo
if (TryGetSolverFor(interactable, out var solver) == false) return false; if (TryGetSolverFor(interactable, out var solver) == false) return false;
return solver.CanExecuteInteraction(this, interactable, payloadSo); return solver.CanExecuteInteraction(this, interactable, payloadSo);
} }
public virtual void InitializeSolvers()
{
var typesToSolver = RestaurantInteractionEventSolvers.TypeToSolver;
InitializeInteractionSolvers(typesToSolver);
}
protected void InitializeInteractionSolvers(Dictionary<InteractionType, Type> typesToSolver)
{
foreach (var typeToSolver in typesToSolver)
{
var flag = typeToSolver.Key;
if (flag == InteractionType.None) continue;
if ((AvailableInteractions & flag) == 0) continue;
if (!TryGetComponent(typeToSolver.Value, out _))
{
gameObject.AddComponent(typeToSolver.Value);
}
}
}
} }
} }

View File

@ -13,19 +13,8 @@ public class RestaurantCharacter : MonoBehaviour, IGameCharacter, IInteractor
protected virtual void Awake() protected virtual void Awake()
{ {
_interactionComponent = GetComponent<CharacterInteraction>(); _interactionComponent = GetComponent<CharacterInteraction>();
_interactionComponent.InitializeSolvers();
_spineController = GetComponent<SpineController>(); _spineController = GetComponent<SpineController>();
foreach (var typeToSolver in RestaurantInteractionEventSolvers.TypeToSolver)
{
var flag = typeToSolver.Key;
if (flag == InteractionType.None) continue;
if ((_interactionComponent.AvailableInteractions & flag) == 0) continue;
if (!TryGetComponent(typeToSolver.Value, out _))
{
gameObject.AddComponent(typeToSolver.Value);
}
}
} }
protected virtual void Start() protected virtual void Start()

View File

@ -1,3 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
@ -35,6 +37,18 @@ private Task Initialize()
return Task.CompletedTask; return Task.CompletedTask;
} }
public override void InitializeSolvers()
{
var typesToSolver = RestaurantInteractionEventSolvers.TypeToSolver;
var playerSolver = RestaurantInteractionEventSolvers.TypeToPlayerSolver;
foreach(var pair in playerSolver)
{
typesToSolver.Remove(pair.Key);
}
InitializeInteractionSolvers(typesToSolver);
InitializeInteractionSolvers(playerSolver);
}
protected override void OnDestroy() protected override void OnDestroy()
{ {
base.OnDestroy(); base.OnDestroy();

View File

@ -13,7 +13,6 @@ public static class RestaurantInteractionSubsystems
{ {
{InteractionType.RestaurantOrder, typeof(InteractionSubsystem_Order)}, {InteractionType.RestaurantOrder, typeof(InteractionSubsystem_Order)},
{InteractionType.RestaurantManagement, typeof(InteractionSubsystem_Management)}, {InteractionType.RestaurantManagement, typeof(InteractionSubsystem_Management)},
{InteractionType.RestaurantMeal, typeof(InteractionSubsystem_Meal)}
}; };
} }

View File

@ -10,9 +10,12 @@ public static class RestaurantInteractionEventSolvers
{ {
{InteractionType.RestaurantManagement, typeof(RestaurantManagementSolver)}, {InteractionType.RestaurantManagement, typeof(RestaurantManagementSolver)},
{InteractionType.RestaurantOrder, typeof(RestaurantOrderSolver)}, {InteractionType.RestaurantOrder, typeof(RestaurantOrderSolver)},
{InteractionType.RestaurantMeal, typeof(RestaurantMealSolver)},
{InteractionType.RestaurantCook, typeof(RestaurantCookSolver)} {InteractionType.RestaurantCook, typeof(RestaurantCookSolver)}
}; };
public static Dictionary<InteractionType, Type> TypeToPlayerSolver = new()
{
{InteractionType.RestaurantOrder, typeof(RestaurantOrderPlayerSolver)},
};
} }
public class RestaurantInteractionEvent : IEvent public class RestaurantInteractionEvent : IEvent

View File

@ -10,9 +10,19 @@ public class RestaurantOrderSolver : RestaurantSubsystemSolver<RestaurantOrderTy
{ {
{ RestaurantOrderType.Wait, typeof(RestaurantOrderSolver_Wait) }, { RestaurantOrderType.Wait, typeof(RestaurantOrderSolver_Wait) },
{ RestaurantOrderType.Reserved, typeof(RestaurantOrderSolver_Reserved) }, { RestaurantOrderType.Reserved, typeof(RestaurantOrderSolver_Reserved) },
{ RestaurantOrderType.Busy, typeof(RestaurantOrderSolver_Busy) },
};
protected override Dictionary<RestaurantOrderType, Type> GetSubsystemSolverTypeMappings()
{
return _typeToOrderSolver;
}
}
public class RestaurantOrderPlayerSolver : RestaurantSubsystemSolver<RestaurantOrderType>
{
private Dictionary<RestaurantOrderType, Type> _typeToOrderSolver = new()
{
{ RestaurantOrderType.Order, typeof(RestaurantOrderSolver_Order) }, { 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) } { RestaurantOrderType.Dirty, typeof(RestaurantOrderSolver_Dirty) }
}; };
protected override Dictionary<RestaurantOrderType, Type> GetSubsystemSolverTypeMappings() protected override Dictionary<RestaurantOrderType, Type> GetSubsystemSolverTypeMappings()