// by chai using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; namespace TweenAnimation { // tween播放过程中产生事件 [Serializable] public class TweenEvent { public string name; // 事件名 public float time; // 事件触发时间 public UnityEvent eventHandler; // 回调函数 #if UNITY_EDITOR [NonSerialized] public bool unfold = false; #endif public TweenEvent() { name = "New Event"; time = 0; eventHandler = null; } } public class TweenAnimation : MonoBehaviour { public enum EventTriggeredDirection { None = 0, Forward = 1, Backward = 2, } public enum PlaybackStyle { Once, Loop, PingPong, } public string description = "No Description"; [SerializeReference] public List modules; public float duration; public PlaybackStyle playbackStyle; public EventTriggeredDirection eventTriggeredDirection; // 回放次数,0是不限制,默认是0 public int playbackLimit; // 是否触发事件 public bool triggerEvents; // 只触发一次事件 public bool triggerOnce; // 脚本中处理 ITweenEventHandler public bool scriptHandler; public List eventList; public TweenAnimation() { this.playbackStyle = PlaybackStyle.Loop; this.playbackLimit = 0; this.duration = 1; this.modules = new List(); this.triggerOnce = false; } public void AddModule(TweenModule module) { if (modules == null) modules = new List(); modules.Add(module); } public void RemoveModule(TweenModule module) { if (modules == null) return; if (modules.Contains(module)) modules.Remove(module); } public void AddEvent(TweenEvent e) { if (eventList == null) eventList = new List(); eventList.Add(e); } public void RemoveEvent(TweenEvent e) { if (eventList == null) return; eventList.Remove(e); } /// /// 根据时间执行tween /// /// real time public void Process(float time) { if (modules == null) return; time = ApplyLimit(time); float logicTime = HandleTime(time); for (int i = 0; i < modules.Count; i ++) { TweenModule module = modules[i]; if (!module.enabled) continue; module.OnUpdate(logicTime); } } float HandleOnce(float time) { time = Mathf.Clamp(time, 0, duration); return time; } float HandleLoop(float time) { time = time % duration; return time; } float HandlePingpong(float time) { if (time <= duration) return time; float remain = time % duration; int round = (int)(time / duration); bool bOdd = (round & 1) == 1; if (bOdd) time = duration - remain; else time = remain; return time; } // 返回[0,duration]范围内的逻辑时间 public float HandleTime(float time) { float logicTime = time; if (this.playbackStyle == PlaybackStyle.Once) logicTime = HandleOnce(time); else if (this.playbackStyle == PlaybackStyle.Loop) logicTime = HandleLoop(time); else if (this.playbackStyle == PlaybackStyle.PingPong) logicTime = HandlePingpong(time); return logicTime; } public float ApplyLimit(float time) { if (playbackLimit <= 0) return time; if (playbackStyle == PlaybackStyle.Loop) time = Mathf.Clamp(time, 0, playbackLimit * duration); else if(playbackStyle == PlaybackStyle.PingPong) time = Mathf.Clamp(time, 0, playbackLimit * duration); return time; } #if UNITY_EDITOR public void UpdateEditor(float time) { Process(time); } // 返回0-duration内的时间,用负数代表从右往左 public float GetIdentifiedTime(float t) { int round = (int)(t / duration); float time = HandleTime(t); if(playbackStyle == PlaybackStyle.PingPong) { bool bOdd = (round & 1) == 1; if(bOdd) time = -time; } return time; } #endif } }