Awesome
<a id="chinese">English</a>
Unity-MecanimEventSystem
Animator 事件回调系统
简述
- 这是一个非常实用的,链式编程风格的 Animator 事件系统。
- 通过 方法扩展 的方式实现了对 Animator 的功能扩展
- 现在你能直接使用 Animator.SetTarget(clipname,frame) 指定在哪一个动画片段的哪一帧上插入事件。
- 解决了必须手动插入AnimationEvent的痛点,同时链式+ Lambda 使得逻辑更集中更优雅,也方便阅读和理解。
- 支持 await/async 语法糖调用, 请参考:AnimatorAwaitEx
插入的事件分2个:
API | Description |
---|---|
OnProcess | 在动画片段用户指定帧执行的回调 |
OnCompleted | 在动画片段结束帧执行的回调 |
使用实例
- 在中间帧
animator.SetTarget("Left", 55) //1. 拿到 Animator 引用
.OnProcess((v) => //2. 拆入事件到 55帧
{
string clipname = v.animatorClipInfo.clip.name; //3.拿到动画片段信息--------片段名称
if (v.animatorStateInfo.IsName("Base Layer.Rotate") //4.拿到动画状态信息--------状态名称
{
Debug.Log("结束时Base Layer:" + clipname + ":" + v.time * v.animatorClipInfo.clip.frameRate); //5. 基于上面的信息做层别以及其他逻辑
}
if (v.animatorStateInfo.IsName("New Layer.Rotate1212"))//演示其它层的事件接受
{
Debug.Log("结束时New Layer:" + clipname + ":" + v.time * v.animatorClipInfo.clip.frameRate);
}
})
.SetParms("ddsf", objectParm: gameObject) //6. 演示在事件中放置参数,但闭包优势,参数均在上下文,所以可以不设置参数
.SetTrigger("Left"); // 7. 适配器--适配了Animator API 可以链式操控动画机
- 在结束帧
animator.SetTarget("Rotate")
.OnCompleted((v) =>
{
//Do something when finished
});
- 使用 async / await
// 这里做一些事情,比如本例中按钮的可交互性改为:false
button.interactable = false;
var r = await animator.SetBoolAsync("Expand","Expand", false); // todo: 必须细分到 layer.state 这种级别,否则误触会很伤
text.text = "collapsed";
// 这里做一些收尾,比如为 text 赋值 或者 将按钮变为可交互
动画演示
演示了动态新增事件到动画片段指定帧、叠加事件到同一帧、复用动画片段事件层别(Rotate动画片段复用,通过Layer 输出看到层别效果)
演示了通过 await 实现对流程控制的优雅把控
todo
- 将参数内敛到一个类型中并绘制到面板在面板上
将对 EventState 的扩展改为对 Animator 的扩展- 整理为 UPM 插件包形式
我的简书
Unity 3D 打造自己的Mecanim Callback System - 简书 - 仓库逻辑为准
<a id="english">简体中文</a>
Unity-MecanimEventSystem
Animator Event Callback System
Overview
-
This is a highly practical, chain-programming style Animator event system that extends the functionality of the Animator through method extensions.
-
With this system, you can now directly use
Animator.SetTarget(clipname,frame)
to specify which frame of an animation clip to insert an event. This solves the pain point of having to manually insertAnimationEvents
, while the chain + Lambda approach makes the logic more concentrated, elegant, and easy to read and understand. -
The system supports
await/async
syntactic sugar calls. you can implemented fit your needs see ref AnimatorAwaitEx.
The inserted events are divided into two types:
API | Description |
---|---|
OnProcess | Callback executed on the user-specified frame of the animation clip |
OnCompleted | Callback executed on the end frame of the animation clip |
Usage Examples
In the Middle Frame
animator.SetTarget("Left", 55) // 1. Get Animator reference
.OnProcess((v) => // 2. Insert event at frame 55
{
string clipname = v.animatorClipInfo.clip.name; // 3. Get animation clip information - clip name
if (v.animatorStateInfo.IsName("Base Layer.Rotate") // 4. Get animation state information - state name
{
Debug.Log("End Base Layer:" + clipname + ":" + v.time * v.animatorClipInfo.clip.frameRate); // 5. Based on the above information, perform layer and other logic
}
if (v.animatorStateInfo.IsName("New Layer.Rotate1212"))// Demonstrate event acceptance on other layers
{
Debug.Log("End New Layer:" + clipname + ":" + v.time * v.animatorClipInfo.clip.frameRate);
}
})
.SetParms("ddsf", objectParm: gameObject) // 6. Demonstrate placing parameters in events, but due to closure advantages, parameters are in context, so you can not set parameters
.SetTrigger("Left"); // 7. Adapter - adapted Animator API for chain control of animation machine
On the End Frame
animator.SetTarget("Rotate")
.OnCompleted((v) =>
{
// Do something when finished
});
Using async / await
// Do something here, such as changing the interactivity of the button in this example to: false
button.interactable = false;
var r = await animator.SetBoolAsync("Expand","Expand", false); //todo :Maybe the syntax "layer.StateName" is good.
text.text = "collapsed";
// Do some finishing touches here, such as assigning values to text or making buttons interactive
Animations
Demonstrates the dynamic addition of events to the specified frame of the animation clip, superimposition of events to the same frame, and multiplexing of the animation clip event layer (Rotate animation clip multiplexing, see the layer effect through the Layer output)
Demonstrates the elegant control of process control through await
To-Do List
- Inline parameters into a type and draw them on the inspector.
Change the extension ofEventState
to an extension ofAnimator
.- Organize into UPM package form.
Reference
Unity 3D 打造自己的Mecanim Callback System - 简书 - Please follow the logic of the repository.