ProjectDDD/Assets/_DDD/_Scripts/RestaurantEvent/InteractableHighlight.cs

155 lines
5.5 KiB
C#
Raw Normal View History

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}}
};
private float OpacityMultiply = 1.0f;
private HighlightEffect highlight;
private RestaurantInteractionComponent interaction;
private void Awake()
{
// Cache HighlightEffect
highlight = GetComponent<HighlightPlus.HighlightEffect>();
interaction = GetComponent<RestaurantInteractionComponent>();
// highlightEffect에 alphaCutoff, constantWidth, combineMeshes, outlineQuality, outlineIndependent 등의 필수 옵션이 켜져있는지 확인
highlight.alphaCutOff = 0.5f;
highlight.combineMeshes = true;
highlight.constantWidth = true;
highlight.outlineQuality = QualityLevel.Highest;
highlight.outlineIndependent = true;
highlight.outlineBlurPasses = 1;
highlight.outlineSharpness = 8;
}
private void Update()
{
var currentType = GetCurrentOutlineType();
ApplyOutlineType(currentType);
}
private InteractionOutlineType GetCurrentOutlineType()
{
// interaction이 null이거나 컴포넌트가 비활성화된 경우
if (interaction == null || !interaction.enabled)
return InteractionOutlineType.None;
// IInteractable 인터페이스로 캐스팅하여 상태 확인
var interactable = interaction as IInteractable;
if (interactable == null)
return InteractionOutlineType.None;
try
{
// 상호작용 불가능한 경우
if (!interactable.CanInteract())
return InteractionOutlineType.Unavailable;
// TODO: 여기에 추가 상태 로직을 구현
// - isHovered, isFocused 등의 상태를 체크
// - isObjective 등의 퀘스트 상태를 체크
// 플레이어가 현재 이 오브젝트를 포커스 중인지 확인
if (IsPlayerFocusing())
{
return InteractionOutlineType.Focused;
}
// 기본적으로 상호작용 가능한 상태
return InteractionOutlineType.Available;
}
catch
{
// CanInteract() 호출 중 예외 발생 시 안전하게 처리
return InteractionOutlineType.Unavailable;
}
}
private InteractionOutlineType lastAppliedType = InteractionOutlineType.None;
private void ApplyOutlineType(InteractionOutlineType type)
{
// 같은 타입이면 불필요한 프로퍼티 세팅을 피함
if (lastAppliedType == type)
return;
lastAppliedType = type;
if (highlight == null)
return;
// OutlineData에서 해당 타입의 스타일 가져오기
if (!OutlineData.TryGetValue(type, out var data))
{
// 데이터가 없으면 None 타입 적용
data = OutlineData[InteractionOutlineType.None];
}
// HighlightEffect에 적용
if (type == InteractionOutlineType.None)
{
highlight.highlighted = false;
highlight.outline = 0;
}
else
{
highlight.highlighted = true;
highlight.outlineColor = data.Color;
highlight.outlineWidth = data.Width;
highlight.outline = data.Opacity * OpacityMultiply;
}
}
private bool IsPlayerFocusing()
{
// 방법 1: 싱글톤 패턴의 플레이어 매니저 사용
// if (PlayerManager.Instance != null)
// {
// return PlayerManager.Instance.CurrentFocusTarget == gameObject;
// }
// 방법 3: 정적 참조를 통한 현재 포커스 대상 확인
// if (InteractionSystem.CurrentFocusedObject == gameObject)
// {
// return true;
// }
return false;
}
}
}