using System.Collections.Generic; using UnityEngine; [ExecuteInEditMode] [AddComponentMenu("Modifiers/Morph Animator")] public class MegaMorphAnimator : MonoBehaviour { public MegaMorphBase morph; public MegaMorphBase[] morphs; public List clips = new List(); public List playing = new List(); public int current; public float t = -1f; public float at; public int sourceFPS = 30; public bool useFrames = true; private Stack clippool; public bool MultipleMorphs; public bool LinkedUpdate; public bool PlayOnStart = true; private Animation myanim; public void UpdatePlayingClips() { if (playing.Count == 0) { return; } morph.ClearBlends(); for (int num = playing.Count - 1; num >= 0; num--) { MegaPlayingClip megaPlayingClip = playing[num]; MegaMorphAnimClip megaMorphAnimClip = clips[megaPlayingClip.clipIndex]; if (megaPlayingClip.t >= 0f) { megaPlayingClip.t += Time.deltaTime * megaMorphAnimClip.speed; float num2 = megaMorphAnimClip.end - megaMorphAnimClip.start; switch (megaMorphAnimClip.loop) { case MegaRepeatMode.Loop: megaPlayingClip.at = Mathf.Repeat(megaPlayingClip.t, Mathf.Abs(num2)); if (num2 < 0f) { megaPlayingClip.at = megaMorphAnimClip.start - megaPlayingClip.at; } break; case MegaRepeatMode.PingPong: megaPlayingClip.at = Mathf.PingPong(megaPlayingClip.t, num2); break; case MegaRepeatMode.Clamp: megaPlayingClip.at = Mathf.Clamp(megaPlayingClip.t, 0f, num2); break; } megaPlayingClip.at += megaMorphAnimClip.start; if (megaPlayingClip.targetblendtime != 0f) { if (megaPlayingClip.targetblendtime > 0f) { megaPlayingClip.blendtime += Time.deltaTime; if (megaPlayingClip.blendtime >= megaPlayingClip.targetblendtime) { megaPlayingClip.targetblendtime = 0f; megaPlayingClip.weight = 1f; } else { megaPlayingClip.weight = (megaPlayingClip.targetblendtime - megaPlayingClip.blendtime) / megaPlayingClip.targetblendtime; } } else { megaPlayingClip.blendtime -= Time.deltaTime; if (megaPlayingClip.blendtime <= megaPlayingClip.targetblendtime) { megaPlayingClip.targetblendtime = 0f; megaPlayingClip.weight = 0f; } else { megaPlayingClip.weight = (megaPlayingClip.targetblendtime - megaPlayingClip.blendtime) / megaPlayingClip.targetblendtime; } } } if (megaPlayingClip.weight != 0f) { if (MultipleMorphs) { if (morphs != null) { for (int i = 0; i < morphs.Length; i++) { morphs[i].SetAnimBlend(megaPlayingClip.at, megaPlayingClip.weight); } } } else if ((bool)morph) { morph.SetAnimBlend(megaPlayingClip.at, megaPlayingClip.weight); } } else { PushClip(megaPlayingClip); playing.RemoveAt(num); } } } } [ContextMenu("Help")] public void Help() { Application.OpenURL("http://www.west-racing.com/mf/?page_id=1108"); } public bool IsPlaying() { if (t >= 0f) { return true; } return false; } public void SetTime(float time) { t = time; } public float GetTime() { return at; } public void PlayClipEvent(int i) { PlayClip(i); } public void PlayClipNameEvent(string name) { PlayClip(name); } public void PlayClip(int i) { if (i < clips.Count) { current = i; t = 0f; } } public void PlayClip(string name) { for (int i = 0; i < clips.Count; i++) { if (clips[i].name == name) { current = i; t = 0f; break; } } } public void PlayClip(int i, float blend) { if (i < clips.Count) { current = i; t = 0f; MegaPlayingClip megaPlayingClip = PopClip(); megaPlayingClip.t = 0f; megaPlayingClip.targetblendtime = blend; MegaPlayingClip megaPlayingClip2 = playing[playing.Count - 1]; megaPlayingClip2.blendtime = 0f - Mathf.Abs(megaPlayingClip2.blendtime); megaPlayingClip2.targetblendtime = 0f - blend; playing.Add(megaPlayingClip); } } public void PlayClip(string name, float blend) { for (int i = 0; i < clips.Count; i++) { if (clips[i].name == name) { PlayClip(i, blend); break; } } } public void Stop() { t = -1f; } public int AddClip(string name, float start, float end, MegaRepeatMode loop) { MegaMorphAnimClip item = new MegaMorphAnimClip(name, start, end, loop); clips.Add(item); return clips.Count - 1; } public string[] GetClipNames() { string[] array = new string[clips.Count]; for (int i = 0; i < clips.Count; i++) { array[i] = clips[i].name; } return array; } private void Start() { if (clippool == null) { clippool = new Stack(8); } if (PlayOnStart) { t = 0f; } else { t = -1f; } } private MegaPlayingClip PopClip() { return clippool.Pop(); } private void PushClip(MegaPlayingClip clip) { clippool.Push(clip); } private void Update() { DoUpdate(); } private void DoUpdate() { if (MultipleMorphs) { if (morphs == null) { morphs = GetComponentsInChildren(); } } else if (morph == null) { morph = GetComponent(); } if (LinkedUpdate) { DoLinkedUpdate(); } else { if (clips.Count <= 0 || current >= clips.Count) { return; } UpdatePlayingClips(); if (!(t >= 0f)) { return; } t += Time.deltaTime * clips[current].speed; float num = clips[current].end - clips[current].start; switch (clips[current].loop) { case MegaRepeatMode.Loop: at = Mathf.Repeat(t, num); break; case MegaRepeatMode.PingPong: at = Mathf.PingPong(t, num); break; case MegaRepeatMode.Clamp: at = Mathf.Clamp(t, 0f, num); break; } at += clips[current].start; if (MultipleMorphs) { if (morphs != null) { for (int i = 0; i < morphs.Length; i++) { morphs[i].SetAnim(at); } } } else if ((bool)morph) { morph.SetAnim(at); } } } private void DoLinkedUpdate() { if (myanim == null) { myanim = GetComponent(); } if (!(myanim != null)) { return; } foreach (AnimationState item in myanim) { if (!item.enabled) { continue; } AnimationClip clip = item.clip; if (!(clip != null)) { continue; } for (int i = 0; i < clips.Count; i++) { if (!(clips[i].name == clip.name)) { continue; } current = i; float num = item.time; if (clip.wrapMode == WrapMode.Default) { WrapMode wrapMode = myanim.wrapMode; } switch (clip.wrapMode) { case WrapMode.Loop: num = Mathf.Repeat(num, clip.length); break; case WrapMode.PingPong: num = Mathf.PingPong(num, clip.length); break; case WrapMode.ClampForever: num = Mathf.Clamp(num, 0f, clip.length); break; case WrapMode.Once: if (num > clip.length) { num = 0f; } break; } num += clips[current].start; if (MultipleMorphs) { if (morphs != null) { for (int j = 0; j < morphs.Length; j++) { morphs[j].SetAnim(at); } } } else if ((bool)morph) { morph.SetAnim(num); } return; } } } }