loudixvmuniu/Assets/_Scripts/Framework/Utilities/TimelineDirectorCtrl.cs

230 lines
6.5 KiB
C#
Raw Normal View History

2025-01-02 12:15:45 +08:00
using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
/*******************************************************************************
*Create By CG
*Function Timeline<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*******************************************************************************/
namespace CG.UTility
{
[RequireComponent(typeof(PlayableDirector))]
public class TimelineDirectorCtrl : MonoBehaviour
{
#region ENUM
public enum Status
{
NULL,
PLAYING,
PAUSED,
STOPPED,
}
public enum Direction
{
NULL,
FORWARD,
BACKWARD
}
#endregion
[SerializeField]
private PlayableDirector m_playableDirector;
[Range(0f, 1f)]
public float PlaySpeed = 1f;
/// <summary>
/// <20><><EFBFBD><EFBFBD>ģʽ
/// </summary>
public WrapMode WrapMode = WrapMode.Once;
/// <summary>
/// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>, <20><><EFBFBD><EFBFBD>ʱ ʱ<><CAB1><EFBFBD><EFBFBD>ʹ<EFBFBD><CDB4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
/// </summary>
public Action<double, Direction> OnPlay;
/// <summary>
/// <20><>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>, <20><><EFBFBD><EFBFBD>ʱ ʱ<><CAB1><EFBFBD><EFBFBD>ʹ<EFBFBD><CDB4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
/// </summary>
public Action<double, Direction> OnPause;
/// <summary>
/// ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>, <20><><EFBFBD><EFBFBD>ʱ ʱ<><CAB1><EFBFBD><EFBFBD>ʹ<EFBFBD><CDB4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
/// </summary>
public Action<double, Direction> OnStop;
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>, <20><><EFBFBD><EFBFBD>ʱ ʱ<><CAB1><EFBFBD><EFBFBD>ʹ<EFBFBD><CDB4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
/// </summary>
public Action<double, Direction> OnContinue;
/// <summary>
/// Timeline<6E><65><EFBFBD><EFBFBD>
/// </summary>
public double Duration { get; private set; } = -1f;
/// <summary>
/// <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>״̬(<28><><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB>״̬<D7B4>ļ<EFBFBD>¼)
/// </summary>
public Status CurrentPlayStatus { get; private set; } = Status.NULL;
/// <summary>
/// <20><>ǰ<EFBFBD><C7B0><EFBFBD>ŷ<EFBFBD><C5B7><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB>״̬<D7B4>ļ<EFBFBD>¼)
/// </summary>
public Direction CurrentPlayDirection { get; private set; } = Direction.NULL;
/// <summary>
/// <20><>ǰ<EFBFBD><C7B0><EFBFBD>Ž<EFBFBD><C5BD><EFBFBD>
/// </summary>
public double CurrentTime { get; private set; } = 0d;
private Tweener m_timeTween;
private void Awake()
{
m_playableDirector = GetComponent<PlayableDirector>();
m_playableDirector.playOnAwake = false;
Duration = m_playableDirector.duration;
CurrentPlayStatus = Status.STOPPED;
}
public void SetDuration()
{
Duration = m_playableDirector.duration;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public void Continue()
{
OnContinue?.Invoke(CurrentTime, CurrentPlayDirection);
2025-01-02 19:54:22 +08:00
CurrentPlayStatus = Status.PLAYING;
CurrentPlayDirection = Direction.FORWARD;
m_timeTween.Kill();
RatioExecute(Duration);
2025-01-02 12:15:45 +08:00
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ͣʱ<CDA3><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򲥷ŵ<F2B2A5B7>ָ<EFBFBD><D6B8>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>, Ӧ<><D3A6><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>;<EFBFBD><CDBE>ͣ<EFBFBD><CDA3><EFBFBD>л<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
/// </summary>
public void ContinuePlayForwardByPausePoint(double time,Action finishCall)
{
OnContinue?.Invoke(CurrentTime, CurrentPlayDirection);
CurrentPlayStatus = Status.PLAYING;
CurrentPlayDirection = Direction.FORWARD;
m_timeTween.Kill();
RatioExecute(time);
m_timeTween.OnComplete(()=> { finishCall?.Invoke(); });
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ͣʱ<CDA3><CAB1><EFBFBD><EFBFBD>򲥷ŵ<F2B2A5B7>ָ<EFBFBD><D6B8>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>, Ӧ<><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;<EFBFBD><CDBE>ͣ<EFBFBD><CDA3><EFBFBD>л<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
/// </summary>
public void ContinuePlayBackwardByPausePoint(double time, Action finishCall)
{
OnContinue?.Invoke(CurrentTime, CurrentPlayDirection);
CurrentPlayStatus = Status.PLAYING;
CurrentPlayDirection = Direction.BACKWARD;
m_timeTween.Kill();
RatioExecute(time);
m_timeTween.OnComplete(() => { finishCall?.Invoke(); });
}
/// <summary>
/// <20>ӿ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
/// </summary>
public void PlayForward()
{
OnPlay?.Invoke(CurrentTime, CurrentPlayDirection);
m_timeTween.Kill();
CurrentTime = 0d;
RatioExecute(Duration);
}
/// <summary>
/// <20>ӽ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD>
/// </summary>
public void PlayBackward()
{
OnPlay?.Invoke(CurrentTime, CurrentPlayDirection);
m_timeTween.Kill();
CurrentTime = Duration;
RatioExecute(0);
}
/// <summary>
/// <20><>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>
/// </summary>
public void Pause()
{
OnPause?.Invoke(CurrentTime, CurrentPlayDirection);
m_timeTween.Pause();
}
/// <summary>
/// <20><>ͣ<EFBFBD><CDA3>ij<EFBFBD><C4B3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
/// </summary>
public void StopInTime(double time)
{
m_timeTween.Kill();
CurrentTime = time;
m_playableDirector.time = CurrentTime;
m_playableDirector.Evaluate();
}
/// <summary>
/// ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
/// </summary>
public void Stop()
{
OnStop?.Invoke(CurrentTime, CurrentPlayDirection);
m_timeTween.Kill();
CurrentTime = 0d;
if (m_playableDirector)
{
m_playableDirector.time = CurrentTime;
m_playableDirector.Evaluate();
}
DOTween.KillAll();
}
private void RatioExecute(double target)
{
// ʹ<><CAB9>DoTween<65>ǰʱ<C7B0><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Թ<EFBFBD><D4B9><EFBFBD>
m_timeTween = DOTween.To(() => CurrentTime, x => CurrentTime = x, target, PlaySpeed).SetSpeedBased().SetEase(Ease.Linear);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>bug
CurrentTime = Clamp(CurrentTime, 0d, Duration);
m_timeTween.OnUpdate(() =>
{
// ֱ<><D6B1>ȡ<EFBFBD><C8A1>
if (m_playableDirector != null)
{
m_playableDirector.time = CurrentTime;
m_playableDirector.Evaluate();
}
});
m_timeTween.Play();
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>Double<6C><65>Clamp
/// </summary>
public static double Clamp(double value, double min, double max)
{
if (value < min)
value = min;
else if (value > max)
value = max;
return value;
}
}
}