DDD-76 상호작용 로직 수정 및 상호작용 오브젝트 테스트 완료
This commit is contained in:
parent
ab7b77c9c8
commit
f825d4f56b
@ -77,7 +77,7 @@ public class InventoryChangedEvent : IEvent
|
||||
public int NewCount;
|
||||
}
|
||||
|
||||
#region RestaurantEvents
|
||||
#region RestaurantInteractionEvents
|
||||
|
||||
public class ItemSlotSelectedEvent : IEvent
|
||||
{
|
||||
|
@ -1,4 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
@ -6,7 +5,7 @@ namespace DDD
|
||||
public enum InteractionType
|
||||
{
|
||||
None,
|
||||
RestaurantManagement,
|
||||
RestaurantManagementUi,
|
||||
Count
|
||||
}
|
||||
public interface IInteractable
|
||||
@ -16,6 +15,7 @@ public interface IInteractable
|
||||
InteractionType GetInteractionType();
|
||||
GameObject GetInteractableGameObject();
|
||||
void InitializeInteraction(InteractionType interactionType);
|
||||
float GetRequiredHoldTime();
|
||||
}
|
||||
public interface IInteractor
|
||||
{
|
||||
@ -24,6 +24,6 @@ public interface IInteractor
|
||||
|
||||
public interface IInteractionSolver
|
||||
{
|
||||
bool ExecuteInteraction(IInteractor interactor, ScriptableObject interactionPayloadSo = null);
|
||||
bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject interactionPayloadSo = null);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,8 @@ public enum RestaurantActions
|
||||
None = 0,
|
||||
Move = 1 << 0,
|
||||
Dash = 1 << 1,
|
||||
OpenManagementUi = 1 << 2,
|
||||
Interact = 1 << 2,
|
||||
OpenManagementUi = 1 << 3,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
@ -1,5 +1,3 @@
|
||||
using DDD.RestaurantEvent;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
@ -8,13 +6,12 @@ public class RestaurantCharacter : MonoBehaviour, IGameCharacter, IInteractor
|
||||
{
|
||||
private void Start()
|
||||
{
|
||||
//TODO_IMPLEMENT_ME();
|
||||
// TODO : Add event solvers dynamically
|
||||
for (int i = (int)InteractionType.Count; i < (int)InteractionType.Count; i++)
|
||||
for (int i = 0; i < (int)InteractionType.Count; i++)
|
||||
{
|
||||
InteractionType interactionType = (InteractionType)i;
|
||||
// TODO : if this character should handle the interaction?
|
||||
if(RestaurantEventSolvers.TypeToSolver.TryGetValue(interactionType, out var solverType))
|
||||
if (RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(interactionType, out var solverType))
|
||||
{
|
||||
gameObject.AddComponent(solverType);
|
||||
}
|
||||
@ -23,8 +20,7 @@ private void Start()
|
||||
|
||||
public GameObject GetInteractorGameObject()
|
||||
{
|
||||
// TODO : TODO_IMPLEMENT_ME
|
||||
return null;
|
||||
return gameObject;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +1,65 @@
|
||||
using DDD.RestaurantEvent;
|
||||
using System.Threading.Tasks;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public class RestaurantCharacterInteraction : MonoBehaviour, IInteractor, IEventHandler<RestaurantInteractionEvent>
|
||||
{
|
||||
private RestaurantPlayerDataSo _restaurantPlayerDataSo;
|
||||
|
||||
[ReadOnly, SerializeField] private Collider[] _nearColliders = new Collider[10];
|
||||
private IInteractable _nearestInteractable;
|
||||
|
||||
private float _interactHeldTime;
|
||||
private bool _isInteracting;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
EventBus.Register(this);
|
||||
_ = Initialize();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_restaurantPlayerDataSo) return;
|
||||
|
||||
_nearestInteractable = GetNearestInteractable();
|
||||
|
||||
if (_isInteracting && _nearestInteractable != null)
|
||||
{
|
||||
_interactHeldTime += Time.deltaTime;
|
||||
|
||||
if (_interactHeldTime >= _nearestInteractable.GetRequiredHoldTime())
|
||||
{
|
||||
_isInteracting = false;
|
||||
_nearestInteractable.OnInteracted(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
EventBus.Unregister<RestaurantInteractionEvent>(this);
|
||||
|
||||
if (_restaurantPlayerDataSo)
|
||||
{
|
||||
_restaurantPlayerDataSo.InteractAction.performed -= OnInteractPerformed;
|
||||
_restaurantPlayerDataSo.InteractAction.canceled -= OnInteractCanceled;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Initialize()
|
||||
{
|
||||
_restaurantPlayerDataSo = await AssetManager.LoadAsset<RestaurantPlayerDataSo>(DataConstants.RestaurantPlayerDataSo);
|
||||
Debug.Assert(_restaurantPlayerDataSo != null, "_restaurantPlayerDataSo is null");
|
||||
|
||||
_restaurantPlayerDataSo.InteractAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Interact));
|
||||
|
||||
_restaurantPlayerDataSo.InteractAction.performed += OnInteractPerformed;
|
||||
_restaurantPlayerDataSo.InteractAction.canceled += OnInteractCanceled;
|
||||
|
||||
EventBus.Register<RestaurantInteractionEvent>(this);
|
||||
}
|
||||
|
||||
public void Invoke(RestaurantInteractionEvent evt)
|
||||
@ -17,8 +69,54 @@ public void Invoke(RestaurantInteractionEvent evt)
|
||||
|
||||
public GameObject GetInteractorGameObject()
|
||||
{
|
||||
// TODO : TODO_IMPLEMENT_ME
|
||||
return null;
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
private void OnInteractPerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
if (_nearestInteractable == null || _nearestInteractable.CanInteract() == false) return;
|
||||
|
||||
float requiredHoldTime = _nearestInteractable.GetRequiredHoldTime();
|
||||
|
||||
if (requiredHoldTime <= 0f)
|
||||
{
|
||||
_nearestInteractable.OnInteracted(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_isInteracting = true;
|
||||
_interactHeldTime = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInteractCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
_isInteracting = false;
|
||||
_interactHeldTime = 0f;
|
||||
}
|
||||
|
||||
private IInteractable GetNearestInteractable()
|
||||
{
|
||||
int nearColliderCount = Physics.OverlapSphereNonAlloc(transform.position, _restaurantPlayerDataSo.InteractionRadius,
|
||||
_nearColliders, _restaurantPlayerDataSo.InteractionLayerMask, QueryTriggerInteraction.Collide);
|
||||
|
||||
IInteractable nearestInteractable = null;
|
||||
float minDistance = float.MaxValue;
|
||||
|
||||
for (int i = 0; i < nearColliderCount; i++)
|
||||
{
|
||||
var interactable = _nearColliders[i].GetComponent<IInteractable>();
|
||||
if (interactable == null || interactable.CanInteract() == false) continue;
|
||||
|
||||
float sqrMagnitude = (interactable.GetInteractableGameObject().transform.position - transform.position).sqrMagnitude;
|
||||
if (sqrMagnitude > minDistance) continue;
|
||||
|
||||
nearestInteractable = interactable;
|
||||
minDistance = sqrMagnitude;
|
||||
}
|
||||
|
||||
print(nearestInteractable?.GetInteractableGameObject().name);
|
||||
return nearestInteractable;
|
||||
}
|
||||
}
|
||||
}
|
@ -28,6 +28,9 @@ public class RestaurantPlayerDataSo : ScriptableObject
|
||||
public float BoxCastExtentScale = 0.95f;
|
||||
public float MinSlideFactorThreshold = 0.05f;
|
||||
|
||||
public float InteractionRadius = 1f;
|
||||
public LayerMask InteractionLayerMask;
|
||||
|
||||
// 디버그
|
||||
public int InputLineSortingOrder = 10;
|
||||
public int VelocityLineSortingOrder = 9;
|
||||
@ -41,6 +44,7 @@ public class RestaurantPlayerDataSo : ScriptableObject
|
||||
|
||||
public InputAction MoveAction;
|
||||
public InputAction DashAction;
|
||||
public InputAction InteractAction;
|
||||
public InputAction OpenManagementUiAction;
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
using DDD.RestaurantEvent;
|
||||
using Spine.Unity;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
|
@ -1,13 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD.RestaurantEvent
|
||||
{
|
||||
public class RestaurantManagementEventSolver : MonoBehaviour, IInteractionSolver
|
||||
{
|
||||
public bool ExecuteInteraction(IInteractor interactor, ScriptableObject interactionPayloadSo = null)
|
||||
{
|
||||
// TODO : TODO_IMPLEMENT_ME
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD.RestaurantEvent
|
||||
namespace DDD
|
||||
{
|
||||
public class RestaurantInteractionComponent : MonoBehaviour, IInteractable
|
||||
{
|
||||
[SerializeField] private InteractionType _interactionType = InteractionType.None;
|
||||
[SerializeField] private float _holdTime = 1f;
|
||||
|
||||
public bool CanInteract()
|
||||
{
|
||||
return true;
|
||||
@ -15,27 +18,29 @@ public bool OnInteracted(IInteractor interactor, ScriptableObject interactionPay
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool interactionResult = RestaurantEvents.RestaurantInteraction.RequestInteraction(interactor.GetInteractorGameObject(),
|
||||
bool interactionResult = RestaurantInteractionEvents.RestaurantInteraction.RequestInteraction(interactor.GetInteractorGameObject(),
|
||||
GetInteractableGameObject(), GetInteractionType(), interactionPayloadSo, true);
|
||||
return interactionResult;
|
||||
}
|
||||
|
||||
public InteractionType GetInteractionType()
|
||||
{
|
||||
// TODO : TODO_IMPLEMENT_ME
|
||||
return InteractionType.None;
|
||||
return _interactionType;
|
||||
}
|
||||
|
||||
public GameObject GetInteractableGameObject()
|
||||
{
|
||||
// TODO : TODO_IMPLEMENT_ME
|
||||
return null;
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
public void InitializeInteraction(InteractionType interactionType)
|
||||
{
|
||||
// TODO : TODO_IMPLEMENT_ME
|
||||
_interactionType = interactionType;
|
||||
}
|
||||
|
||||
public float GetRequiredHoldTime()
|
||||
{
|
||||
return _holdTime;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,18 +2,18 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD.RestaurantEvent
|
||||
namespace DDD
|
||||
{
|
||||
public static class RestaurantEvents
|
||||
public static class RestaurantInteractionEvents
|
||||
{
|
||||
public static RestaurantInteractionEvent RestaurantInteraction = new();
|
||||
}
|
||||
|
||||
public static class RestaurantEventSolvers
|
||||
public static class RestaurantInteractionEventSolvers
|
||||
{
|
||||
public static Dictionary<InteractionType, Type> TypeToSolver = new()
|
||||
{
|
||||
{InteractionType.RestaurantManagement, typeof(RestaurantManagementEventSolver)}
|
||||
{InteractionType.RestaurantManagementUi, typeof(RestaurantManagementUiEventSolver)}
|
||||
};
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ public class RestaurantInteractionEvent : IEvent
|
||||
public GameObject Target;
|
||||
public InteractionType InteractionType;
|
||||
public ScriptableObject InteractionPayloadSo;
|
||||
public bool eventResult = false;
|
||||
public bool EventResult = false;
|
||||
|
||||
public RestaurantInteractionEvent MakeInteractionEvent(GameObject causer, GameObject target, InteractionType interactionType,
|
||||
ScriptableObject interactionPayloadSo)
|
||||
@ -41,18 +41,19 @@ public bool RequestInteraction(GameObject causer, GameObject target, Interaction
|
||||
}
|
||||
|
||||
var evt = MakeInteractionEvent(causer, target, interactionType, interactionPayloadSo);
|
||||
evt.eventResult = false;
|
||||
evt.EventResult = false;
|
||||
// Solve event directly. 이벤트 처리는 여기서 하고, 이벤트 호출로는 이런 이벤트가 호출되었고 결과가 어떻다는 거 전파하는 식으로.
|
||||
if (RestaurantEventSolvers.TypeToSolver.TryGetValue(interactionType, out var solverType))
|
||||
if (RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(interactionType, out var solverType))
|
||||
{
|
||||
Component solverComponent = target.GetComponent(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)
|
||||
{
|
||||
evt.eventResult = solver.ExecuteInteraction(interactor, interactionPayloadSo);
|
||||
evt.EventResult = solver.ExecuteInteraction(interactor, interactable, interactionPayloadSo);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -62,7 +63,7 @@ public bool RequestInteraction(GameObject causer, GameObject target, Interaction
|
||||
}
|
||||
|
||||
EventBus.Broadcast(evt);// 이벤트 결과를 이거 받아서 처리하면 될듯.
|
||||
return evt.eventResult;
|
||||
return evt.EventResult;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public class RestaurantManagementUiEventSolver : MonoBehaviour, IInteractionSolver
|
||||
{
|
||||
public bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject interactionPayloadSo = null)
|
||||
{
|
||||
GameFlowState currentGameFlowState = GameFlowManager.Instance.GameFlowDataSo.CurrentGameState;
|
||||
if (currentGameFlowState != GameFlowState.ReadyForRestaurant) return false;
|
||||
var evt = GameEvents.OpenPopupUiEvent;
|
||||
evt.UiType = typeof(RestaurantManagementUi);
|
||||
EventBus.Broadcast(evt);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user