用animator控制animation並記錄正播倒播
//父級指令碼,掛在animator上
using UnityEngine;
using System.Collections;public class UIAnimatorParent : MonoBehaviour
{
//父級指令碼
//控制動畫時長
float animTime = 0.1f;
//停止時間
float stopTime = 0f;
//是否開始播放動畫
bool isStart = false;
public bool isBacking = false;
Animator animator;
string nextAnim;
public string playName = "";
private UIAnimator[] allUIA;
void Awake()
{
animator = this.transform.GetComponent<Animator>();
allUIA = transform.GetComponentsInChildren<UIAnimator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Z))
{
PlayAnimation(playName, 1);
}
if (isBacking)
{
stopTime -= Time.deltaTime;
//Debug.Log(animator.playbackTime);
if (stopTime <= 0f)
{
isBacking = false;
animator.StopPlayback();
isStart = false;
if (string.IsNullOrEmpty(nextAnim))
{
}
else
{
PlayAnimation(nextAnim, 1);
nextAnim = null;
}
}
return;
}
//判斷播放時長是否大於最大動畫時長
if (isStart)
{
if (stopTime > animTime)
{
AllStoped();
}
else
{
stopTime += Time.deltaTime;
}
}
}
//全部結束
public void AllStoped()
{
isStart = false;
stopTime = 0;
animTime = 0.1f;
//animator.CrossFade("default", 0);
animator.StopPlayback();
animator.StopRecording();
animator.Stop();
animator.enabled = false;
for (int i = 0; i < allUIA.Length; i++)
{
allUIA[i].StopAnimation();
}
if (stopDelegate != null)
{
if (callDelegateName == playName)
{
stopDelegate();
ClearDelegate();
}
}
//所有動畫播放完畢回撥,動畫播放完畢後開始正式執行邏輯
}
int lastPlayType = 1;
public delegate void animStoped();
animStoped stopDelegate;
string callDelegateName;
//清除結束回撥
public void ClearDelegate()
{
stopDelegate = null;
callDelegateName = null;
}
//播放動畫
public void PlayAnimation(string _playName, int type = 1,animStoped delega = null)
{
playName = _playName;
if (lastPlayType == 2)
{
AllStoped();
}
if (delega != null)
{
callDelegateName = playName;
stopDelegate = delega;
}
animator.enabled = true;
if (type == 1)
{
float speed = 1f;
if (!isStart)
{
animator.Play(playName, 0, 0);
animator.StartRecording(60);
speed = 1f;
StartCoroutine(PlayNext(type));
}
else
{
animator.playbackTime = stopTime;
animator.StopRecording();
animator.StartPlayback();
UIAnimator[] animtionList = transform.GetComponentsInChildren<UIAnimator>();
for (int i = 0; i < animtionList.Length; i++)
{
if (animtionList[i].ani.isPlaying)
{
animtionList[i].ani[animtionList[i].animaName].speed = -1;
}
}
isBacking = true;
nextAnim = playName;
speed = -1f;
}
animator.speed = speed;
isStart = true;
}
else if (type == 2)
{
lastPlayType = 2;
animator.Play(playName, 0, 0);
isStart = true;
StartCoroutine(PlayNext(type));
}
}
//下幀執行,因為動畫play後動畫在下幀才播放
public IEnumerator PlayNext(int type)
{
yield return GamePresident.Instance.oneFrame;
JudgeTime(animator.GetCurrentAnimatorClipInfo(0)[0].clip.length, type);
}
//判斷子動畫時間是否大於整個動畫時長
public void JudgeTime(float time, int type = 0)
{
//大於則重新整理
if (stopTime + time > animTime)
{
animTime = stopTime + time;
}
}
}
//子指令碼,掛在animation上
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class UIAnimatorInformation
{
public string parentPlayName;
public string playName;
}
[RequireComponent(typeof(Animation))]
public class UIAnimator : MonoBehaviour
{
//父級控制指令碼
public UIAnimatorParent animParent;
//父級控制的動畫
public Animation ani;
UIAnimator uiani;
//當動畫有多個的時候啟用
public List<UIAnimatorInformation> animNameList = new List<UIAnimatorInformation>();
//動畫時長
float animfloat;
//此動畫名稱
public string animaName;
// Use this for initialization
void Awake()
{
ani = this.GetComponent<Animation>();
uiani = this.GetComponent<UIAnimator>();
AnimationClip aniClip = ani.clip;
//獲取子動畫時長
//AnimationEvent ae = new AnimationEvent();
animParent = transform.GetComponentInParent<UIAnimatorParent>();
//ae.time = aniClip.length;
////增加子動畫結束回撥
//ae.functionName = "Stoped";
//aniClip.AddEvent(ae);
}
void Start()
{
}
// Update is called once per frame
void Update()
{
}
//結束回撥
public void AnimStoped()
{
Debug.Log("AnimStoped!");
StopAnimation();
}
//全播完後執行此方法
public void StopAnimation()
{
ani.enabled = false;
uiani.enabled = false;
}
//控制指令碼開關來控制播放
void OnEnable()
{
ani.enabled = true;
if (animNameList.Count > 0)
{
for (int i = 0; i < animNameList.Count; i++)
{
if (animNameList[i].parentPlayName == animParent.playName)
{
animaName = animNameList[i].playName;
}
}
}
if (animParent.isBacking)
{
ani[animaName].speed = -1;
}
else
{
ani[animaName].speed = 1;
animParent.JudgeTime(ani.GetClip(animaName).length);
}
ani.Play(animaName,PlayMode.StopAll);
//判斷此子動畫的時長從播放到結束是否大於其他所有動畫的時長
}
public void ClearEvents()
{
ani.GetClip(animaName).events = null;
}
}
//Editor下
//基本字面意思,子物體建立好animation後直接點選我要新增控制子動畫指令碼
//多個的時候要在子指令碼上新增每個動畫所屬animatorClip的名字
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
public class AddAnimatorControlInspector : Editor
{
public override void OnInspectorGUI()
{
base.DrawDefaultInspector();
if (GUILayout.Button("我要新增控制子動畫指令碼!"))
{
Animator parent = (Animator)base.target;
Animation[] animationList = parent.GetComponentsInChildren<Animation>();
UIAnimatorParent uiaParent = parent.GetComponent<UIAnimatorParent>();
if (uiaParent == null)
{
parent.gameObject.AddComponent<UIAnimatorParent>();
}
for (int i = 0; i < animationList.Length; i++)
{
Animation anim = animationList[i];
UIAnimator uia = anim.transform.GetComponent<UIAnimator>();
uia.ani = anim;
uia.animaName = anim.clip.name;
int cc = 0;
foreach (AnimationState state in anim)
{
if (uia.animNameList.Count > cc)
{
uia.animNameList[cc].playName = state.name;
cc++;
}
else
{
uia = anim.gameObject.AddComponent<UIAnimator>();
}
//uia.ClearEvents();
//bool haveStop = false;
//for (int j = 0; j < state.clip.events.Length; j++)
//{
// AnimationEvent ste = state.clip.events[j];
// if (ste.functionName == "AnimStoped")
// {
// haveStop = true;
// }
//}
//if (!haveStop)
//{
// AnimationEvent ae = new AnimationEvent();
// ae.time = state.clip.length;
// //增加子動畫結束回撥
// ae.functionName = "AnimStoped";
// AnimationEvent[] aes = { };
// AnimationUtility.SetAnimationEvents(state.clip, aes);
//}
}
if (uia.animNameList.Count > cc)
{
for (int j = cc; j < uia.animNameList.Count; j++)
{
uia.animNameList.RemoveAt(j);
}
}
}
}
if (GUILayout.Button("重置所有元件!"))
{
Animator parent = (Animator)base.target;
Animation[] animationList = parent.GetComponentsInChildren<Animation>();
UIAnimator[] uiaList = parent.transform.GetComponentsInChildren<UIAnimator>();
parent.enabled = false;
for (int i = 0; i < animationList.Length; i++)
{
animationList[i].enabled = false;
animationList[i].playAutomatically = false;
}
for (int i = 0; i < uiaList.Length; i++)
{
uiaList[i].enabled = false;
}
}
}
}
[CanEditMultipleObjects()]
[CustomEditor(typeof(Animator), true)]
public class AddAnimatorControlInspectorP : AddAnimatorControlInspector
{
}
//子Editor
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
public class ChangeAnimationInspector : Editor
{
public override void OnInspectorGUI()
{
base.DrawDefaultInspector();
if (GUILayout.Button("我要修改子動畫!"))
{
Animation thisTransform = (Animation)base.target;
SaveChangeAnimatorInfo saInfo = thisTransform.transform.GetComponentInChildren<SaveChangeAnimatorInfo>();
GameObject gobjParent;
if (saInfo == null)
{
gobjParent = new GameObject("gobjParent!");
saInfo = gobjParent.AddComponent<SaveChangeAnimatorInfo>();
gobjParent.transform.SetParent(thisTransform.transform);
}
else
{
gobjParent = saInfo.gameObject;
}
Animator[] animList = thisTransform.GetComponentsInParent<Animator>();
for (int i = 0; i < animList.Length; i++)
{
GameObject gobj = new GameObject("gobj");
gobj.transform.SetParent(gobjParent.transform);
UnityEditorInternal.ComponentUtility.CopyComponent(animList[i]);
UnityEditorInternal.ComponentUtility.PasteComponentAsNew(gobj);
ChangeAnimatorInfomation caiInfo = gobj.AddComponent<ChangeAnimatorInfomation>();
caiInfo.belongTo = animList[i].gameObject;
DestroyImmediate(animList[i]);
}
}
if (GUILayout.Button("我要還原!"))
{
Animation thisTransform = (Animation)base.target;
SaveChangeAnimatorInfo[] saInfoList = thisTransform.transform.GetComponentsInChildren<SaveChangeAnimatorInfo>();
for (int i = 0; i < saInfoList.Length; i++)
{
ChangeAnimatorInfomation[] mationList = saInfoList[i].transform.GetComponentsInChildren<ChangeAnimatorInfomation>();
for (int j = 0; j < mationList.Length; j++)
{
if (mationList[j].belongTo != null)
{
UnityEditorInternal.ComponentUtility.CopyComponent(mationList[j].transform.GetComponent<Animator>());
Animator componentOld = mationList[j].belongTo.GetComponent<Animator>();
if (!componentOld)
{
UnityEditorInternal.ComponentUtility.PasteComponentAsNew(mationList[j].belongTo);
}
else
{
UnityEditorInternal.ComponentUtility.PasteComponentValues(componentOld);
}
}
DestroyImmediate(mationList[j].gameObject);
}
DestroyImmediate(saInfoList[i].gameObject);
}
}
}
}
[CanEditMultipleObjects()]
[CustomEditor(typeof(Animation), true)]
public class ChangeAnimationInspectorP : ChangeAnimationInspector
{
}