상호작용 로직 수정
This commit is contained in:
parent
78ca575910
commit
f02fe591dc
@ -4,8 +4,9 @@ namespace DDD
|
||||
{
|
||||
public enum InteractionType
|
||||
{
|
||||
None,
|
||||
None = 0,
|
||||
RestaurantManagementUi,
|
||||
OpenRestaurant,
|
||||
Count
|
||||
}
|
||||
public interface IInteractable
|
||||
@ -26,6 +27,6 @@ public interface IInteractor
|
||||
public interface IInteractionSolver
|
||||
{
|
||||
bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject interactionPayloadSo = null);
|
||||
bool CanInteract();
|
||||
bool CanExecuteInteraction();
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ private void OnInteractPerformed(InputAction.CallbackContext context)
|
||||
|
||||
private void OnInteractCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
OnInteractionHoldProgress(0f);
|
||||
ResetInteractionState();
|
||||
}
|
||||
|
||||
@ -74,10 +75,7 @@ protected override void OnNearestInteractableChanged(IInteractable newTarget)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isInteracting == false)
|
||||
{
|
||||
EventBus.Broadcast(GameEvents.HideInteractionUiEvent);
|
||||
}
|
||||
EventBus.Broadcast(GameEvents.HideInteractionUiEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
@ -16,6 +17,7 @@ public class RestaurantCharacterInteraction : MonoBehaviour, IInteractor, IEvent
|
||||
|
||||
protected float _interactionRadius = 1f;
|
||||
protected LayerMask _interactionLayerMask = (LayerMask)(-1);
|
||||
private Dictionary<InteractionType, IInteractionSolver> _cachedSolvers = new();
|
||||
|
||||
protected virtual void Start() { }
|
||||
|
||||
@ -63,37 +65,54 @@ protected virtual void OnInteractionCompleted() { }
|
||||
protected void ResetInteractionState()
|
||||
{
|
||||
_isInteracting = false;
|
||||
_interactingTarget = null;
|
||||
_interactHeldTime = 0f;
|
||||
OnInteractionHoldProgress(0f);
|
||||
_interactingTarget = null;
|
||||
}
|
||||
|
||||
protected IInteractable GetNearestInteractable()
|
||||
{
|
||||
int nearColliderCount = Physics.OverlapSphereNonAlloc(transform.position, _interactionRadius,
|
||||
_nearColliders, _interactionLayerMask, QueryTriggerInteraction.Collide);
|
||||
int colliderCount = Physics.OverlapSphereNonAlloc(transform.position, _interactionRadius, _nearColliders, _interactionLayerMask);
|
||||
float closestDistance = float.MaxValue;
|
||||
IInteractable closest = null;
|
||||
|
||||
IInteractable nearest = null;
|
||||
float minSqrDistance = float.MaxValue;
|
||||
|
||||
for (int i = 0; i < nearColliderCount; i++)
|
||||
for (int i = 0; i < colliderCount; i++)
|
||||
{
|
||||
var interactable = _nearColliders[i].GetComponent<IInteractable>();
|
||||
if (interactable == null || !interactable.CanInteract()) continue;
|
||||
var col = _nearColliders[i];
|
||||
if (col.TryGetComponent<IInteractable>(out var interactable) == false || interactable.CanInteract() == false) continue;
|
||||
|
||||
float sqrDistance = (interactable.GetInteractableGameObject().transform.position - transform.position).sqrMagnitude;
|
||||
if (sqrDistance < minSqrDistance)
|
||||
var type = interactable.GetInteractionType();
|
||||
if (ContainTypeToSolver(type, out var solver) == false || solver.CanExecuteInteraction() == false) continue;
|
||||
|
||||
float distance = Vector3.Distance(transform.position, col.transform.position);
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
minSqrDistance = sqrDistance;
|
||||
nearest = interactable;
|
||||
closestDistance = distance;
|
||||
closest = interactable;
|
||||
}
|
||||
}
|
||||
|
||||
return nearest;
|
||||
return closest;
|
||||
}
|
||||
|
||||
public virtual void Invoke(RestaurantInteractionEvent evt) { }
|
||||
|
||||
public GameObject GetInteractorGameObject() => gameObject;
|
||||
|
||||
private bool ContainTypeToSolver(InteractionType type, out IInteractionSolver solver)
|
||||
{
|
||||
if (_cachedSolvers.TryGetValue(type, out solver)) return solver != null;
|
||||
|
||||
solver = null;
|
||||
|
||||
if (!RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(type, out var solverType)) return false;
|
||||
|
||||
if (!TryGetComponent(solverType, out var component)) return false;
|
||||
|
||||
solver = component as IInteractionSolver;
|
||||
_cachedSolvers[type] = solver;
|
||||
|
||||
return solver != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ public static class RestaurantInteractionEventSolvers
|
||||
{
|
||||
public static Dictionary<InteractionType, Type> TypeToSolver = new()
|
||||
{
|
||||
{InteractionType.RestaurantManagementUi, typeof(RestaurantManagementUiEventSolver)}
|
||||
{InteractionType.RestaurantManagementUi, typeof(RestaurantManagementUiEventSolver)},
|
||||
{InteractionType.OpenRestaurant, typeof(RestaurantOpenEventSolver)}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ public class RestaurantManagementUiEventSolver : MonoBehaviour, IInteractionSolv
|
||||
{
|
||||
public bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject interactionPayloadSo = null)
|
||||
{
|
||||
if (CanInteract() == false) return false;
|
||||
if (CanExecuteInteraction() == false) return false;
|
||||
|
||||
var evt = GameEvents.OpenPopupUiEvent;
|
||||
evt.UiType = typeof(RestaurantManagementUi);
|
||||
@ -14,7 +14,7 @@ public bool ExecuteInteraction(IInteractor interactor, IInteractable interactabl
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanInteract()
|
||||
public bool CanExecuteInteraction()
|
||||
{
|
||||
GameFlowState currentGameFlowState = GameFlowManager.Instance.GameFlowDataSo.CurrentGameState;
|
||||
return currentGameFlowState == GameFlowState.ReadyForRestaurant;
|
||||
|
@ -1,23 +1,34 @@
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public class RestaurantOpenEventSolver : MonoBehaviour, IInteractionSolver
|
||||
{
|
||||
private RestaurantManagementSo _restaurantManagementSo;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_ = Initialize();
|
||||
}
|
||||
|
||||
private async Task Initialize()
|
||||
{
|
||||
_restaurantManagementSo = await AssetManager.LoadAsset<RestaurantManagementSo>(DataConstants.RestaurantManagementSo);
|
||||
}
|
||||
|
||||
public bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject interactionPayloadSo = null)
|
||||
{
|
||||
if (CanInteract() == false) return false;
|
||||
if (CanExecuteInteraction() == false) return false;
|
||||
|
||||
GameFlowManager.Instance.ChangeFlow(GameFlowState.RunRestaurant);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanInteract()
|
||||
public bool CanExecuteInteraction()
|
||||
{
|
||||
// TODO : 영업 가능한 상태인지 조건 추가 (최소 요리, 요리도구 배치 등)
|
||||
|
||||
GameFlowState currentGameFlowState = GameFlowManager.Instance.GameFlowDataSo.CurrentGameState;
|
||||
return currentGameFlowState == GameFlowState.ReadyForRestaurant;
|
||||
return currentGameFlowState == GameFlowState.ReadyForRestaurant && _restaurantManagementSo.IsOpenable();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user