refactor(skill): 优化特效生命周期管理并添加新动画

- 移除 timedCom 组件中未使用的 cd 和 ap 属性
- 重命名 dead 组件为 oneCom 并重构动画结束销毁逻辑,避免内存泄漏
- 为部分技能添加准备动画(readyAnm)配置
- 新增 uplv 升级动画特效预制体
- 统一特效生成接口,支持基于动画结束或定时销毁两种模式
- 清理 HeroViewComp 中未使用的导入和方法
This commit is contained in:
panw
2026-03-19 14:40:51 +08:00
parent 2a4a9cbe3f
commit 0f6ab4a775
6 changed files with 51 additions and 43 deletions

View File

@@ -197,7 +197,7 @@ export const SkillSet: Record<number, SkillConfig> = {
buffs:[],debuffs:[],info:"对前方目标造成100%攻击的伤害",
},
6002: {
uuid:6002,name:"电击",sp_name:"atk_s4",icon:"1173",TGroup:TGroup.Enemy,TType:TType.Frontline,readyAnm:"",endAnm:"",act:"max",DTType:DTType.single,
uuid:6002,name:"电击",sp_name:"atk_s4",icon:"1173",TGroup:TGroup.Enemy,TType:TType.Frontline,readyAnm:"blues",endAnm:"",act:"max",DTType:DTType.single,
ap:100,hit_count:1,hitcd:0.2,speed:720,with:0,
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.collision,
buffs:[],debuffs:[],info:"对前方目标造成150%攻击的伤害",
@@ -209,7 +209,7 @@ export const SkillSet: Record<number, SkillConfig> = {
buffs:[],debuffs:[],info:"对前方目标造成150%攻击的伤害",
},
6004: {
uuid:6004,name:"火焰击",sp_name:"atk_f2",icon:"1173",TGroup:TGroup.Enemy,TType:TType.Frontline,readyAnm:"",endAnm:"",act:"max",DTType:DTType.single,
uuid:6004,name:"火焰击",sp_name:"atk_f2",icon:"1173",TGroup:TGroup.Enemy,TType:TType.Frontline,readyAnm:"reds",endAnm:"",act:"max",DTType:DTType.single,
ap:100,hit_count:6,hitcd:0.2,speed:720,with:0,
ready:0,EAnm:0,DAnm:9001,RType:RType.fixed,EType:EType.animationEnd,
buffs:[],debuffs:[],info:"对前方目标造成150%攻击的伤害",
@@ -233,7 +233,7 @@ export const SkillSet: Record<number, SkillConfig> = {
buffs:[],debuffs:[],info:"对前方单个目标造成100%攻击的伤害",
},
6008: {
uuid:6008,name:"光箭",sp_name:"arrow_big_yellow",icon:"1135",TGroup:TGroup.Enemy,TType:TType.Frontline,readyAnm:"",endAnm:"",act:"max",DTType:DTType.single,
uuid:6008,name:"光箭",sp_name:"arrow_big_yellow",icon:"1135",TGroup:TGroup.Enemy,TType:TType.Frontline,readyAnm:"blues",endAnm:"",act:"max",DTType:DTType.single,
ap:100,hit_count:6,hitcd:0.2,speed:720,with:0,
ready:0,EAnm:0,DAnm:9001,RType:RType.linear,EType:EType.collision,
buffs:[],debuffs:[],info:"对前方单个目标造成100%攻击的伤害",

View File

@@ -7,14 +7,12 @@ import { BoxSet, FacSet, FightSet } from "../common/config/GameSet";
import { smc } from "../common/SingletonModuleComp";
import { EAnmConf, SkillSet,} from "../common/config/SkillSet";
import { oops } from "db://oops-framework/core/Oops";
import { GameEvent } from "../common/config/GameEvent";
import { TooltipTypes } from "../common/config/GameSet";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { Tooltip } from "../skill/Tooltip";
import { timedCom } from "../skill/timedCom";
import { HeroInfo, HType } from "../common/config/heroSet";
import { Timer } from "db://oops-framework/core/common/timer/Timer";
import { Attrs } from "../common/config/HeroAttrs";
import { oneCom } from "../skill/oncend";
const { ccclass, property } = _decorator;
@@ -245,19 +243,12 @@ export class HeroViewComp extends CCComp {
/** 升级特效 */
private lv_up() {
this.spawnEffect("game/skill/buff/buff_lvup", this.node, 1.0);
this.spawnTimedFx("game/skill/buff/buff_lvup", this.node, 1.0);
}
/** 攻击力提升特效 */
private ap_up() {
this.spawnEffect("game/skill/buff/buff_apup", this.node, 1.0);
}
/** 显示 Buff 特效 */
private show_do_buff(name: string) {
var path = "game/skill/buff/" + name;
let pos = v3(this.node.position.x, this.node.position.y + 20, this.node.position.z);
this.spawnEffect(path, this.node.parent, 1.0, pos);
this.spawnTimedFx("game/skill/buff/buff_apup", this.node, 1.0);
}
@@ -274,22 +265,16 @@ export class HeroViewComp extends CCComp {
/** 冰冻特效 */
private in_iced(t: number = 1, ap: number = 0) {
const node = this.spawnEffect("game/skill/buff/buff_iced", this.node, t);
if (!node) return;
const timer = node.getComponent(timedCom) || node.addComponent(timedCom);
timer.time = t;
timer.ap = ap;
const node = this.spawnTimedFx("game/skill/buff/iced", this.node, t);
}
/** 眩晕特效 */
private in_yun(t: number = 1, ap: number = 0) {
const node = this.spawnEffect("game/skill/buff/buff_yun", this.node, t);
const node = this.spawnTimedFx("game/skill/buff/buff_yun", this.node, t);
if (!node) return;
let height = this.node.getComponent(UITransform).height;
node.setPosition(v3(0, height));
const timer = node.getComponent(timedCom) || node.addComponent(timedCom);
timer.time = t;
timer.ap = ap;
}
/** 技能提示 */
@@ -322,29 +307,29 @@ export class HeroViewComp extends CCComp {
public palayBuff(anm: string = ""){
if(anm==="") return;
var path = "game/skill/buff/" + anm;
this.spawnEffect(path, this.node, this.effectLifeTime);
this.spawnTimedFx(path, this.node, this.effectLifeTime);
}
public playReady(anm: string = ""){
if(anm==="") return;
var path = "game/skill/ready/" + anm;
this.spawnEffect(path, this.node, this.effectLifeTime);
this.spawnAnimEndFx(path, this.node, undefined);
}
public playEnd(anm: string = ""){
if(anm==="") return;
var path = "game/skill/end/" + anm;
this.spawnEffect(path, this.node, this.effectLifeTime);
this.spawnAnimEndFx(path, this.node, undefined);
}
/** 治疗特效 */
private heathed() {
this.spawnEffect("game/skill/buff/heathed", this.node, 1.0);
this.spawnAnimEndFx("game/skill/buff/heathed", this.node, undefined);
}
private deaded(){
this.spawnEffect("game/skill/end/atked", this.node, this.effectLifeTime);
this.spawnAnimEndFx("game/skill/end/atked", this.node, undefined);
}
private spawnEffect(path: string, parent: Node | null, life: number = 0.8, worldPos?: Vec3): Node | null {
private createFxNode(path: string, parent: Node | null, worldPos?: Vec3): Node | null {
if (!parent || !parent.isValid) return null;
const prefab: Prefab = oops.res.get(path, Prefab)!;
if (!prefab) return null;
@@ -354,9 +339,23 @@ export class HeroViewComp extends CCComp {
if (worldPos) {
node.setWorldPosition(worldPos);
}
return node;
}
private spawnTimedFx(path: string, parent: Node | null, life: number = 0.8, worldPos?: Vec3): Node | null {
const node = this.createFxNode(path, parent, worldPos);
if (!node) return null;
const ender = node.getComponent(oneCom);
if (ender) ender.destroy();
const timer = node.getComponent(timedCom) || node.addComponent(timedCom);
timer.time = Math.max(0.2, life);
timer.ap = 0;
return node;
}
private spawnAnimEndFx(path: string, parent: Node | null, worldPos?: Vec3): Node | null {
const node = this.createFxNode(path, parent, worldPos);
if (!node) return null;
const timer = node.getComponent(timedCom);
if (timer) timer.destroy();
node.getComponent(oneCom) || node.addComponent(oneCom);
return node;
}
// 注意BaseUp 逻辑已移到 HeroAttrSystem.update()

View File

@@ -1,18 +1,29 @@
import { _decorator, Component, Node ,Animation} from 'cc';
const { ccclass, property } = _decorator;
import { _decorator, Component, Animation } from 'cc';
const { ccclass } = _decorator;
@ccclass('oneCom')
export class oneCom extends Component {
private anim: Animation | null = null;
@ccclass('dead')
export class dead extends Component {
start() {
let anim = this.node.getComponent(Animation);
anim.on(Animation.EventType.FINISHED, this.onAnimationFinished, this);
this.anim = this.node.getComponent(Animation);
if (!this.anim) {
this.node.destroy();
return;
}
this.anim.off(Animation.EventType.FINISHED, this.onAnimationFinished, this);
this.anim.on(Animation.EventType.FINISHED, this.onAnimationFinished, this);
}
onAnimationFinished(){
onDestroy() {
if (!this.anim) return;
this.anim.off(Animation.EventType.FINISHED, this.onAnimationFinished, this);
this.anim = null;
}
onAnimationFinished() {
this.node.destroy();
}
update(deltaTime: number) {
}
}

View File

@@ -6,8 +6,6 @@ const { ccclass, property } = _decorator;
@ccclass('timedCom')
export class timedCom extends Component {
time = 0.3;
cd: number = 0;
ap: number = 0;
start() {