Files

112 lines
3.6 KiB
C#
Raw Permalink Normal View History

2026-07-08 19:53:15 +08:00
using UnityEngine;
using DG.Tweening; // 引入 DOTween 命名空间
namespace Interaction
{
public class DoorController : MonoBehaviour, IInteractable
{
[System.Serializable]
public class DoorLeaf
{
[Tooltip("门页对象")]
public Transform doorTransform;
[Tooltip("开门时,该门页的 Y 轴角度 (例如 90 或 -90)")]
public float openAngle = 90f;
}
[Header("门页设置")]
[Tooltip("请绑定门页对象 (最多两个),并设置各自的开门角度。关门角度默认为 0 度。")]
[SerializeField] private DoorLeaf[] doorLeaves;
[Header("动画设置")]
[Tooltip("开门需要几秒钟")]
[SerializeField] private float duration = 1.0f;
[SerializeField] private Ease animationEase = Ease.OutQuad;
// 运行时状态
private bool isOpen = false; //默认关闭
public bool IsOpen => isOpen;
private void Start()
{
// 校验配置
if (doorLeaves == null || doorLeaves.Length == 0)
{
Debug.LogWarning("[DoorController] 未绑定任何门页 (Door Leaves)!请在 Inspector 中设置。");
return;
}
// 初始化状态判断:
// 我们以"第一个门页"的状态为准来判断当前整个门是开还是关
var firstLeaf = doorLeaves[0];
if (firstLeaf.doorTransform == null) return;
float currentY = firstLeaf.doorTransform.localEulerAngles.y;
// 处理欧拉角 360 度问题 (比如 -90 度可能是 270)
if (currentY > 180) currentY -= 360;
// 关门角度默认为 0
float distToClose = Mathf.Abs(Mathf.DeltaAngle(currentY, 0f));
float distToOpen = Mathf.Abs(Mathf.DeltaAngle(currentY, firstLeaf.openAngle));
isOpen = distToOpen < distToClose;
Debug.Log($"[Door] 初始化完成。当前角度: {currentY}, 判定为: {(isOpen ? "" : "")}");
}
public void Interact()
{
if (doorLeaves == null || doorLeaves.Length == 0) return;
Debug.Log($"<color=green>[Door] 收到交互请求!当前状态 isOpen: {isOpen}</color>");
ToggleDoor();
}
public string GetInteractPrompt()
{
return isOpen ? "关闭" : "打开";
}
public void OpenDoor()
{
if (isOpen) return;
ToggleDoor();
}
public void CloseDoor()
{
if (!isOpen) return;
ToggleDoor();
}
public void ToggleDoor()
{
isOpen = !isOpen;
// 遍历所有门页进行旋转
foreach (var leaf in doorLeaves)
{
if (leaf == null || leaf.doorTransform == null) continue;
Vector3 currentRot = leaf.doorTransform.localEulerAngles;
// 关门目标为 0,开门目标为 leaf.openAngle
float targetY = isOpen ? leaf.openAngle : 0f;
Vector3 targetRotation = new Vector3(currentRot.x, targetY, currentRot.z);
// --- DOTween 核心代码 ---
// 1. 杀掉该对象上可能正在运行的旋转动画,防止冲突
leaf.doorTransform.DOKill();
// 2. 创建新动画
leaf.doorTransform.DOLocalRotate(targetRotation, duration)
.SetEase(animationEase);
}
}
}
}