一个用于Cocos Creator的可视化动画状态机编辑器。
一个用于Cocos Creator的可视化动画状态机编辑器。
编辑器地址:https://leeyip.github.io/cocos-animator/
当动画数量较多且转换规则复杂的时候,手动编写代码去处理转换逻辑会非常痛苦。用过Unity的话,都知道Unity的Animator Controller能可视化地编辑状态机,在一定程度上减轻了手写逻辑的痛苦,但是Cocos Creator目前没有提供这种便利的工具,于是便有了这个项目。
动手之前,在网上看到已经有人做了一个这种工具[1],但离我想要的效果差了一点,以及runtime的实现也有一些问题,同时我也希望能随时根据需求自由更改功能,于是便用Cocos Creator另写了一个状态机编辑器,runtime的实现也在他的基础上进行了修改。
操作基本和Unity Animator类似
编辑器界面分为三个部分
用于编辑状态机参数,可填写初始值表示状态机开始运行时的参数状态
用于编辑状态以及连线数据
{
/** 编辑器版本号 */
animator: string;
parameters: [
{
/** 参数名 */
param: string;
/** 参数类型 */
type: ParamType;
/** 初始值 */
init: number;
}
];
mainStateMachine: {
layerPos: [number, number];
layerScale: number;
anyStatePos: [number, number];
subStates: string[];
subStateMachines: string[];
};
subStateMachines: [
{
/** 此状态机视图坐标 */
layerPos: [number, number];
/** 此状态机视图缩放 */
layerScale: number;
/** 此状态机视图内AnyState坐标 */
anyStatePos: [number, number];
/** 状态机名 **/
name: string;
/** 在父状态机视图下的坐标 */
position: [number, number];
/** 父状态机 **/
upStateMachine: string;
/** 在此状态机视图内父状态机的坐标 */
upStateMachinePos: [number, number];
/** 子状态 */
subStates: string[];
/** 子状态机 */
subStateMachines: string[];
}
];
defaultState: string;
anyState: {
transitions: [
{
toState: string;
hasExitTime: boolean;
conditions: [
{
param: string;
value: number;
logic: LogicType;
}
]
}
]
};
states: [
{
/** 在父状态机视图下的坐标 */
position: [number, number];
/** 父状态机 **/
upStateMachine: string;
/** 状态名 */
state: string;
/** 动画名 */
motion: string;
/** 动画播放速度 */
speed: number;
/** 动画播放速度混合参数 */
multiplier: string;
/** 动画是否循环播放 */
loop: boolean;
/** 转向别的状态的连线 */
transitions: [
{
/** 目标状态名 */
toState: string;
/** 是否需等动画播放完毕才可转换 */
hasExitTime: boolean;
/** 转换需满足的参数条件 */
conditions: [
{
/** 此条件对应的参数名 */
param: string;
/** 此条件对应的值 */
value: number;
/** 此条件与值比较的逻辑 */
logic: LogicType;
}
]
}
]
}
];
}
{
parameters: [
{
param: string;
type: ParamType;
init: number;
}
];
defaultState: string;
anyState: {
transitions: [
{
toState: string;
hasExitTime: boolean;
conditions: [
{
param: string;
value: number;
logic: LogicType;
}
]
}
]
};
states: [
{
state: string;
motion: string;
speed: number;
multiplier: string;
loop: boolean;
transitions: [
{
toState: string;
hasExitTime: boolean;
conditions: [
{
param: string;
value: number;
logic: LogicType;
}
]
}
]
}
];
}
只要将对应版本的runtime整个文件夹丢入项目中即可使用。 core中是runtime的核心实现,而AnimatorAnimation、AnimatorSpine、AnimatorDragonBones、AnimatorCustomization是用于与节点绑定的cc.Component脚本,分别用于不同类型的动画。
Animator脚本组件 API
属性
extraMulti
统一控制所有动画播放速度的参数curStateName
当前状态名curStateMotion
当前动画名animComplete
当前动画是否播放完毕方法
onInit
手动初始化状态机manualUpdate
手动调用更新setBool
设置boolean类型参数的值getBool
获取boolean类型参数的值setNumber
设置number类型参数的值getNumber
获取number类型参数的值setTrigger
设置trigger类型参数的值resetTrigger
重置trigger类型参数的值autoTrigger
设置autoTrigger类型参数的值play
无视条件直接跳转状态,如果当前已处于此状态则重置状态this.Animator.setNumber('speed', this.speed);
this.Animator.setTrigger('hit');
// 单个状态的逻辑控制类
export default class SheepIdle extends AnimatorStateLogic {
public onEntry() {
cc.log('idle entry');
}
public onUpdate() {
cc.log('idle update');
}
public onExit() {
cc.log('idle exit');
}
}
let map: Map<string, AnimatorStateLogic> = new Map();
map.set('sheep_idle', new SheepIdle());
map.set('sheep_run', new SheepRun());
map.set('sheep_hit', new SheepHit(this));
this.Animator.onInit(map);
this.Animator.onInit((fromState: string, toState: string) => {
cc.log(`state change: ${fromState} -> ${toState}`);
});
/**
* 自定义控制动画播放的接口
*/
export interface AnimationPlayer {
/** 设置动画播放结束的回调 */
setFinishedCallback(callback: () => void, target: any): void;
/** 播放动画 */
playAnimation(animName: string, loop: boolean): void;
/** 缩放动画播放速率 */
scaleTime(scale: number): void;
}
this.Animator.onInit(AnimationPlayer);
AnimatorSpine为主状态机,trackindex为0,负责播放walk、run、jump三个动画 AnimatorSpineSecondary为次状态机,trackindex为1,负责播放shoot动画 编辑好两个不同的状态机,运行时便可将实现播放别的动画的同时开枪 ps:但实际项目中如果需要使用并行状态机往往比这会复杂很多,很可能需要你自行修改runtime的实现