Files
2026-07-08 20:42:51 +08:00

112 lines
3.3 KiB
C#

using Interaction.Conditions;
using UnityEngine;
using UnityEngine.Events;
namespace Interaction
{
public class InteractUnlockState : InteractConditionBehaviour
{
[SerializeField] private bool unlocked;
[Header("Interact Gate")]
[SerializeField] private bool blockInteractionWhenLocked;
[SerializeField] private string lockedFailReason = "尚未解锁";
[Header("State Visuals")]
[SerializeField] private GameObject[] activateWhenUnlocked;
[SerializeField] private GameObject[] deactivateWhenUnlocked;
[Header("State Events")]
[SerializeField] private UnityEvent onUnlocked;
[SerializeField] private UnityEvent onLocked;
[SerializeField] private UnityEvent<bool> onValueChanged;
[Header("Behavior")]
[SerializeField] private bool applyOnEnable = true;
[Header("Debug")]
[SerializeField] private bool debugLog;
public bool IsUnlocked => unlocked;
public bool BlocksInteractionWhenLocked => blockInteractionWhenLocked;
public override bool CanInteract(GameObject interactor, out string failReason)
{
failReason = null;
if (!blockInteractionWhenLocked) return true;
if (unlocked) return true;
failReason = string.IsNullOrWhiteSpace(lockedFailReason) ? "尚未解锁" : lockedFailReason;
return false;
}
public override void OnInteractSucceeded(GameObject interactor)
{
}
public void SetUnlocked(bool value)
{
if (unlocked == value)
{
Apply();
return;
}
unlocked = value;
Apply();
onValueChanged?.Invoke(unlocked);
if (unlocked) onUnlocked?.Invoke();
else onLocked?.Invoke();
}
public void Unlock()
{
SetUnlocked(true);
}
public void Lock()
{
SetUnlocked(false);
}
private void OnEnable()
{
if (applyOnEnable) Apply();
}
private void Apply()
{
if (activateWhenUnlocked != null)
{
bool active = unlocked;
for (int i = 0; i < activateWhenUnlocked.Length; i++)
{
var go = activateWhenUnlocked[i];
if (go == null) continue;
if (go.activeSelf != active) go.SetActive(active);
}
}
if (deactivateWhenUnlocked != null)
{
bool active = !unlocked;
for (int i = 0; i < deactivateWhenUnlocked.Length; i++)
{
var go = deactivateWhenUnlocked[i];
if (go == null) continue;
if (go.activeSelf != active) go.SetActive(active);
}
}
if (debugLog)
{
Debug.Log(
$"[InteractUnlockState] Apply on '{name}' unlocked={unlocked} " +
$"activateCount={(activateWhenUnlocked == null ? 0 : activateWhenUnlocked.Length)} " +
$"deactivateCount={(deactivateWhenUnlocked == null ? 0 : deactivateWhenUnlocked.Length)}",
this);
}
}
}
}