using UnityEngine; using DG.Tweening; namespace AibisDream { /// /// 三状态位置移动器 /// 提供Open、Close、Half三个目标位置,使用DOTween进行平滑移动 /// 移动过程不可被打断,并提供移动状态标记 /// public class ThreeStatePositionMover : MonoBehaviour { [Header("目标位置设置")] [SerializeField] private Transform openPosition; [SerializeField] private Transform closePosition; [SerializeField] private Transform halfPosition; [Header("移动设置")] [SerializeField] private float moveDuration = 0.5f; [SerializeField] private Ease moveEase = Ease.OutQuad; // 当前状态 private PositionState _currentState = PositionState.Close; // 当前正在执行的Tween private Tween _currentTween; // 是否正在移动中 public bool IsMoving { get; private set; } private void Awake() { // 初始化时设置到Close位置 if (closePosition != null) { transform.position = closePosition.position; } } private void OnDestroy() { // 清理Tween if (_currentTween != null) { _currentTween.Kill(); _currentTween = null; } } /// /// 设置到Open状态 /// public void SetToOpen() { MoveToState(PositionState.Open); } /// /// 设置到Close状态 /// public void SetToClose() { MoveToState(PositionState.Close); } /// /// 设置到Half状态 /// public void SetToHalf() { MoveToState(PositionState.Half); } /// /// 移动到指定状态 /// /// 目标状态 public void MoveToState(PositionState targetState) { // 如果正在移动中,忽略新的移动请求 if (IsMoving) { return; } // 如果已经是目标状态,直接返回 if (_currentState == targetState) { return; } // 获取目标Transform Transform targetTransform = GetTransformForState(targetState); if (targetTransform == null) { Debug.LogWarning($"ThreeStatePositionMover: {targetState} 状态的Transform未设置!"); return; } // 获取目标位置 Vector3 targetPosition = targetTransform.position; // 如果当前有正在执行的Tween,先停止它 if (_currentTween != null && _currentTween.IsActive()) { _currentTween.Kill(); } // 设置移动状态 IsMoving = true; // 创建新的Tween _currentTween = transform.DOMove(targetPosition, moveDuration) .SetEase(moveEase) .OnComplete(() => { IsMoving = false; _currentState = targetState; _currentTween = null; }); } /// /// 立即设置到指定状态(不播放动画) /// /// 目标状态 public void SetStateImmediate(PositionState targetState) { // 如果正在移动,先停止移动 if (_currentTween != null && _currentTween.IsActive()) { _currentTween.Kill(); _currentTween = null; } IsMoving = false; _currentState = targetState; Transform targetTransform = GetTransformForState(targetState); if (targetTransform != null) { transform.position = targetTransform.position; } } /// /// 获取指定状态对应的Transform /// private Transform GetTransformForState(PositionState state) { return state switch { PositionState.Open => openPosition, PositionState.Close => closePosition, PositionState.Half => halfPosition, _ => closePosition }; } /// /// 获取当前状态 /// public PositionState GetCurrentState() { return _currentState; } /// /// 设置移动持续时间(运行时) /// public void SetMoveDuration(float duration) { moveDuration = duration; } /// /// 设置缓动类型(运行时) /// public void SetMoveEase(Ease ease) { moveEase = ease; } #if UNITY_EDITOR // 编辑器辅助:在Scene视图中显示目标位置 private void OnDrawGizmosSelected() { if (openPosition != null) { Gizmos.color = Color.green; Gizmos.DrawWireSphere(openPosition.position, 0.1f); } if (closePosition != null) { Gizmos.color = Color.red; Gizmos.DrawWireSphere(closePosition.position, 0.1f); } if (halfPosition != null) { Gizmos.color = Color.yellow; Gizmos.DrawWireSphere(halfPosition.position, 0.1f); } } #endif } /// /// 位置状态枚举 /// public enum PositionState { Open, Close, Half } }