cocos-animator/animator-runtime/core/AnimatorBase.ts
2021-01-19 22:30:12 +08:00

229 lines
6.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import AnimatorController from "./AnimatorController";
import AnimatorState from "./AnimatorState";
import AnimatorStateLogic from "./AnimatorStateLogic";
const { ccclass, property, executionOrder } = cc._decorator;
/**
* 自定义控制动画播放的接口
*/
export interface AnimationPlayer {
/** 设置动画播放结束的回调 */
setFinishedCallback(callback: (event: cc.Event.EventCustom) => void, target?: any): void;
/** 播放动画 */
playAnimation(animName: string, loop: boolean): void;
/** 缩放动画播放速率 */
scaleTime(scale: number): void;
}
/**
* 状态机组件基类 优先执行生命周期
*/
@ccclass
@executionOrder(-1000)
export default class AnimatorBase extends cc.Component {
@property({ type: cc.JsonAsset, tooltip: CC_DEV && '状态机json文件' })
protected AssetRawUrl: cc.JsonAsset = null;
@property({ tooltip: CC_DEV && '是否在onLoad中自动启动状态机' })
protected PlayOnLoad: boolean = true;
@property({ tooltip: CC_DEV && '是否在update中自动触发状态机逻辑更新' })
protected AutoUpdate: boolean = true;
/** 是否初始化 */
protected _hasInit: boolean = false;
/** 状态机控制 */
protected _ac: AnimatorController = null;
/** 各个状态逻辑控制key为状态名 */
protected _stateLogicMap: Map<string, AnimatorStateLogic> = null;
/** 状态切换时的回调 */
protected _onStateChangeCall: (fromState: string, toState: string) => void = null;
/** 自定义的动画播放控制器 */
protected _animationPlayer: AnimationPlayer = null;
public get curStateName(): string {
return this._ac.curState.name;
}
public get curStateMotion(): string {
return this._ac.curState.motion;
}
/**
* 手动初始化状态机可传入0-3个参数类型如下
* - onStateChangeCall 状态切换时的回调
* - stateLogicMap 各个状态逻辑控制
* - animationPlayer 自定义动画控制
* @virtual
*/
public onInit(...args: Array<Map<string, AnimatorStateLogic> | ((fromState: string, toState: string) => void) | AnimationPlayer>) {
}
/**
* 处理初始化参数
*/
protected initArgs(...args: Array<Map<string, AnimatorStateLogic> | ((fromState: string, toState: string) => void) | AnimationPlayer>) {
args.forEach((arg) => {
if (!arg) {
return;
}
if (typeof arg === 'function') {
this._onStateChangeCall = arg;
} else if (typeof arg === 'object') {
if (arg instanceof Map) {
this._stateLogicMap = arg;
} else {
this._animationPlayer = arg;
this._animationPlayer.setFinishedCallback(this.onAnimFinished, this);
}
}
});
}
private updateAnimator() {
// 混合当前动画播放速度
let playSpeed = this._ac.curState.speed;
if (this._ac.curState.multi) {
playSpeed *= this._ac.params.getNumber(this._ac.curState.multi) || 1;
}
this.scaleTime(playSpeed);
// 更新AnimatorStateLogic
if (this._stateLogicMap) {
let curLogic = this._stateLogicMap.get(this._ac.curState.name);
curLogic && curLogic.onUpdate();
}
// 更新状态机逻辑
this._ac.updateAnimator();
}
protected update() {
if (this._hasInit && this.AutoUpdate) {
this.updateAnimator();
}
}
/**
* 手动调用更新
*/
public manualUpdate() {
if (this._hasInit && !this.AutoUpdate) {
this.updateAnimator();
}
}
/**
* 解析状态机json文件
*/
protected initJson(json: any) {
this._ac = new AnimatorController(this, json);
}
/**
* 动画结束的回调
*/
protected onAnimFinished() {
this._ac.onAnimationComplete();
}
/**
* 播放动画
* @virtual
* @param animName 动画名
* @param loop 是否循环播放
*/
protected playAnimation(animName: string, loop: boolean) {
}
/**
* 缩放动画播放速率
* @virtual
* @param scale 缩放倍率
*/
protected scaleTime(scale: number) {
}
/**
* 状态切换时的逻辑(状态机内部方法,不能由外部直接调用)
*/
public onStateChange(fromState: AnimatorState, toState: AnimatorState) {
if (toState.motion && toState.motion !== "") {
this.playAnimation(toState.motion, toState.loop);
}
let fromStateName = fromState ? fromState.name : '';
if (this._stateLogicMap) {
let fromLogic = this._stateLogicMap.get(fromStateName);
fromLogic && fromLogic.onExit();
let toLogic = this._stateLogicMap.get(toState.name);
toLogic && toLogic.onEntry();
}
this._onStateChangeCall && this._onStateChangeCall(fromStateName, toState.name);
}
/**
* 设置boolean类型参数的值
*/
public setBool(key: string, value: boolean) {
this._ac.params.setBool(key, value);
}
/**
* 获取boolean类型参数的值
*/
public getBool(key: string): boolean {
return this._ac.params.getBool(key) !== 0;
}
/**
* 设置number类型参数的值
*/
public setNumber(key: string, value: number) {
this._ac.params.setNumber(key, value);
}
/**
* 获取number类型参数的值
*/
public getNumber(key: string): number {
return this._ac.params.getNumber(key);
}
/**
* 设置trigger类型参数的值
*/
public setTrigger(key: string) {
this._ac.params.setTrigger(key);
}
/**
* 重置trigger类型参数的值
*/
public resetTrigger(key: string) {
this._ac.params.resetTrigger(key);
}
/**
* 设置autoTrigger类型参数的值autoTrigger类型参数不需要主动reset每次状态机更新结束后会自动reset
*/
public autoTrigger(key: string) {
this._ac.params.autoTrigger(key);
}
/**
* 无视条件直接跳转状态
* @param 状态名
*/
public play(stateName: string) {
if (!this._hasInit) {
return;
}
this._ac.play(stateName);
}
}