2025-08-13 12:21:35 +00:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
|
|
using QualityLevel = HighlightPlus.QualityLevel;
|
|
|
|
|
|
|
|
using HighlightPlus;
|
|
|
|
|
|
|
|
namespace DDD
|
|
|
|
{
|
|
|
|
public enum InteractionOutlineType
|
|
|
|
{
|
|
|
|
None,
|
|
|
|
Focused,
|
|
|
|
Available,
|
|
|
|
Unavailable,
|
|
|
|
Objective
|
|
|
|
}
|
|
|
|
|
|
|
|
public struct InteractionOutlineData
|
|
|
|
{
|
|
|
|
public Color Color;
|
|
|
|
public float Width;
|
|
|
|
public float Opacity;
|
|
|
|
}
|
|
|
|
|
|
|
|
[RequireComponent(typeof(HighlightEffect))]
|
|
|
|
[RequireComponent(typeof(RestaurantInteractionComponent))]
|
|
|
|
[AddComponentMenu("DDD/Interaction/InteractableHighlight")]
|
|
|
|
public class InteractableHighlight : MonoBehaviour
|
|
|
|
{
|
|
|
|
public static Dictionary<InteractionOutlineType, InteractionOutlineData> OutlineData = new()
|
|
|
|
{
|
|
|
|
{InteractionOutlineType.Available, new InteractionOutlineData() {Color = Color.white, Width = 0.5f, Opacity = 1f}},
|
|
|
|
{InteractionOutlineType.Focused, new InteractionOutlineData() {Color = Color.yellow, Width = 0.5f, Opacity = 1f}},
|
|
|
|
{InteractionOutlineType.Unavailable, new InteractionOutlineData() {Color = Color.gray, Width = 0.5f, Opacity = 1f}},
|
|
|
|
{InteractionOutlineType.Objective, new InteractionOutlineData() {Color = Color.cyan, Width = 0.5f, Opacity = 1f}},
|
|
|
|
{InteractionOutlineType.None, new InteractionOutlineData() {Color = Color.clear, Width = 0.5f, Opacity = 0f}}
|
|
|
|
};
|
|
|
|
|
2025-08-14 04:46:36 +00:00
|
|
|
private HighlightEffect _highlightComponent;
|
|
|
|
private RestaurantInteractionComponent _interactionComponent;
|
|
|
|
private IInteractor _interactor;
|
2025-08-13 12:21:35 +00:00
|
|
|
private void Awake()
|
|
|
|
{
|
|
|
|
// Cache HighlightEffect
|
2025-08-14 04:46:36 +00:00
|
|
|
_highlightComponent = GetComponent<HighlightPlus.HighlightEffect>();
|
|
|
|
_interactionComponent = GetComponent<RestaurantInteractionComponent>();
|
2025-08-13 12:21:35 +00:00
|
|
|
|
|
|
|
// highlightEffect에 alphaCutoff, constantWidth, combineMeshes, outlineQuality, outlineIndependent 등의 필수 옵션이 켜져있는지 확인
|
2025-08-14 04:46:36 +00:00
|
|
|
_highlightComponent.alphaCutOff = 0.5f;
|
|
|
|
_highlightComponent.combineMeshes = true;
|
|
|
|
_highlightComponent.constantWidth = true;
|
|
|
|
_highlightComponent.outlineQuality = QualityLevel.Highest;
|
|
|
|
_highlightComponent.outlineIndependent = true;
|
|
|
|
_highlightComponent.outlineBlurPasses = 1;
|
|
|
|
_highlightComponent.outlineSharpness = 8;
|
2025-08-13 12:21:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void Update()
|
|
|
|
{
|
2025-08-14 04:46:36 +00:00
|
|
|
FetchPlayerInteractorComponent();
|
|
|
|
|
2025-08-13 12:21:35 +00:00
|
|
|
var currentType = GetCurrentOutlineType();
|
|
|
|
ApplyOutlineType(currentType);
|
2025-08-14 04:46:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private void FetchPlayerInteractorComponent()
|
|
|
|
{
|
|
|
|
if (_interactor == null)
|
|
|
|
{
|
|
|
|
var player = PlayerManager.Instance.GetPlayer();
|
|
|
|
_interactor = player?.GetComponent<IInteractor>();
|
|
|
|
}
|
2025-08-13 12:21:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private InteractionOutlineType GetCurrentOutlineType()
|
|
|
|
{
|
|
|
|
// interaction이 null이거나 컴포넌트가 비활성화된 경우
|
2025-08-14 04:46:36 +00:00
|
|
|
if (!_interactionComponent || !_interactionComponent.enabled)
|
2025-08-13 12:21:35 +00:00
|
|
|
return InteractionOutlineType.None;
|
|
|
|
|
|
|
|
// IInteractable 인터페이스로 캐스팅하여 상태 확인
|
2025-08-14 04:46:36 +00:00
|
|
|
if (_interactionComponent is not IInteractable interactable)
|
2025-08-13 12:21:35 +00:00
|
|
|
return InteractionOutlineType.None;
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// 상호작용 불가능한 경우
|
2025-08-14 04:46:36 +00:00
|
|
|
if (CanExecuteInteraction() == false)
|
2025-08-13 12:21:35 +00:00
|
|
|
return InteractionOutlineType.Unavailable;
|
|
|
|
|
|
|
|
// TODO: 여기에 추가 상태 로직을 구현
|
|
|
|
// - isObjective 등의 퀘스트 상태를 체크
|
|
|
|
|
|
|
|
// 플레이어가 현재 이 오브젝트를 포커스 중인지 확인
|
|
|
|
if (IsPlayerFocusing())
|
|
|
|
{
|
|
|
|
return InteractionOutlineType.Focused;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 기본적으로 상호작용 가능한 상태
|
|
|
|
return InteractionOutlineType.Available;
|
|
|
|
}
|
|
|
|
catch
|
|
|
|
{
|
|
|
|
return InteractionOutlineType.Unavailable;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private InteractionOutlineType lastAppliedType = InteractionOutlineType.None;
|
|
|
|
|
|
|
|
private void ApplyOutlineType(InteractionOutlineType type)
|
|
|
|
{
|
|
|
|
// 같은 타입이면 불필요한 프로퍼티 세팅을 피함
|
|
|
|
if (lastAppliedType == type)
|
|
|
|
return;
|
|
|
|
|
|
|
|
lastAppliedType = type;
|
|
|
|
|
2025-08-14 04:46:36 +00:00
|
|
|
if (!_highlightComponent)
|
2025-08-13 12:21:35 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// OutlineData에서 해당 타입의 스타일 가져오기
|
|
|
|
if (!OutlineData.TryGetValue(type, out var data))
|
|
|
|
{
|
|
|
|
// 데이터가 없으면 None 타입 적용
|
|
|
|
data = OutlineData[InteractionOutlineType.None];
|
|
|
|
}
|
|
|
|
|
|
|
|
// HighlightEffect에 적용
|
|
|
|
if (type == InteractionOutlineType.None)
|
|
|
|
{
|
2025-08-14 04:46:36 +00:00
|
|
|
_highlightComponent.highlighted = false;
|
|
|
|
_highlightComponent.outline = 0;
|
2025-08-13 12:21:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2025-08-14 04:46:36 +00:00
|
|
|
_highlightComponent.highlighted = true;
|
|
|
|
_highlightComponent.outlineColor = data.Color;
|
|
|
|
_highlightComponent.outlineWidth = data.Width;
|
|
|
|
_highlightComponent.outline = data.Opacity * opacityMultiply;
|
2025-08-13 12:21:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool IsPlayerFocusing()
|
|
|
|
{
|
2025-08-14 04:46:36 +00:00
|
|
|
return _interactor?.GetFocusedInteractable() == _interactionComponent;
|
2025-08-13 12:21:35 +00:00
|
|
|
}
|
2025-08-14 04:46:36 +00:00
|
|
|
|
|
|
|
private bool CanExecuteInteraction()
|
|
|
|
{
|
|
|
|
if (_interactionComponent.CanInteract() == false)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2025-08-13 12:21:35 +00:00
|
|
|
|
2025-08-14 04:46:36 +00:00
|
|
|
if (_interactor == null)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return _interactor.CanInteractTo(_interactionComponent);
|
|
|
|
}
|
2025-08-13 12:21:35 +00:00
|
|
|
}
|
|
|
|
}
|