123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- import { _decorator, Component, Node, Prefab, AnimationComponent, ParticleSystemComponent, Vec3, find, AnimationState, AnimationClip, instantiate, Animation } from 'cc';
- import { poolManager } from './poolManager';
- import { resourceUtil } from './resourceUtil';
- const { ccclass, property } = _decorator;
- @ccclass('EffectManager')
- export class EffectManager extends Component {
- private _ndParent: Node = null!;
- public get ndParent() {
- if (!this._ndParent) {
- this._ndParent = find("effectManager") as Node;
- }
- return this._ndParent
- }
- private _ndEff: Node = null!;
- public get ndEff() {
- if (!this._ndEff) {
- this._ndEff = find("effParent") as Node;
- }
- return this._ndEff;
- }
- static _instance: EffectManager;
- static get instance() {
- if (this._instance) {
- return this._instance;
- }
- this._instance = new EffectManager();
- return this._instance;
- }
- /**
- * 播放动画
- * @param {string} path 动画节点路径
- * @param {string} aniName
- * @param {vec3} worPos 世界坐标
- * @param {boolean} isLoop 是否循环
- * @param {boolean} isRecycle 是否回收
- * @param {number} [scale=1] 缩放倍数
- * @param {Function} [callback=()=>{}] 回调函数
- */
- public playAni(path: string, aniName: string, worPos: Vec3 = new Vec3(), isLoop: boolean = false, isRecycle: boolean = false, scale: number = 1, callback: Function = () => { }) {
- let childName: string = path.split("/")[1];
- let ndEffect: Node | null = this.ndParent.getChildByName(childName);
- let cb = () => {
- ndEffect?.setScale(new Vec3(scale, scale, scale));
- ndEffect?.setWorldPosition(worPos);
- let ani: AnimationComponent = ndEffect?.getComponent(AnimationComponent) as AnimationComponent;
- ani.play(aniName);
- let aniState: AnimationState = ani.getState(aniName) as AnimationState;
- if (aniState) {
- if (isLoop) {
- aniState.wrapMode = AnimationClip.WrapMode.Loop;
- } else {
- aniState.wrapMode = AnimationClip.WrapMode.Normal;
- }
- }
- ani.once(AnimationComponent.EventType.FINISHED, () => {
- callback && callback();
- if (isRecycle && ndEffect) {
- poolManager.instance.putNode(ndEffect);
- }
- })
- }
- if (!ndEffect) {
- resourceUtil.loadModelRes(path).then((prefab: any) => {
- ndEffect = poolManager.instance.getNode(prefab as Prefab, this.ndParent) as Node;
- ndEffect.setScale(new Vec3(scale, scale, scale));
- ndEffect.setWorldPosition(worPos);
- cb();
- })
- } else {
- cb();
- }
- }
- /**
- * 移除特效
- * @param {string} name 特效名称
- * @param {Node}} ndParent 特效父节点
- */
- public removeEffect(name: string, ndParent: Node = this.ndParent) {
- let ndEffect: Node | null = ndParent.getChildByName(name);
- if (ndEffect) {
- let arrAni: AnimationComponent[] = ndEffect.getComponentsInChildren(AnimationComponent);
- arrAni.forEach((element: AnimationComponent) => {
- element.stop();
- })
- let arrParticle: [] = ndEffect?.getComponentsInChildren(ParticleSystemComponent) as any;
- arrParticle.forEach((element: ParticleSystemComponent) => {
- element?.clear();
- element?.stop();
- })
- poolManager.instance.putNode(ndEffect);
- }
- }
- /**
- * 播放粒子特效
- * @param {string} path 特效路径
- * @param {vec3}worPos 特效世界坐标
- * @param {number} [recycleTime=0] 特效节点回收时间,如果为0,则使用默认duration
- * @param {number} [scale=1] 缩放倍数
- * @param {vec3} eulerAngles 特效角度
- * @param {Function} [callback=()=>{}] 回调函数
- */
- public playParticle(path: string, worPos: Vec3, recycleTime: number = 0, scale: number = 1, eulerAngles?: Vec3, callback?: Function) {
- resourceUtil.loadEffectRes(path).then((prefab: any) => {
- let ndEffect: Node = poolManager.instance.getNode(prefab as Prefab, this.ndParent) as Node;
- ndEffect.setScale(new Vec3(scale, scale, scale));
- ndEffect.setWorldPosition(worPos);
- if (eulerAngles) {
- ndEffect.eulerAngles = eulerAngles;
- }
- let maxDuration: number = 0;
- let arrParticle: ParticleSystemComponent[] = ndEffect.getComponentsInChildren(ParticleSystemComponent);
- arrParticle.forEach((item: ParticleSystemComponent) => {
- item.simulationSpeed = 1;
- item?.clear();
- item?.stop();
- item?.play()
- let duration: number = item.duration;
- maxDuration = duration > maxDuration ? duration : maxDuration;
- })
- let seconds: number = recycleTime && recycleTime > 0 ? recycleTime : maxDuration;
- setTimeout(() => {
- if (ndEffect.parent) {
- callback && callback();
- poolManager.instance.putNode(ndEffect);
- }
- }, seconds * 1000)
- })
- }
- /**
- * 播放节点下面的动画和粒子
- *
- * @param {Node} targetNode 特效挂载节点
- * @param {string} effectPath 特效路径
- * @param {boolean} [isPlayAni=true] 是否播放动画
- * @param {boolean} [isPlayParticle=true] 是否播放特效
- * @param {number} [recycleTime=0] 特效节点回收时间,如果为0,则使用默认duration
- * @param {number} [scale=1] 缩放倍数
- * @param {Vec3} [pos=new Vec3()] 位移
- * @param {Function} [callback=()=>{}] 回调函数
- * @returns
- * @memberof EffectManager
- */
- public playEffect(targetNode: Node, effectPath: string, isPlayAni: boolean = true, isPlayParticle: boolean = true, recycleTime: number = 0, scale: number = 1, pos: Vec3 = new Vec3(), eulerAngles?: Vec3, callback?: Function) {
- if (!targetNode.parent) {//父节点被回收的时候不播放
- return;
- }
- resourceUtil.loadEffectRes(effectPath).then((prefab: any) => {
- let ndEffect: Node = poolManager.instance.getNode(prefab as Prefab, targetNode) as Node;
- ndEffect.setScale(new Vec3(scale, scale, scale));
- ndEffect.setPosition(pos);
- if (eulerAngles) {
- ndEffect.eulerAngles = eulerAngles;
- }
- let maxDuration: number = 0;
- if (isPlayAni) {
- let arrAni: AnimationComponent[] = ndEffect.getComponentsInChildren(AnimationComponent);
- arrAni.forEach((element: AnimationComponent, idx: number) => {
- element?.play();
- let aniName = element?.defaultClip?.name;
- if (aniName) {
- let aniState = element.getState(aniName);
- if (aniState) {
- let duration = aniState.duration;
- maxDuration = duration > maxDuration ? duration : maxDuration;
- aniState.speed = 1;
- }
- }
- })
- }
- if (isPlayParticle) {
- let arrParticle: ParticleSystemComponent[] = ndEffect.getComponentsInChildren(ParticleSystemComponent);
- arrParticle.forEach((element: ParticleSystemComponent) => {
- element.simulationSpeed = 1;
- element?.clear();
- element?.stop();
- element?.play()
- let duration: number = element.duration;
- maxDuration = duration > maxDuration ? duration : maxDuration;
- })
- }
- let seconds: number = recycleTime && recycleTime > 0 ? recycleTime : maxDuration;
- setTimeout(() => {
- if (ndEffect.parent) {
- callback && callback();
- poolManager.instance.putNode(ndEffect);
- }
- }, seconds * 1000)
- })
- }
- public playGetPresent(parent: Node) {
- resourceUtil.loadEffectRes('propSynthesis').then((prefab: any) => {
- let ndEffect: Node = poolManager.instance.getNode(prefab as Prefab, parent) as Node;
- // ndEffect.setScale(new Vec3(scale, scale, scale));
- // ndEffect.setPosition(pos);
- let maxDuration: number = 0;
- let arrParticle: ParticleSystemComponent[] = ndEffect.getComponentsInChildren(ParticleSystemComponent);
- arrParticle.forEach((item: ParticleSystemComponent) => {
- item.simulationSpeed = 1;
- item?.clear();
- item?.stop();
- item?.play()
- let duration: number = item.duration;
- maxDuration = duration > maxDuration ? duration : maxDuration;
- })
- let seconds: number = maxDuration;
- setTimeout(() => {
- if (ndEffect.parent) {
- poolManager.instance.putNode(ndEffect);
- // ndEffect.destroy()
- }
- }, seconds * 1000)
- })
- }
- /**
- * 播放待机动画
- */
- public playIdle(isCelebrateToIdle?: boolean) {
- for (let i = 0; i < this.ndEff.children.length; i++) {
- const item = this.ndEff.children[i];
- if (isCelebrateToIdle && item.name === 'machineTop') {
- item.getComponent(AnimationComponent)?.play('idleIn');
- item.getComponent(AnimationComponent)?.once(Animation.EventType.FINISHED, () => {
- item.getComponent(AnimationComponent)?.play('idle');
- })
- continue;
- }
- item.getComponent(AnimationComponent)?.play('idle');
- }
- }
- /**
- * 播放庆祝动画——获得特殊奖品
- */
- public playCelebrate() {
- for (let i = 0; i < this.ndEff.children.length; i++) {
- this.ndEff.children[i].getComponent(AnimationComponent)?.play('celebrate');
- }
- setTimeout(() => {
- this.playIdle(true);
- }, 3000);
- //庆祝礼花
- let ndEffect: Node;
- resourceUtil.loadEffectRes('celebrate').then((prefab: any) => {
- ndEffect = instantiate(prefab) as Node;
- ndEffect.parent = this.ndParent;
- ndEffect.setPosition(new Vec3(0, 0, 0));
- let maxDuration = 0;
- let arrParticle: ParticleSystemComponent[] = ndEffect.getComponentsInChildren(ParticleSystemComponent);
- arrParticle.forEach((item: ParticleSystemComponent) => {
- item.simulationSpeed = 1;
- item?.clear();
- item?.stop();
- item?.play()
- let duration: number = item.duration;
- maxDuration = duration > maxDuration ? duration : maxDuration;
- })
- //礼花需要置空消失的时间
- let seconds: number = maxDuration + 2.5;
- setTimeout(() => {
- if (ndEffect.parent) {
- ndEffect.destroy();
- }
- }, seconds * 1000)
- })
- }
- }
|