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;
|
|
|
|
|
|
|
2025-01-16 11:21:23 +08:00
|
|
|
|
public Dictionary<float, Action<float>> OnTriDic = new Dictionary<float, Action<float>>();
|
|
|
|
|
|
|
2025-01-02 12:15:45 +08:00
|
|
|
|
/// <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;
|
2025-01-16 11:21:23 +08:00
|
|
|
|
foreach (float item in OnTriDic.Keys)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(Math.Abs(item-CurrentTime)<0.01f)
|
|
|
|
|
|
{
|
|
|
|
|
|
OnTriDic[item]?.Invoke(item);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-01-02 12:15:45 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|