Unity Animator 封装(更新中)
ani.OnPlay(“Jump”).OnTriggerEvent(() => {//处理触发事件;3、等待动画播放进度到0.5f。4、动画播放进度到0.5f执行。处理animator动画播放。1、等待动画播放完成。2、动画播放完成执行。
·
处理animator动画播放
1、等待动画播放完成
yield return ani.OnPlay(“Idle”).OnWaitComplete();
2、动画播放完成执行
ani.OnPlay(“Idle”).OnComplete(() => xxx.SetActive(false));
3、等待动画播放进度到0.5f
yield return ani.OnPlay(“Idle”).OnWaitProgress(0.5f);
4、动画播放进度到0.5f执行
ani.OnPlay(“Idle”).OnProgress(()=> { xxx.SetActive(false)}, 0.5f);
5、触发事件
ani.OnPlay(“Jump”).OnTriggerEvent(() => { //处理触发事件; }, “JumpEventName”);
using UnityEngine;
using System;
using System.Collections;
using System.Threading.Tasks;
/// <summary>
/// Animator功能拓展
/// </summary>
public static class BXAnimatorUtil
{
#region 状态
/// <summary>
/// 是否为激活状态
/// </summary>
public static bool IsActive(this Animator ani)
{
return ani.gameObject ? ani.gameObject.activeSelf : false;
}
/// <summary>
/// 设置激活状态
/// </summary>
public static void SetActive(this Animator ani, bool value)
{
ani.gameObject?.SetActive(value);
}
#endregion
#region 播放动画
/// <summary>
/// 播放动画-nameHash
/// </summary>
public static Animator OnPlay(this Animator ani, int nameHash)
{
ani?.Play(nameHash);
return ani;
}
/// <summary>
/// 异步播放动画-nameHash
/// </summary>
public static Animator OnAsyncPlay(this Animator ani, int nameHash)
{
ani.AsyncPlay(nameHash);
return ani;
}
/// <summary>
/// 异步播放动画-nameHash
/// </summary>
public static async void AsyncPlay(this Animator ani, int nameHash)
{
await new WaitForEndOfFrame();
ani?.Play(nameHash);
}
#endregion
#region 播放动画
/// <summary>
/// 播放动画
/// </summary>
public static Animator OnPlay(this Animator ani, string name)
{
ani?.Play(name);
return ani;
}
/// <summary>
/// 异步播放动画
/// </summary>
public static Animator OnAsyncPlay(this Animator ani, string name)
{
ani.AsyncPlay(name);
return ani;
}
/// <summary>
/// 异步播放动画
/// </summary>
public static async void AsyncPlay(this Animator ani, string name)
{
await new WaitForEndOfFrame();
ani?.Play(name);
}
#endregion
#region 动画播放进度
/// <summary>
/// 等待动画播放完成
/// </summary>
public static Task OnWaitComplete(this Animator ani)
{
return PlayCallBack(ani);
}
/// <summary>
/// 动画播放完成
/// </summary>
public static void OnComplete(this Animator ani, Action call)
{
if (ani == null || call == null) return;
PlayCallBack(ani, call);
}
/// <summary>
/// 等待动画播放进度
/// </summary>
/// <param name="ani">动画控制器</param>
/// <param name="progress">动画播放进度0-1</param>
public static Task OnWaitProgress(this Animator ani, float progress)
{
return PlayCallBack(ani, null, progress);
}
/// <summary>
/// 动画播放进度
/// </summary>
/// <param name="ani">动画控制器</param>
/// <param name="progress">动画播放进度0-1</param>
public static void OnProgress(this Animator ani, Action call, float progress)
{
if (ani == null) return;
PlayCallBack(ani, call, progress);
}
/// <summary>
/// 动画播放进度回调
/// </summary>
static async Task PlayCallBack(Animator ani, Action call = null, float progress = 1)
{
await new WaitForEndOfFrame();
if (ani != null)
{
var clipInfo = ani.GetCurrentAnimatorStateInfo(0);
await new WaitForSecondsRealtime(clipInfo.length * progress);
}
call?.Invoke();
}
#endregion
#region 当前动画播放进度
/// <summary>
/// 当前动画播放完成
/// </summary>
public static void OnCurrentComplete(this Animator ani, Action call)
{
if (ani == null || call == null) return;
PlayCurrentCallBack(ani, call);
}
/// <summary>
/// 当前动画播放进度回调
/// </summary>
static async void PlayCurrentCallBack(Animator ani, Action call = null)
{
await new WaitForEndOfFrame();
if (ani != null)
{
var clipInfo = ani.GetCurrentAnimatorStateInfo(0);
var time = clipInfo.length * (1 - clipInfo.normalizedTime);
await new WaitForSecondsRealtime(time);
}
call?.Invoke();
}
#endregion
#region 动画触发事件
/// <summary>
///动画触发事件
/// </summary>
public static Animator OnTriggerEvent(this Animator ani, Action call, string eventName)
{
if (ani != null)
{
ani.fireEvents = false;
TriggerCallBack(ani, call, eventName);
}
return ani;
}
/// <summary>
/// 动画触发事件回调
/// </summary>
static async void TriggerCallBack(Animator ani, Action call, string eventName)
{
await new WaitForEndOfFrame();
if (ani != null)
{
float progress = GetCurEventProgress(ani, eventName);
if (progress != -1)
{
var curState = ani.GetCurrentAnimatorStateInfo(0);
if (curState.loop)//循环触发
{
TriggerCallBackLoop(ani, curState, call, progress);
}
else//单次触发
{
await new WaitForSecondsRealtime(curState.length * progress);
call?.Invoke();
}
}
else
{
Debug.LogError($"Animator ani don't have AnimationEvent {eventName}");
}
}
}
/// <summary>
/// Animation loop触发事件
/// </summary>
static async void TriggerCallBackLoop(Animator ani, AnimatorStateInfo lastState, Action call, float progress)
{
await new WaitForEndOfFrame();
bool loop = lastState.loop;
while (loop)
{
await new WaitForSecondsRealtime(lastState.length * progress);
if (ani.GetCurrentAnimatorStateInfo(0).fullPathHash == lastState.fullPathHash) call?.Invoke();
await new WaitForSecondsRealtime(lastState.length * (1 - progress));
loop = lastState.loop && ani.GetCurrentAnimatorStateInfo(0).fullPathHash == lastState.fullPathHash;
}
}
#endregion
/// <summary>
/// 获取Animator当前动画event.time
/// </summary>
public static float GetCurEventProgress(Animator ani, string mathName)
{
var curClip = ani.GetCurrentAnimatorClipInfo(0);
if (curClip == null || curClip.Length <= 0) return -1;
AnimationClip clip = curClip[0].clip;
if (clip == null || clip.events.Length <= 0) return -1;
AnimationEvent[] events = clip.events;
for (int i = 0; i < events.Length; i++)
{
if (events[i].functionName == mathName)
{
return events[i].time;
}
}
return -1;
}
}
更多推荐
所有评论(0)