[Unity3d]打造⾃⼰的AnimatorEventSystem
依旧是基于链式编程思想,笔者封装了⼀个动画机回调系统,简单实⽤。在本⽂,笔者将采⽤图⽂并茂的⽅式简单的讲讲如何实现这个回调系统,⽂章结尾会提供链接下载该回调系统。
需求:
1. 指定动画机运⾏到指定层 触动指定帧上的指定事件链
2. AnimationEvent 可以指定 多参数,组合参数。
效果:
code
输出
Code
业务流程说明:
1. 获取 Animator 引⽤;
2. 上述引⽤到扩展⽅法(此⽅法2个重载):SetTarget
3. 链式编程,继续点出OnProcess ⽅法,写⼊回调逻辑(lambda或者指定签名的⽅法)
4. 链式编程,继续点出SetParm⽅法,设置这个AnimationEvent⽤到的参数(同时多参数组合),⼀般来说,如果不配合事件系统向外分发该
事件,可以不调⽤这个⽅法
5. 触发注册了该事件的的动画⽚段(AnimationClip),第三步回调将被触发。
实现:
Preview
运⽤语法糖,可以指定参数赋值
using System;
using UnityEngine;
namespace zFrame.Event
{
/// <summary>
/// 参数配置类,不建议配置任何参数,除⾮配合事件系统使⽤
/// </summary>
public class BaseEventConfig
{
protected AnimationEvent _ClipEvent;
protected int _keyFrame;
protected A_EventInfo a_Event;
protected Animator _animator;
public BaseEventConfig(A_EventInfo eventInfo, int frame)
{
_keyFrame = frame;
a_Event = eventInfo;
_animator = eventInfo.animator;
}
/// <summary>设置组合参数</summary>
/// <param name="intParm">int参数</param>
/// <param name="floatParm">float参数</param>
/// <param name="stringParm">string参数(必填)</param>
/// <param name="objectParm">Object参数</param>
/// <returns></returns>
public Animator SetParms(string stringParm, int intParm = default(int), float floatParm = default(float), UnityEngine.Object objectParm = default(UnityEngine.Object)) {
if (null == a_Event){ return _animator;}
AnimationEvent _ClipEvent;
a_Event.frameEventPairs.TryGetValue(_keyFrame, out _ClipEvent);
if (null == _ClipEvent){ return _animator; }
_ClipEvent.intParameter = intParm;
_ClipEvent.floatParameter = floatParm;
_ClipEvent.stringParameter = stringParm;
_ClipEvent.objectReferenceParameter = objectParm;
ResignEvent();
return a_Event.animator;
}
/// <summary>
/// 参数被变更,需要重新绑定所有的事件
/// </summary>
private void ResignEvent()
{
{
a_Event.animationClip.events = default(AnimationEvent[]); //被逼的,AnimationEvent不是简单的对象引⽤及其字段修改的问题,只能从新插⼊事件
foreach (AnimationEvent item in a_Event.frameEventPairs.Values)
{
a_Event.animationClip.AddEvent(item);
}
a_Event.animator.Rebind();
}
/// <summary>
/// 为指定帧加⼊回调链
/// </summary>
/// <param name="frame"></param>
/// <param name="action"></param>
protected void ConfigProcess(int frame, Action<AnimationEvent> action)
{
if (null == action) return;
_keyFrame = frame;
if (!a_Event.frameCallBackPairs.ContainsKey(_keyFrame))
{
a_Event.frameCallBackPairs.Add(_keyFrame, action);
}
else
{
Action<AnimationEvent> t_action = a_Event.frameCallBackPairs[_keyFrame];
if (null == t_action)
{
a_Event.frameCallBackPairs[_keyFrame] = action;
}
else
{
Delegate[] delegates = t_action.GetInvocationList();
if (Array.IndexOf(delegates, action) == -1)
{
a_Event.frameCallBackPairs[_keyFrame] += action;
}
else
{
Debug.LogWarningFormat("AnimatorEventSystem[⼀般]:指定AnimationClip【{0}】已经订阅了该事件【{1}】!\n 建议:请勿频繁订阅!", a_Event.animationCli }
}
}
if (!a_Event.frameEventPairs.ContainsKey(_keyFrame))
{
A_EventHandler.Handler.GenerAnimationEvent(a_Event, _keyFrame);
}
}
#region Adapter For Animatorunity3d animation
/// <summary>
/// 设置动画机bool参数
/// </summary>
/
// <param name="name">参数名</param>
/// <param name="value">参数值</param>
/// <returns></returns>
public Animator SetBool(string name, bool value)
{
_animator.SetBool(name, value);
return _animator;
}
/// <summary>
/// 设置动画机bool参数
/// </summary>
/
// <param name="name">参数id</param>
/// <param name="value">参数值</param>
/// <returns></returns>
public Animator SetBool(int id, bool value)
{
_animator.SetBool(id, value);
return _animator;
}
/// <summary>
/// 设置动画机float参数
/// </summary>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论