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