인터랙션 구조 수정

This commit is contained in:
Jeonghyeon Ha 2025-08-27 17:05:54 +09:00
parent a473f517eb
commit be0a7f4cfe
6 changed files with 29 additions and 45 deletions

View File

@ -41,7 +41,7 @@ public interface IInteractable
{ {
bool CanInteract(); bool CanInteract();
bool IsInteractionHidden(); bool IsInteractionHidden();
bool OnInteracted(IInteractor interactor, ScriptableObject causerPayload = null); void OnInteracted(IInteractor interactor, ScriptableObject causerPayload = null);
InteractionType GetInteractionType(); InteractionType GetInteractionType();
GameObject GetInteractableGameObject(); GameObject GetInteractableGameObject();
void InitializeInteraction(InteractionType interactionType); void InitializeInteraction(InteractionType interactionType);

View File

@ -25,7 +25,6 @@ public override void OnStart()
public override TaskStatus OnUpdate() public override TaskStatus OnUpdate()
{ {
// TODO : 아래 타겟 찾기가 RestaurantOrderAvailable과 동일해야 함, 동일하면 중복될 필요 없으니 스태틱 유틸 함수정도로 만들어서 공유하기.
// 레스토랑 주문 인터랙션 후보를 가져옴 // 레스토랑 주문 인터랙션 후보를 가져옴
TaskStatus targetSearchSuccess = RestaurantOrderAvailable.FindAvailableOrderInteractable(_requireCanInteract, _targetOrderType, out var TaskStatus targetSearchSuccess = RestaurantOrderAvailable.FindAvailableOrderInteractable(_requireCanInteract, _targetOrderType, out var
outInteractable); outInteractable);
@ -34,19 +33,15 @@ public override TaskStatus OnUpdate()
return TaskStatus.Failure; return TaskStatus.Failure;
} }
// TODO : 아래 상호작용 수행 로직이 우리 프로젝트의 권장하는 방식이 아님. 플레이어가 오브젝트에 인터랙션하는 것과 비슷한 흐름으로 NPC가 오브젝트에 인터랙션하게 만들 것.
// 상호작용 수행: 액션이 붙은 에이전트를 Interactor로 사용 // 상호작용 수행: 액션이 붙은 에이전트를 Interactor로 사용
if (!_isGetInteractor || !_interactor.CanInteractTo(outInteractable)) if (!_isGetInteractor || !_interactor.CanInteractTo(outInteractable))
{ {
return TaskStatus.Failure; return TaskStatus.Failure;
} }
// TODO : 아래 상호작용 수행 로직이 우리 프로젝트의 권장하는 방식이 아님. 플레이어가 오브젝트에 인터랙션하는 것과 비슷한 흐름으로 NPC가 오브젝트에 인터랙션하게 만들 것.
// TODO : 이벤트 통해서 인터랙션. 직접 호출하지 말 것! // TODO : 이벤트 통해서 인터랙션. 직접 호출하지 말 것!
var interacted = outInteractable.OnInteracted(_interactor); outInteractable.OnInteracted(_interactor);
if (!interacted)
{
return TaskStatus.Failure;
}
if (_registerOnBlackboard) if (_registerOnBlackboard)
{ {

View File

@ -28,27 +28,20 @@ protected virtual void OnDestroy()
} }
protected virtual void OnInteractionCompleted() { } protected virtual void OnInteractionCompleted() { }
public virtual void RequestInteraction(RestaurantInteractionEvent evt)
{
EventBus.Broadcast(evt);
}
public virtual void HandleEvent(RestaurantInteractionEvent evt) public virtual void HandleEvent(RestaurantInteractionEvent evt)
{ {
Debug.Log($"Handle Event : {evt.ToString()}"); Debug.Log($"Event handled : {evt.ToString()}");
} }
public GameObject GetInteractorGameObject() => gameObject; public GameObject GetInteractorGameObject() => gameObject;
protected RestaurantInteractionEvent MakeInteractionEventTo(IInteractable interactable, ScriptableObject payload = null) protected void TryInteraction(IInteractable interactable, ScriptableObject payload = null)
{ {
var evt = RestaurantEvents.InteractionEvent; var causer = gameObject;
evt.Target = interactable.GetInteractableGameObject(); var target = interactable.GetInteractableGameObject();
evt.Causer = gameObject; var interactionType = _nearestInteractable.GetInteractionType();
evt.InteractionType = _nearestInteractable.GetInteractionType(); RestaurantEvents.InteractionEvent.RequestInteraction(causer, target, interactionType, payload);
evt.Payload = payload;
return evt;
} }
public IInteractionSolver GetInteractionSolver(InteractionType interactionType) public IInteractionSolver GetInteractionSolver(InteractionType interactionType)

View File

@ -70,19 +70,19 @@ protected virtual void Update()
float requiredHoldTime = _interactingTarget.GetExecutionParameters().HoldTime; float requiredHoldTime = _interactingTarget.GetExecutionParameters().HoldTime;
float ratio = Mathf.Clamp01(_interactHeldTime / requiredHoldTime); float ratio = Mathf.Clamp01(_interactHeldTime / requiredHoldTime);
if (_interactHeldTime >= requiredHoldTime) if (_interactHeldTime >= requiredHoldTime)
{ {
var evt = MakeInteractionEventTo(_nearestInteractable); TryInteraction(_nearestInteractable);
RequestInteraction(evt); OnInteractionCompleted();
ResetInteractionState(); ResetInteractionState();
ratio = 0; OnInteractionHoldProgress(0f);
}
OnInteractionCompleted(); else
{
OnInteractionHoldProgress(ratio);
} }
OnInteractionHoldProgress(ratio);
} }
} }
@ -95,8 +95,7 @@ private void OnInteractPerformed(InputAction.CallbackContext context)
if (requiredHoldTime <= 0f) if (requiredHoldTime <= 0f)
{ {
var evt = MakeInteractionEventTo(_nearestInteractable); TryInteraction(_nearestInteractable);
RequestInteraction(evt);
} }
else else
{ {

View File

@ -75,20 +75,9 @@ public virtual bool IsInteractionHidden()
return flowDisabled; return flowDisabled;
} }
public virtual bool OnInteracted(IInteractor interactor, ScriptableObject payload = null) public virtual void OnInteracted(IInteractor interactor, ScriptableObject payload = null)
{ {
if (CanInteract() == false) // TODO : Do Something cosmetic?
{
return false;
}
bool interactionResult = RestaurantEvents.InteractionEvent.RequestInteraction(interactor.GetInteractorGameObject(),
GetInteractableGameObject(), GetInteractionType(), payload, true);
if (HasSubsystem(_interactionType))
{
interactionResult &= GetSubsystem(_interactionType).OnInteracted(interactor, payload);
}
return interactionResult;
} }
public virtual InteractionType GetInteractionType() public virtual InteractionType GetInteractionType()

View File

@ -54,7 +54,15 @@ public bool RequestInteraction(GameObject causer, GameObject target, Interaction
// Cast solverComponent to IInteractable // Cast solverComponent to IInteractable
if (solver is not null && interactor is not null) if (solver is not null && interactor is not null)
{ {
evt.EventResult = solver.ExecuteInteraction(interactor, interactable, payload); bool canExecute = solver.CanExecuteInteraction(interactor, interactable, payload);
if (canExecute)
{
evt.EventResult = solver.ExecuteInteraction(interactor, interactable, payload);
}
else
{
evt.EventResult = false;
}
} }
else else
{ {