상호작용 오브젝트 조건 변경

This commit is contained in:
NTG_Lenovo 2025-08-13 18:31:34 +09:00
parent f359c7d06d
commit d12ede279c
6 changed files with 305 additions and 263 deletions

File diff suppressed because it is too large Load Diff

View File

@ -81,6 +81,7 @@ public class InventoryChangedEvent : IEvent
public class ShowInteractionUiEvent : IEvent public class ShowInteractionUiEvent : IEvent
{ {
public bool CanInteract;
public string TextKey; public string TextKey;
public float HoldProgress; public float HoldProgress;
} }

View File

@ -1,3 +1,4 @@
using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.Localization; using UnityEngine.Localization;
using UnityEngine.Localization.Components; using UnityEngine.Localization.Components;
@ -8,7 +9,11 @@ namespace DDD
public class InteractionMessageUi : BaseUi, IEventHandler<ShowInteractionUiEvent>, IEventHandler<HideInteractionUiEvent> public class InteractionMessageUi : BaseUi, IEventHandler<ShowInteractionUiEvent>, IEventHandler<HideInteractionUiEvent>
{ {
[SerializeField] private Image _filledImage; [SerializeField] private Image _filledImage;
[SerializeField] private TextMeshProUGUI _textLabel;
[SerializeField] private LocalizeStringEvent _textLabelLocalizeStringEvent; [SerializeField] private LocalizeStringEvent _textLabelLocalizeStringEvent;
[SerializeField] private Color _canInteractTextColor = Color.white;
[SerializeField] private Color _cannotInteractTextColor = Color.gray2;
private LocalizedString _previousLocalizedString; private LocalizedString _previousLocalizedString;
@ -33,6 +38,8 @@ protected override void OnDestroy()
public void Invoke(ShowInteractionUiEvent evt) public void Invoke(ShowInteractionUiEvent evt)
{ {
_previousLocalizedString = LocalizationManager.Instance.GetLocalizedString(evt.TextKey); _previousLocalizedString = LocalizationManager.Instance.GetLocalizedString(evt.TextKey);
_textLabel.color = evt.CanInteract ? _canInteractTextColor : _cannotInteractTextColor;
if (_textLabelLocalizeStringEvent.StringReference != _previousLocalizedString) if (_textLabelLocalizeStringEvent.StringReference != _previousLocalizedString)
{ {
_textLabelLocalizeStringEvent.StringReference = _previousLocalizedString; _textLabelLocalizeStringEvent.StringReference = _previousLocalizedString;

View File

@ -20,7 +20,7 @@ private async Task Initialize()
_restaurantPlayerDataSo = await AssetManager.LoadAsset<RestaurantPlayerDataSo>(DataConstants.RestaurantPlayerDataSo); _restaurantPlayerDataSo = await AssetManager.LoadAsset<RestaurantPlayerDataSo>(DataConstants.RestaurantPlayerDataSo);
Debug.Assert(_restaurantPlayerDataSo != null, "_restaurantPlayerDataSo is null"); Debug.Assert(_restaurantPlayerDataSo != null, "_restaurantPlayerDataSo is null");
_restaurantPlayerDataSo.InteractAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Interact)); _restaurantPlayerDataSo!.InteractAction = InputManager.Instance.GetAction(InputActionMaps.Restaurant, nameof(RestaurantActions.Interact));
_restaurantPlayerDataSo.InteractAction.performed += OnInteractPerformed; _restaurantPlayerDataSo.InteractAction.performed += OnInteractPerformed;
_restaurantPlayerDataSo.InteractAction.canceled += OnInteractCanceled; _restaurantPlayerDataSo.InteractAction.canceled += OnInteractCanceled;
@ -45,7 +45,7 @@ protected override void OnDestroy()
private void OnInteractPerformed(InputAction.CallbackContext context) private void OnInteractPerformed(InputAction.CallbackContext context)
{ {
if (_nearestInteractable == null || !_nearestInteractable.CanInteract()) return; if (_nearestInteractable == null || CanInteract(_nearestInteractable) == false) return;
float requiredHoldTime = _nearestInteractable.GetRequiredHoldTime(); float requiredHoldTime = _nearestInteractable.GetRequiredHoldTime();
@ -69,9 +69,9 @@ private void OnInteractCanceled(InputAction.CallbackContext context)
protected override void OnNearestInteractableChanged(IInteractable newTarget) protected override void OnNearestInteractableChanged(IInteractable newTarget)
{ {
if (newTarget != null && newTarget.CanInteract()) if (newTarget != null)
{ {
BroadcastShowUi(newTarget, 0f); BroadcastShowUi(newTarget, CanInteract(newTarget), 0f);
} }
else else
{ {
@ -83,7 +83,7 @@ protected override void OnInteractionHoldProgress(float ratio)
{ {
if (_interactingTarget != null) if (_interactingTarget != null)
{ {
BroadcastShowUi(_interactingTarget, ratio); BroadcastShowUi(_interactingTarget, CanInteract(_interactingTarget), ratio);
} }
} }
@ -92,9 +92,10 @@ protected override void OnInteractionCompleted()
} }
private void BroadcastShowUi(IInteractable interactable, float ratio) private void BroadcastShowUi(IInteractable interactable, bool canInteract, float ratio)
{ {
var evt = GameEvents.ShowInteractionUiEvent; var evt = GameEvents.ShowInteractionUiEvent;
evt.CanInteract = canInteract;
evt.TextKey = interactable.GetInteractionMessageKey(); evt.TextKey = interactable.GetInteractionMessageKey();
evt.HoldProgress = ratio; evt.HoldProgress = ratio;
EventBus.Broadcast(evt); EventBus.Broadcast(evt);

View File

@ -33,7 +33,7 @@ protected virtual void Update()
if (_isInteracting) if (_isInteracting)
{ {
if (_nearestInteractable != _interactingTarget) if (_nearestInteractable != _interactingTarget || CanInteract(_interactingTarget) == false)
{ {
ResetInteractionState(); ResetInteractionState();
return; return;
@ -46,6 +46,7 @@ protected virtual void Update()
if (_interactHeldTime >= requiredHoldTime) if (_interactHeldTime >= requiredHoldTime)
{ {
OnInteractionHoldProgress(1f);
_isInteracting = false; _isInteracting = false;
_interactingTarget.OnInteracted(this); _interactingTarget.OnInteracted(this);
_interactingTarget = null; _interactingTarget = null;
@ -79,10 +80,10 @@ protected IInteractable GetNearestInteractable()
for (int i = 0; i < colliderCount; i++) for (int i = 0; i < colliderCount; i++)
{ {
var col = _nearColliders[i]; var col = _nearColliders[i];
if (col.TryGetComponent<IInteractable>(out var interactable) == false || interactable.CanInteract() == false) continue; if (col.TryGetComponent<IInteractable>(out var interactable) == false) continue;
var type = interactable.GetInteractionType(); var type = interactable.GetInteractionType();
if (ContainTypeToSolver(type, out var solver) == false || solver.CanExecuteInteraction() == false) continue; if (ContainsSolverForType(type) == false) continue;
float distance = Vector3.Distance(transform.position, col.transform.position); float distance = Vector3.Distance(transform.position, col.transform.position);
if (distance < closestDistance) if (distance < closestDistance)
@ -99,20 +100,50 @@ public virtual void Invoke(RestaurantInteractionEvent evt) { }
public GameObject GetInteractorGameObject() => gameObject; public GameObject GetInteractorGameObject() => gameObject;
private bool ContainTypeToSolver(InteractionType type, out IInteractionSolver solver) private bool TryGetSolverFor(IInteractable interactable, out IInteractionSolver solver)
{
solver = null;
if (interactable == null) return false;
return TryGetSolverForType(interactable.GetInteractionType(), out solver);
}
private bool TryGetSolverForType(InteractionType type, out IInteractionSolver solver)
{ {
if (_cachedSolvers.TryGetValue(type, out solver)) return solver != null; if (_cachedSolvers.TryGetValue(type, out solver)) return solver != null;
solver = null; solver = null;
if (!RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(type, out var solverType)) return false; if (RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(type, out var solverType) == false) return false;
if (!TryGetComponent(solverType, out var component)) return false; if (transform.TryGetComponent(solverType, out var component) == false) return false;
solver = component as IInteractionSolver; solver = component as IInteractionSolver;
_cachedSolvers[type] = solver; _cachedSolvers[type] = solver;
return solver != null; return solver != null;
} }
private bool ContainsSolverForType(InteractionType type)
{
if (_cachedSolvers.TryGetValue(type, out var cachedSolver)) return cachedSolver != null;
if (RestaurantInteractionEventSolvers.TypeToSolver.TryGetValue(type, out var solverType) == false) return false;
if (transform.TryGetComponent(solverType, out var component) == false) return false;
var solver = component as IInteractionSolver;
_cachedSolvers[type] = solver;
return solver != null;
}
protected bool CanInteract(IInteractable interactable)
{
if (interactable == null) return false;
if (interactable.CanInteract() == false) return false;
if (TryGetSolverFor(interactable, out var solver) == false) return false;
return solver.CanExecuteInteraction();
}
} }
} }

View File

@ -19,7 +19,6 @@ private async Task Initialize()
public bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject interactionPayloadSo = null) public bool ExecuteInteraction(IInteractor interactor, IInteractable interactable, ScriptableObject interactionPayloadSo = null)
{ {
print("발생");
if (CanExecuteInteraction() == false) return false; if (CanExecuteInteraction() == false) return false;
GameFlowManager.Instance.ChangeFlow(GameFlowState.RunRestaurant); GameFlowManager.Instance.ChangeFlow(GameFlowState.RunRestaurant);