JM_KA/assets/Script/Engine/Component/Animation/AnimationRandomPlay.ts

154 lines
4.8 KiB
TypeScript
Raw Normal View History

2022-08-26 16:48:17 +08:00
const { ccclass, property, requireComponent, menu } = cc._decorator;
@ccclass("State_AnimationRandomPlay")
export class State_AnimationRandomPlay {
@property({ displayName: "最少時間", type: cc.Float })
public mintime: number = 0;
@property({ displayName: "最多時間", type: cc.Float })
public maxtime: number = 0;
@property({ displayName: "權重", type: cc.Integer })
public weight: number = 0;
@property({ displayName: "動畫", type: cc.AnimationClip })
public clip: cc.AnimationClip = null;
}
@ccclass
@menu("Plug-in/Animation/AnimationRandomPlay")
@requireComponent(cc.Animation)
/** 可以根據權重決定多久後隨機播放甚麼動畫 */
export class AnimationRandomPlay extends cc.Component {
//#region public 外調參數
@property({ type: State_AnimationRandomPlay })
public states: State_AnimationRandomPlay[] = [];
//#endregion
//#region public 屬性
public nowPlayName: string = "";
public nextPlayName: string = "";
public nextPlayTime: number = null;
//#endregion
//#region private 屬性
private _animation: cc.Animation = null;
private _weightAll: number[] = [];
private _weightAllNum: number = 0;
//#endregion
//#region get set
get animation(): cc.Animation {
if (this._animation == null) {
this._animation = this.node.getComponent(cc.Animation);
}
return this._animation;
}
//#endregion
//#region Lifecycle
onLoad(): void {
let self: this = this;
let weight: number = 0;
for (let i: number = 0; i < this.states.length; i++) {
weight += this.states[i].weight;
this._weightAll.push(weight);
this._weightAllNum += this.states[i].weight;
}
// 一般動畫
this.animation.on("finished", () => {
self.GetNextAnim();
}, this);
// 不一般動畫 (X
// Loop動畫
this.animation.on("lastframe", () => {
self.animation.setCurrentTime(0);
self.animation.stop();
self.GetNextAnim();
}, this);
}
onEnable(): void {
this.GetNextAnim();
}
onDisable(): void {
this.nextPlayName = "";
this.nextPlayTime = null;
this.animation.setCurrentTime(0);
this.animation.stop();
}
onDestroy(): void {
this.animation.targetOff(this);
// let self: this = this;
// this.animation.off("finished", () => {
// self.GetNextAnim();
// }, this);
// this.animation.off("lastframe", () => {
// self.animation.setCurrentTime(0);
// self.animation.stop();
// self.GetNextAnim();
// }, this);
}
update(dt: number): void {
let time: number = Date.now();
if (this.nextPlayTime && time >= this.nextPlayTime) {
this.nowPlayName = this.nextPlayName;
if (this.animation.getAnimationState(this.nextPlayName)) {
this.animation.play(this.nextPlayName);
} else {
console.error(`this node(${this.node.name}) not has animation(${this.nextPlayName})`);
this.animation.addClip(this.GetClip_From_states(this.nextPlayName));
if (this.animation.getAnimationState(this.nextPlayName)) {
console.warn(`this node(${this.node.name}) add animation(${this.nextPlayName})`);
this.animation.play(this.nextPlayName);
}
}
this.nextPlayName = "";
this.nextPlayTime = null;
}
}
//#endregion
//#region Custom Function
/** 取得下一隻動畫的時間&名稱 */
GetNextAnim(): void {
let random: number = Math.floor(Math.random() * this._weightAllNum) + 1;
for (let i: number = 0; i < this._weightAll.length; i++) {
if (random <= this._weightAll[i]) {
let time: number = Math.floor(Math.random() * (this.states[i].maxtime - this.states[i].mintime + 1)) + this.states[i].mintime;
this.nextPlayTime = Date.now() + (time * 1000);
this.nextPlayName = this.states[i].clip.name;
// if (CC_DEBUG) {
// let date: Date = new Date(this.nextPlayTime);
// console.log(`nextWaitTime: ${time}, nextPlayTime: ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}, nextPlayName: ${this.nextPlayName}`);
// }
break;
}
}
}
/** 取得下一隻動畫的時間&名稱 */
GetClip_From_states(name: string): cc.AnimationClip {
for (let i: number = 0; i < this.states.length; i++) {
if (this.states[i].clip.name === name) {
return this.states[i].clip;
}
}
}
//#endregion
}