219 lines
6.0 KiB
C#
219 lines
6.0 KiB
C#
using UnityEngine;
|
|
using DG.Tweening;
|
|
|
|
namespace AibisDream
|
|
{
|
|
/// <summary>
|
|
/// 三状态位置移动器
|
|
/// 提供Open、Close、Half三个目标位置,使用DOTween进行平滑移动
|
|
/// 移动过程不可被打断,并提供移动状态标记
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置到Open状态
|
|
/// </summary>
|
|
public void SetToOpen()
|
|
{
|
|
MoveToState(PositionState.Open);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置到Close状态
|
|
/// </summary>
|
|
public void SetToClose()
|
|
{
|
|
MoveToState(PositionState.Close);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置到Half状态
|
|
/// </summary>
|
|
public void SetToHalf()
|
|
{
|
|
MoveToState(PositionState.Half);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 移动到指定状态
|
|
/// </summary>
|
|
/// <param name="targetState">目标状态</param>
|
|
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;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 立即设置到指定状态(不播放动画)
|
|
/// </summary>
|
|
/// <param name="targetState">目标状态</param>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取指定状态对应的Transform
|
|
/// </summary>
|
|
private Transform GetTransformForState(PositionState state)
|
|
{
|
|
return state switch
|
|
{
|
|
PositionState.Open => openPosition,
|
|
PositionState.Close => closePosition,
|
|
PositionState.Half => halfPosition,
|
|
_ => closePosition
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取当前状态
|
|
/// </summary>
|
|
public PositionState GetCurrentState()
|
|
{
|
|
return _currentState;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置移动持续时间(运行时)
|
|
/// </summary>
|
|
public void SetMoveDuration(float duration)
|
|
{
|
|
moveDuration = duration;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置缓动类型(运行时)
|
|
/// </summary>
|
|
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
|
|
}
|
|
|
|
/// <summary>
|
|
/// 位置状态枚举
|
|
/// </summary>
|
|
public enum PositionState
|
|
{
|
|
Open,
|
|
Close,
|
|
Half
|
|
}
|
|
}
|