Files
Cielonos/Assets/Scripts/Core/Interaction/InteractableObjectBase.cs

112 lines
3.5 KiB
C#
Raw Normal View History

2026-02-13 09:22:11 -05:00
using System;
using System.Collections.Generic;
2026-06-12 17:11:39 -04:00
using Cielonos.MainGame;
2026-02-13 09:22:11 -05:00
using SickscoreGames.HUDNavigationSystem;
using Sirenix.OdinInspector;
using UnityEngine;
namespace Cielonos.Core.Interaction
{
2026-05-10 11:47:55 -04:00
public partial class InteractableObjectBase : SerializedMonoBehaviour
2026-02-13 09:22:11 -05:00
{
public InteractionTrigger interactionTrigger;
public HUDNavigationElement navigation;
[HideInInspector]
public List<InteractionChoice> choices;
private void Awake()
{
choices = new List<InteractionChoice>();
InitializeChoices();
}
}
public partial class InteractableObjectBase
{
protected virtual void InitializeChoices()
{
// Override in derived classes to set up interaction choices
}
public virtual void EnterTriggerAction()
{
navigation.showIndicator = true;
navigation.useIndicatorDistanceText = true;
navigation.indicatorOnscreenDistanceTextFormat = "[E]-Interact";
}
public virtual void ExitTriggerAction()
{
navigation.showIndicator = false;
}
2026-05-10 11:47:55 -04:00
/// <summary>
/// 运行时启用或禁用此可交互对象。
/// 禁用后触发区碰撞体关闭HUD 指示器隐藏choices 不再注册给玩家。
/// 用于单次使用节点MechanicalTable、MedicalStation使用完毕后的 Exhausted 状态。
/// </summary>
public void SetInteractable(bool enabled)
{
interactionTrigger.GetComponent<Collider>().enabled = enabled;
navigation.showIndicator = enabled && navigation.showIndicator;
2026-06-12 17:11:39 -04:00
if (!enabled)
{
var player = MainGameManager.Player;
if (player != null && player.interactionSc != null && player.interactionSc.currentInteractable == this)
{
// 从玩家的选择列表中移除此物体的所有选项,防止残留选项造成后续按 R 键误触发
foreach (var choice in choices)
{
player.interactionSc.currentChoices.Remove(choice);
}
// 清除控制器引用的当前交互对象,并隐藏 UI Area
player.interactionSc.RemoveCurrentInteractable(this);
}
}
2026-05-10 11:47:55 -04:00
}
2026-02-13 09:22:11 -05:00
}
#if UNITY_EDITOR
public partial class InteractableObjectBase
{
private void Reset()
{
Setup();
}
[Button("Setup")]
private void Setup()
{
if (interactionTrigger == null)
{
interactionTrigger = GetComponentInChildren<InteractionTrigger>();
interactionTrigger.interactableObject = this;
}
if (navigation == null)
{
navigation = GetComponentInChildren<HUDNavigationElement>();
}
}
}
#endif
public class InteractionChoice
{
public string choiceName;
public Action action;
2026-06-12 17:11:39 -04:00
/// <summary>
/// 此选项是否可执行。false 时 UI 灰显,按下 R 键也不会触发 action。
/// </summary>
public bool isInteractable;
public InteractionChoice(string name, Action action, bool isInteractable = true)
2026-02-13 09:22:11 -05:00
{
this.choiceName = name;
this.action = action;
2026-06-12 17:11:39 -04:00
this.isInteractable = isInteractable;
2026-02-13 09:22:11 -05:00
}
}
}