using System; using UnityEngine; #if FAIRYGUI_TOLUA using LuaInterface; #endif namespace FairyGUI { /// /// /// public delegate void GTweenCallback(); /// /// /// /// public delegate void GTweenCallback1(GTweener tweener); /// /// /// public interface ITweenListener { /// /// /// /// void OnTweenStart(GTweener tweener); /// /// /// /// void OnTweenUpdate(GTweener tweener); /// /// /// /// void OnTweenComplete(GTweener tweener); } /// /// /// public class GTweener { internal object _target; internal TweenPropType _propType; internal bool _killed; internal bool _paused; float _delay; float _duration; float _breakpoint; EaseType _easeType; float _easeOvershootOrAmplitude; float _easePeriod; int _repeat; bool _yoyo; float _timeScale; bool _ignoreEngineTimeScale; bool _snapping; object _userData; GPath _path; CustomEase _customEase; GTweenCallback _onUpdate; GTweenCallback _onStart; GTweenCallback _onComplete; GTweenCallback1 _onUpdate1; GTweenCallback1 _onStart1; GTweenCallback1 _onComplete1; ITweenListener _listener; TweenValue _startValue; TweenValue _endValue; TweenValue _value; TweenValue _deltaValue; int _valueSize; bool _started; int _ended; float _elapsedTime; float _normalizedTime; int _smoothStart; public GTweener() { _startValue = new TweenValue(); _endValue = new TweenValue(); _value = new TweenValue(); _deltaValue = new TweenValue(); } /// /// /// /// /// public GTweener SetDelay(float value) { _delay = value; return this; } /// /// /// public float delay { get { return _delay; } } /// /// /// /// /// public GTweener SetDuration(float value) { _duration = value; return this; } /// /// /// public float duration { get { return _duration; } } /// /// /// /// /// public GTweener SetBreakpoint(float value) { _breakpoint = value; return this; } /// /// /// /// /// public GTweener SetEase(EaseType value) { _easeType = value; return this; } /// /// /// /// /// /// public GTweener SetEase(EaseType value, CustomEase customEase) { _easeType = value; _customEase = customEase; return this; } /// /// /// /// /// public GTweener SetEasePeriod(float value) { _easePeriod = value; return this; } /// /// /// /// /// public GTweener SetEaseOvershootOrAmplitude(float value) { _easeOvershootOrAmplitude = value; return this; } /// /// /// /// /// /// public GTweener SetRepeat(int times, bool yoyo = false) { _repeat = times; _yoyo = yoyo; return this; } /// /// /// public int repeat { get { return _repeat; } } /// /// /// /// /// public GTweener SetTimeScale(float value) { _timeScale = value; return this; } /// /// /// /// /// public GTweener SetIgnoreEngineTimeScale(bool value) { _ignoreEngineTimeScale = value; return this; } /// /// /// /// /// public GTweener SetSnapping(bool value) { _snapping = value; return this; } /// /// /// /// /// public GTweener SetPath(GPath value) { _path = value; return this; } /// /// /// /// /// public GTweener SetTarget(object value) { _target = value; _propType = TweenPropType.None; return this; } /// /// /// /// /// /// public GTweener SetTarget(object value, TweenPropType propType) { _target = value; _propType = propType; return this; } /// /// /// public object target { get { return _target; } } /// /// /// /// /// public GTweener SetUserData(object value) { _userData = value; return this; } /// /// /// public object userData { get { return _userData; } } /// /// /// /// /// #if FAIRYGUI_TOLUA [NoToLua] #endif public GTweener OnUpdate(GTweenCallback callback) { _onUpdate = callback; return this; } /// /// /// /// /// #if FAIRYGUI_TOLUA [NoToLua] #endif public GTweener OnStart(GTweenCallback callback) { _onStart = callback; return this; } /// /// /// /// /// #if FAIRYGUI_TOLUA [NoToLua] #endif public GTweener OnComplete(GTweenCallback callback) { _onComplete = callback; return this; } /// /// /// /// /// public GTweener OnUpdate(GTweenCallback1 callback) { _onUpdate1 = callback; return this; } /// /// /// /// /// public GTweener OnStart(GTweenCallback1 callback) { _onStart1 = callback; return this; } /// /// /// /// /// public GTweener OnComplete(GTweenCallback1 callback) { _onComplete1 = callback; return this; } /// /// /// /// /// public GTweener SetListener(ITweenListener value) { _listener = value; return this; } /// /// /// public TweenValue startValue { get { return _startValue; } } /// /// /// public TweenValue endValue { get { return _endValue; } } /// /// /// public TweenValue value { get { return _value; } } /// /// /// public TweenValue deltaValue { get { return _deltaValue; } } /// /// /// public float normalizedTime { get { return _normalizedTime; } } /// /// /// public bool completed { get { return _ended != 0; } } /// /// /// public bool allCompleted { get { return _ended == 1; } } /// /// /// /// /// public GTweener SetPaused(bool paused) { _paused = paused; if (_paused) _smoothStart = 0; return this; } /// /// /// /// public void Seek(float time) { if (_killed) return; _elapsedTime = time; if (_elapsedTime < _delay) { if (_started) _elapsedTime = _delay; else return; } Update(); } /// /// /// /// public void Kill(bool complete = false) { if (_killed) return; if (complete) { if (_ended == 0) { if (_breakpoint >= 0) _elapsedTime = _delay + _breakpoint; else if (_repeat >= 0) _elapsedTime = _delay + _duration * (_repeat + 1); else _elapsedTime = _delay + _duration * 2; Update(); } CallCompleteCallback(); } _killed = true; } internal GTweener _To(float start, float end, float duration) { _valueSize = 1; _startValue.x = start; _endValue.x = end; _value.x = start; _duration = duration; return this; } internal GTweener _To(Vector2 start, Vector2 end, float duration) { _valueSize = 2; _startValue.vec2 = start; _endValue.vec2 = end; _value.vec2 = start; _duration = duration; return this; } internal GTweener _To(Vector3 start, Vector3 end, float duration) { _valueSize = 3; _startValue.vec3 = start; _endValue.vec3 = end; _value.vec3 = start; _duration = duration; return this; } internal GTweener _To(Vector4 start, Vector4 end, float duration) { _valueSize = 4; _startValue.vec4 = start; _endValue.vec4 = end; _value.vec4 = start; _duration = duration; return this; } internal GTweener _To(Color start, Color end, float duration) { _valueSize = 4; _startValue.color = start; _endValue.color = end; _value.color = start; _duration = duration; return this; } internal GTweener _To(double start, double end, float duration) { _valueSize = 5; _startValue.d = start; _endValue.d = end; _value.d = start; _duration = duration; return this; } internal GTweener _Shake(Vector3 start, float amplitude, float duration) { _valueSize = 6; _startValue.vec3 = start; _startValue.w = amplitude; _duration = duration; _easeType = EaseType.Linear; return this; } internal void _Init() { _delay = 0; _duration = 0; _breakpoint = -1; _easeType = EaseType.QuadOut; _timeScale = 1; _ignoreEngineTimeScale = false; _easePeriod = 0; _easeOvershootOrAmplitude = 1.70158f; _snapping = false; _repeat = 0; _yoyo = false; _valueSize = 0; _started = false; _paused = false; _killed = false; _elapsedTime = 0; _normalizedTime = 0; _ended = 0; _path = null; _customEase = null; _smoothStart = Time.frameCount == 1 ? 3 : 1;//刚启动时会有多帧的超时 } internal void _Reset() { _target = null; _listener = null; _userData = null; _onStart = _onUpdate = _onComplete = null; _onStart1 = _onUpdate1 = _onComplete1 = null; } internal void _Update() { if (_ended != 0) //Maybe completed by seek { CallCompleteCallback(); _killed = true; return; } float dt; if (_smoothStart > 0) { _smoothStart--; dt = Mathf.Clamp(Time.unscaledDeltaTime, 0, Application.targetFrameRate > 0 ? (1.0f / Application.targetFrameRate) : 0.016f); if (!_ignoreEngineTimeScale) dt *= Time.timeScale; } else if (_ignoreEngineTimeScale) dt = Time.unscaledDeltaTime; else dt = Time.deltaTime; if (_timeScale != 1) dt *= _timeScale; if (dt == 0) return; _elapsedTime += dt; Update(); if (_ended != 0) { if (!_killed) { CallCompleteCallback(); _killed = true; } } } void Update() { _ended = 0; if (_valueSize == 0) //DelayedCall { if (_elapsedTime >= _delay + _duration) _ended = 1; return; } if (!_started) { if (_elapsedTime < _delay) return; _started = true; CallStartCallback(); if (_killed) return; } bool reversed = false; float tt = _elapsedTime - _delay; if (_breakpoint >= 0 && tt >= _breakpoint) { tt = _breakpoint; _ended = 2; } if (_repeat != 0) { int round = Mathf.FloorToInt(tt / _duration); tt -= _duration * round; if (_yoyo) reversed = round % 2 == 1; if (_repeat > 0 && _repeat - round < 0) { if (_yoyo) reversed = _repeat % 2 == 1; tt = _duration; _ended = 1; } } else if (tt >= _duration) { tt = _duration; _ended = 1; } _normalizedTime = EaseManager.Evaluate(_easeType, reversed ? (_duration - tt) : tt, _duration, _easeOvershootOrAmplitude, _easePeriod, _customEase); _value.SetZero(); _deltaValue.SetZero(); if (_valueSize == 5) { double d = _startValue.d + (_endValue.d - _startValue.d) * _normalizedTime; if (_snapping) d = Math.Round(d); _deltaValue.d = d - _value.d; _value.d = d; _value.x = (float)d; } else if (_valueSize == 6) { if (_ended == 0) { Vector3 r = UnityEngine.Random.insideUnitSphere; r.x = r.x > 0 ? 1 : -1; r.y = r.y > 0 ? 1 : -1; r.z = r.z > 0 ? 1 : -1; r *= _startValue.w * (1 - _normalizedTime); _deltaValue.vec3 = r; _value.vec3 = _startValue.vec3 + r; } else _value.vec3 = _startValue.vec3; } else if (_path != null) { Vector3 vec3 = _path.GetPointAt(_normalizedTime); if (_snapping) { vec3.x = Mathf.Round(vec3.x); vec3.y = Mathf.Round(vec3.y); vec3.z = Mathf.Round(vec3.z); } _deltaValue.vec3 = vec3 - _value.vec3; _value.vec3 = vec3; } else { for (int i = 0; i < _valueSize; i++) { float n1 = _startValue[i]; float n2 = _endValue[i]; float f = n1 + (n2 - n1) * _normalizedTime; if (_snapping) f = Mathf.Round(f); _deltaValue[i] = f - _value[i]; _value[i] = f; } _value.d = _value.x; } if (_target != null && _propType != TweenPropType.None) TweenPropTypeUtils.SetProps(_target, _propType, _value); CallUpdateCallback(); } void CallStartCallback() { if (GTween.catchCallbackExceptions) { try { if (_onStart1 != null) _onStart1(this); if (_onStart != null) _onStart(); if (_listener != null) _listener.OnTweenStart(this); } catch (Exception e) { Debug.LogWarning("FairyGUI: error in start callback > " + e.Message); } } else { if (_onStart1 != null) _onStart1(this); if (_onStart != null) _onStart(); if (_listener != null) _listener.OnTweenStart(this); } } void CallUpdateCallback() { if (GTween.catchCallbackExceptions) { try { if (_onUpdate1 != null) _onUpdate1(this); if (_onUpdate != null) _onUpdate(); if (_listener != null) _listener.OnTweenUpdate(this); } catch (Exception e) { Debug.LogWarning("FairyGUI: error in update callback > " + e.Message); } } else { if (_onUpdate1 != null) _onUpdate1(this); if (_onUpdate != null) _onUpdate(); if (_listener != null) _listener.OnTweenUpdate(this); } } void CallCompleteCallback() { if (GTween.catchCallbackExceptions) { try { if (_onComplete1 != null) _onComplete1(this); if (_onComplete != null) _onComplete(); if (_listener != null) _listener.OnTweenComplete(this); } catch (Exception e) { Debug.LogWarning("FairyGUI: error in complete callback > " + e.Message); } } else { if (_onComplete1 != null) _onComplete1(this); if (_onComplete != null) _onComplete(); if (_listener != null) _listener.OnTweenComplete(this); } } } }