185 lines
5.3 KiB
TypeScript
Raw Normal View History

2022-08-26 16:48:17 +08:00
import { CoroutineV2 } from "../../CatanEngine/CoroutineV2/CoroutineV2";
const { ccclass, property, requireComponent, menu, executeInEditMode } = cc._decorator;
// /** Clipname */
// export enum Clipname {
// None,
// }
@ccclass("SPState")
export class SPState {
@property()
public name: string = "";
public clip: cc.AnimationClip = null;
@property({ displayName: "Spine動畫名稱", tooltip: "Spine動畫名稱" })
public clipname: string = "";
// @property({ displayName: "clipname1", type: cc.Enum(Clipname) })
// public clipname1: Clipname = Clipname.None;
@property()
public isloop: boolean = false;
@property()
public transitionTo: string = "";
}
@ccclass
// @executeInEditMode
@menu("Plug-in/Animation/SPAnimator")
@requireComponent(sp.Skeleton)
export class SPAnimator extends cc.Component {
@property({ displayName: "Default State" })
public defaultState: string = "";
@property({ type: SPState })
public states: SPState[] = [];
public nowPlayName: string = "";
private _isInit: boolean = false;
_animation: sp.Skeleton = null;
/** 動畫速度 */
private _speed: number = 1;
get animation(): sp.Skeleton {
if (this._animation == null) {
this._animation = this.node.getComponent(sp.Skeleton);
}
return this._animation;
}
protected onLoad(): void {
if (this._isInit) {
return;
}
if (!this.node.activeInHierarchy) {
cc.error(`node: ${this.node.name}, activeInHierarchy: ${this.node.activeInHierarchy}, 動畫沒有打開無法初始化`);
return;
}
let animationClip: cc.AnimationClip[] = this.animation["skeletonData"]["_skeletonCache"].animations;
// if (CC_EDITOR) {
// for (let i: number = 0; i < animationClip.length; i++) {
// const clip: cc.AnimationClip = animationClip[i];
// Clipname[clip.name] = i;
// Clipname[i.toString()] = clip.name;
// cc.log(`[${i}] ${clip.name}`);
// }
// return;
// }
for (let s of this.states) {
let state: SPState = null;
for (let i: number = 0; i < animationClip.length; i++) {
const clip: cc.AnimationClip = animationClip[i];
if (s.clipname === clip.name && s.clipname != null) {
s.clip = clip;
state = s;
break;
}
}
if (CC_DEV) {
if (state === null) {
console.error(`node: ${this.node.name}, anim: ${s.clipname}, 動畫沒有掛在Animation上面`);
}
}
}
this._isInit = true;
}
protected onEnable(): void {
this.stopState();
if (this.defaultState !== "") {
this.playState(this.defaultState);
}
}
protected onDisable(): void {
this.stopState();
}
/**
* runStateAndWait()
* @param name State的名稱
* @param callback callback transitionTo才會觸發
*/
public *runStateAndWait(name: string, callback: Function = null): any {
if (!this._isInit) {
this.onLoad();
}
if (name === "") {
return;
}
this.animation.setToSetupPose();
let lastPlayName: string = "";
for (let s of this.states) {
if (s.name === this.nowPlayName && s.clipname != null) {
lastPlayName = s.clipname;
break;
}
}
this.nowPlayName = name;
let state: SPState = null;
for (let s of this.states) {
if (s.name === name && s.clipname != null) {
state = s;
break;
}
}
if (state == null) {
return;
}
// let animationState: cc.AnimationState = this.animation.play(state.clipname);
if (lastPlayName) {
this.animation.setMix(lastPlayName, state.clipname, 0.5);
}
this.animation.setAnimation(0, state.clipname, state.isloop);
// let animationState: sp.spine.TrackEntry = this.animation.setAnimation(0, state.clipname, state.isloop);
// animationState.speed = this.animation.currentClip.speed * this._speed;
// this.animation.sample(animationState.name);
if (state.clip.duration) {
yield CoroutineV2.WaitTime(state.clip.duration);
}
if (callback && !state.transitionTo) {
callback();
}
yield* this.runStateAndWait(state.transitionTo, callback);
}
/** playState(動作機只會接一次動畫) */
public playState(name: string, callback: Function = null): void {
if (!this.node.activeInHierarchy) {
cc.warn(`SPAnimator error name: ${this.node.name}, activeInHierarchy: ${this.node.activeInHierarchy}`);
}
CoroutineV2.Single(this.runStateAndWait(name, callback)).Start(this);
}
// /** playState(隨機) */
// public playRandomState(callback: Function = null): void {
// let random: number = RandomEx.GetInt(0, this.states.length);
// let state: SPState = this.states[random];
// this.playState(state.name, callback);
// }
public stopState(): void {
CoroutineV2.StopCoroutinesBy(this);
this.nowPlayName = "";
this.animation.clearTracks();
}
// /**
// * 設定動畫速率(原有動畫的Speed在乘上倍率)
// * @param speed 速率
// */
// public SetSpeed(speed: number): void {
// this._speed = speed;
// }
public getAnimTime(name: string, isGetNext: boolean = false): number {
for (let s of this.states) {
if (s.name === name && s.clipname != null) {
let time: number = s.clip.duration / this._speed;
if (isGetNext && s.transitionTo !== "") {
time += this.getAnimTime(s.transitionTo, true);
}
return time;
}
}
return null;
}
}