feat(battle): 重构技能施放与战斗距离系统
- 新增技能距离缓存机制,根据英雄类型动态计算最小和最大攻击范围 - 重构SCastSystem实现完整的技能施放逻辑,支持伤害、治疗、护盾和buff技能 - 在Hero和Monster初始化时调用updateSkillDistanceCache预计算技能距离 - 修改HeroMoveSystem和MonMoveSystem使用动态战斗范围,支持撤退逻辑 - 优化Skill实体创建,增加对象池支持 - 添加技能CD触发方法和状态检查方法
This commit is contained in:
@@ -91,6 +91,7 @@ export class Hero extends ecs.Entity {
|
|||||||
if(hero.skills[1]) {
|
if(hero.skills[1]) {
|
||||||
model.skill_id=hero.skills[1]
|
model.skill_id=hero.skills[1]
|
||||||
}
|
}
|
||||||
|
model.updateSkillDistanceCache(model.skill_id || model.atk_id);
|
||||||
|
|
||||||
// 初始化 buff/debuff 系统
|
// 初始化 buff/debuff 系统
|
||||||
model.initAttrs();
|
model.initAttrs();
|
||||||
@@ -143,4 +144,4 @@ export class HeroLifecycleSystem extends ecs.ComblockSystem
|
|||||||
mLogger.log(true, 'HeroLifecycle', `英雄离开世界: 实体ID ${e.eid}`);
|
mLogger.log(true, 'HeroLifecycle', `英雄离开世界: 实体ID ${e.eid}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
|||||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { Attrs, BType } from "../common/config/HeroAttrs";
|
import { Attrs, BType } from "../common/config/HeroAttrs";
|
||||||
import { BuffConf, SkillDisVal, SkillRange, SkillSet } from "../common/config/SkillSet";
|
import { BuffConf, SkillDisVal, SkillRange } from "../common/config/SkillSet";
|
||||||
import { HeroInfo } from "../common/config/heroSet";
|
import { HeroInfo, HType } from "../common/config/heroSet";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { _decorator } from "cc";
|
import { _decorator } from "cc";
|
||||||
|
|
||||||
@@ -267,11 +267,25 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
this.a_cd+=dt
|
this.a_cd+=dt
|
||||||
if(this.a_cd >= this.a_cd_max) this.can_atk = true
|
if(this.a_cd >= this.a_cd_max) this.can_atk = true
|
||||||
}
|
}
|
||||||
if(this.skill_id !=0&&this.can_skill){
|
if(this.skill_id !=0&&!this.can_skill){
|
||||||
this.s_cd+=dt
|
this.s_cd+=dt
|
||||||
if(this.s_cd >= this.s_cd_max) this.can_skill = true
|
if(this.s_cd >= this.s_cd_max) this.can_skill = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
isStun(): boolean {
|
||||||
|
return this.in_stun;
|
||||||
|
}
|
||||||
|
isFrost(): boolean {
|
||||||
|
return this.in_frost;
|
||||||
|
}
|
||||||
|
triggerAtkCD() {
|
||||||
|
this.a_cd = 0;
|
||||||
|
this.can_atk = false;
|
||||||
|
}
|
||||||
|
triggerSkillCD() {
|
||||||
|
this.s_cd = 0;
|
||||||
|
this.can_skill = false;
|
||||||
|
}
|
||||||
// ==================== 临时 BUFF/DEBUFF 更新 ====================
|
// ==================== 临时 BUFF/DEBUFF 更新 ====================
|
||||||
/**
|
/**
|
||||||
* 更新临时 buff/debuff 的剩余时间
|
* 更新临时 buff/debuff 的剩余时间
|
||||||
@@ -342,16 +356,26 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
* @param skillsComp 技能组件
|
* @param skillsComp 技能组件
|
||||||
*/
|
*/
|
||||||
public updateSkillDistanceCache(skill_id:number): void {
|
public updateSkillDistanceCache(skill_id:number): void {
|
||||||
let skillConf=SkillSet[skill_id];
|
void skill_id;
|
||||||
if (!skillConf) {
|
let rangeType = this.rangeType;
|
||||||
this.maxSkillDistance = 0;
|
if (rangeType === undefined || rangeType === null) {
|
||||||
this.minSkillDistance = 0;
|
if (this.type === HType.remote) {
|
||||||
return;
|
rangeType = SkillRange.Long;
|
||||||
|
} else if (this.type === HType.mage || this.type === HType.support) {
|
||||||
|
rangeType = SkillRange.Mid;
|
||||||
|
} else {
|
||||||
|
rangeType = SkillRange.Melee;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 最远距离使用当前MP可施放的技能
|
const maxRange = SkillDisVal[rangeType];
|
||||||
this.maxSkillDistance = SkillDisVal[skillConf.dis];
|
let minRange = 0;
|
||||||
// 最近距离使用所有技能中的最小距离,不考虑MP限制,用于停止位置判断
|
if (rangeType === SkillRange.Mid) {
|
||||||
this.minSkillDistance = SkillDisVal[skillConf.dis];
|
minRange = SkillDisVal[SkillRange.Melee];
|
||||||
|
} else if (rangeType === SkillRange.Long) {
|
||||||
|
minRange = SkillDisVal[SkillRange.Mid];
|
||||||
|
}
|
||||||
|
this.maxSkillDistance = maxRange;
|
||||||
|
this.minSkillDistance = minRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -110,11 +110,13 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
const currentX = view.node.position.x;
|
const currentX = view.node.position.x;
|
||||||
const enemyX = enemy.node.position.x;
|
const enemyX = enemy.node.position.x;
|
||||||
const dist = Math.abs(currentX - enemyX);
|
const dist = Math.abs(currentX - enemyX);
|
||||||
const attackRange = 75; // 保持原有的近战判定
|
const [minRange, maxRange] = this.resolveCombatRange(model, 0, 75);
|
||||||
|
|
||||||
move.direction = enemyX > currentX ? 1 : -1;
|
move.direction = enemyX > currentX ? 1 : -1;
|
||||||
|
|
||||||
if (dist <= attackRange) {
|
if (dist < minRange) {
|
||||||
|
this.performRetreat(view, move, model, currentX);
|
||||||
|
} else if (dist <= maxRange) {
|
||||||
view.status_change("idle");
|
view.status_change("idle");
|
||||||
model.is_atking = true;
|
model.is_atking = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -134,8 +136,7 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
const enemyX = enemy.node.position.x;
|
const enemyX = enemy.node.position.x;
|
||||||
const dist = Math.abs(currentX - enemyX);
|
const dist = Math.abs(currentX - enemyX);
|
||||||
|
|
||||||
const minRange = 120;
|
const [minRange, maxRange] = this.resolveCombatRange(model, 120, 360);
|
||||||
const maxRange = 360;
|
|
||||||
|
|
||||||
move.direction = enemyX > currentX ? 1 : -1;
|
move.direction = enemyX > currentX ? 1 : -1;
|
||||||
|
|
||||||
@@ -164,8 +165,7 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
const enemyX = enemy.node.position.x;
|
const enemyX = enemy.node.position.x;
|
||||||
const dist = Math.abs(currentX - enemyX);
|
const dist = Math.abs(currentX - enemyX);
|
||||||
|
|
||||||
const minRange = 360;
|
const [minRange, maxRange] = this.resolveCombatRange(model, 360, 720);
|
||||||
const maxRange = 720;
|
|
||||||
|
|
||||||
move.direction = enemyX > currentX ? 1 : -1;
|
move.direction = enemyX > currentX ? 1 : -1;
|
||||||
|
|
||||||
@@ -245,6 +245,14 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private resolveCombatRange(model: HeroAttrsComp, defaultMin: number, defaultMax: number): [number, number] {
|
||||||
|
const minRange = model.getCachedMinSkillDistance();
|
||||||
|
const maxRange = model.getCachedMaxSkillDistance();
|
||||||
|
if (maxRange <= 0) return [defaultMin, defaultMax];
|
||||||
|
const safeMin = Math.max(0, Math.min(minRange, maxRange - 20));
|
||||||
|
return [safeMin, maxRange];
|
||||||
|
}
|
||||||
|
|
||||||
// --- 辅助方法 ---
|
// --- 辅助方法 ---
|
||||||
|
|
||||||
private findNearestEnemy(entity: ecs.Entity): HeroViewComp | null {
|
private findNearestEnemy(entity: ecs.Entity): HeroViewComp | null {
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ export class Monster extends ecs.Entity {
|
|||||||
// ✅ 初始化技能数据(迁移到 HeroSkillsComp)
|
// ✅ 初始化技能数据(迁移到 HeroSkillsComp)
|
||||||
if(hero.skills[0]) model.atk_id=hero.skills[0]
|
if(hero.skills[0]) model.atk_id=hero.skills[0]
|
||||||
if(hero.skills[1]) model.skill_id=hero.skills[1]
|
if(hero.skills[1]) model.skill_id=hero.skills[1]
|
||||||
|
model.updateSkillDistanceCache(model.skill_id || model.atk_id);
|
||||||
|
|
||||||
|
|
||||||
this.add(view);
|
this.add(view);
|
||||||
@@ -178,4 +179,4 @@ export class MonLifecycleSystem extends ecs.ComblockSystem
|
|||||||
mLogger.log(this.debugMode, 'MonLifecycleSystem', `怪物离开世界: 实体ID ${e.eid}`);
|
mLogger.log(this.debugMode, 'MonLifecycleSystem', `怪物离开世界: 实体ID ${e.eid}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,11 +127,13 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
const currentX = view.node.position.x;
|
const currentX = view.node.position.x;
|
||||||
const enemyX = enemy.node.position.x;
|
const enemyX = enemy.node.position.x;
|
||||||
const dist = Math.abs(currentX - enemyX);
|
const dist = Math.abs(currentX - enemyX);
|
||||||
const attackRange = 75; // 保持原有的近战判定
|
const [minRange, maxRange] = this.resolveCombatRange(model, 0, 75);
|
||||||
|
|
||||||
move.direction = enemyX > currentX ? 1 : -1;
|
move.direction = enemyX > currentX ? 1 : -1;
|
||||||
|
|
||||||
if (dist <= attackRange) {
|
if (dist < minRange) {
|
||||||
|
this.performRetreat(view, move, model, currentX);
|
||||||
|
} else if (dist <= maxRange) {
|
||||||
view.status_change("idle");
|
view.status_change("idle");
|
||||||
model.is_atking = true;
|
model.is_atking = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -151,8 +153,7 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
const enemyX = enemy.node.position.x;
|
const enemyX = enemy.node.position.x;
|
||||||
const dist = Math.abs(currentX - enemyX);
|
const dist = Math.abs(currentX - enemyX);
|
||||||
|
|
||||||
const minRange = 120;
|
const [minRange, maxRange] = this.resolveCombatRange(model, 120, 360);
|
||||||
const maxRange = 360;
|
|
||||||
|
|
||||||
move.direction = enemyX > currentX ? 1 : -1;
|
move.direction = enemyX > currentX ? 1 : -1;
|
||||||
|
|
||||||
@@ -181,8 +182,7 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
const enemyX = enemy.node.position.x;
|
const enemyX = enemy.node.position.x;
|
||||||
const dist = Math.abs(currentX - enemyX);
|
const dist = Math.abs(currentX - enemyX);
|
||||||
|
|
||||||
const minRange = 360;
|
const [minRange, maxRange] = this.resolveCombatRange(model, 360, 720);
|
||||||
const maxRange = 720;
|
|
||||||
|
|
||||||
move.direction = enemyX > currentX ? 1 : -1;
|
move.direction = enemyX > currentX ? 1 : -1;
|
||||||
|
|
||||||
@@ -263,6 +263,14 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private resolveCombatRange(model: HeroAttrsComp, defaultMin: number, defaultMax: number): [number, number] {
|
||||||
|
const minRange = model.getCachedMinSkillDistance();
|
||||||
|
const maxRange = model.getCachedMaxSkillDistance();
|
||||||
|
if (maxRange <= 0) return [defaultMin, defaultMax];
|
||||||
|
const safeMin = Math.max(0, Math.min(minRange, maxRange - 20));
|
||||||
|
return [safeMin, maxRange];
|
||||||
|
}
|
||||||
|
|
||||||
/** 检查并设置y轴目标位置 */
|
/** 检查并设置y轴目标位置 */
|
||||||
private checkAndSetTargetY(entity: ecs.Entity): void {
|
private checkAndSetTargetY(entity: ecs.Entity): void {
|
||||||
const move = entity.get(MonMoveComp);
|
const move = entity.get(MonMoveComp);
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { Vec3, v3 } from "cc";
|
import { Vec3 } from "cc";
|
||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
import { HeroViewComp } from "./HeroViewComp";
|
import { HeroViewComp } from "./HeroViewComp";
|
||||||
import { HSSet, SkillSet, SType, TGroup, SkillConfig } from "../common/config/SkillSet";
|
import { BuffsList, SkillConfig, SkillSet, SType, TGroup } from "../common/config/SkillSet";
|
||||||
import { Skill } from "../skill/Skill";
|
import { Skill } from "../skill/Skill";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { BoxSet, FacSet } from "../common/config/GameSet";
|
|
||||||
import { GameConst } from "../common/config/GameConst";
|
import { GameConst } from "../common/config/GameConst";
|
||||||
import { Attrs } from "../common/config/HeroAttrs";
|
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,7 +34,124 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
|||||||
update(e: ecs.Entity): void {
|
update(e: ecs.Entity): void {
|
||||||
if(!smc.mission.play ) return;
|
if(!smc.mission.play ) return;
|
||||||
if(smc.mission.pause) return
|
if(smc.mission.pause) return
|
||||||
|
const heroAttrs = e.get(HeroAttrsComp);
|
||||||
|
const heroView = e.get(HeroViewComp);
|
||||||
|
if (!heroAttrs || !heroView || !heroView.node) return;
|
||||||
|
if (heroAttrs.is_dead || heroAttrs.is_reviving || heroAttrs.isStun() || heroAttrs.isFrost()) return;
|
||||||
|
heroAttrs.updateCD(this.dt);
|
||||||
|
if (!heroAttrs.is_atking) return;
|
||||||
|
const castSkillId = this.pickCastSkill(heroAttrs, heroView);
|
||||||
|
if (castSkillId === 0) return;
|
||||||
|
this.castSkill(e, castSkillId, heroAttrs, heroView);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private pickCastSkill(heroAttrs: HeroAttrsComp, heroView: HeroViewComp): number {
|
||||||
|
const skillCandidates = [heroAttrs.skill_id, heroAttrs.atk_id];
|
||||||
|
for (const s_uuid of skillCandidates) {
|
||||||
|
if (!s_uuid) continue;
|
||||||
|
const config = SkillSet[s_uuid];
|
||||||
|
if (!config) continue;
|
||||||
|
const isMainSkill = s_uuid === heroAttrs.skill_id;
|
||||||
|
if (isMainSkill && !heroAttrs.can_skill) continue;
|
||||||
|
if (!isMainSkill && !heroAttrs.can_atk) continue;
|
||||||
|
const targets = this.findTargets(heroView, heroAttrs, config);
|
||||||
|
if (targets.length === 0) continue;
|
||||||
|
return s_uuid;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private castSkill(entity: ecs.Entity, s_uuid: number, heroAttrs: HeroAttrsComp, heroView: HeroViewComp) {
|
||||||
|
const config = SkillSet[s_uuid];
|
||||||
|
if (!config) return;
|
||||||
|
const targets = this.findTargets(heroView, heroAttrs, config);
|
||||||
|
if (targets.length === 0) return;
|
||||||
|
heroView.playSkillEffect(s_uuid);
|
||||||
|
const isMainSkill = s_uuid === heroAttrs.skill_id;
|
||||||
|
const delay = GameConst.Battle.SKILL_CAST_DELAY;
|
||||||
|
heroView.scheduleOnce(() => {
|
||||||
|
if (!heroView.node || !heroView.node.isValid || heroAttrs.is_dead) return;
|
||||||
|
if (config.SType === SType.damage) {
|
||||||
|
this.createSkillEntity(s_uuid, heroView, targets[0].node.position);
|
||||||
|
} else {
|
||||||
|
this.applySupportSkill(entity, config, targets);
|
||||||
|
}
|
||||||
|
}, delay);
|
||||||
|
if (isMainSkill) {
|
||||||
|
heroAttrs.triggerSkillCD();
|
||||||
|
} else {
|
||||||
|
heroAttrs.triggerAtkCD();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private createSkillEntity(s_uuid: number, caster: HeroViewComp, targetPos: Vec3) {
|
||||||
|
if (!caster.node || !caster.node.isValid) return;
|
||||||
|
const parent = caster.node.parent;
|
||||||
|
if (!parent) return;
|
||||||
|
const skill = ecs.getEntity<Skill>(Skill);
|
||||||
|
skill.load(caster.node.position.clone(), parent, s_uuid, targetPos.clone(), caster, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private applySupportSkill(casterEntity: ecs.Entity, config: SkillConfig, targets: HeroViewComp[]) {
|
||||||
|
const casterAttrs = casterEntity.get(HeroAttrsComp);
|
||||||
|
if (!casterAttrs) return;
|
||||||
|
const ratio = Number(config.ap ?? 0) / 100;
|
||||||
|
for (const target of targets) {
|
||||||
|
if (!target.ent) continue;
|
||||||
|
const model = target.ent.get(HeroAttrsComp);
|
||||||
|
if (!model || model.is_dead) continue;
|
||||||
|
if (config.SType === SType.heal) {
|
||||||
|
const amount = model.hp_max * ratio;
|
||||||
|
model.add_hp(amount, true);
|
||||||
|
target.health(amount);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (config.SType === SType.shield) {
|
||||||
|
const amount = model.hp_max * ratio;
|
||||||
|
model.shield_max = Math.max(model.shield_max, amount);
|
||||||
|
model.add_shield(amount, true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (config.SType === SType.buff) {
|
||||||
|
for (const buffId of config.buffs) {
|
||||||
|
const buffConf = BuffsList[buffId];
|
||||||
|
if (buffConf) {
|
||||||
|
model.addBuff(buffConf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mLogger.log(this.debugMode, "SCastSystem", `[SCastSystem] ${casterAttrs.hero_name} 施放 ${config.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
private findTargets(caster: HeroViewComp, casterAttrs: HeroAttrsComp, config: SkillConfig): HeroViewComp[] {
|
||||||
|
const range = Number(config.dis ?? GameConst.Battle.DEFAULT_SEARCH_RANGE);
|
||||||
|
const isEnemy = config.TGroup === TGroup.Enemy;
|
||||||
|
const isSelf = config.TGroup === TGroup.Self;
|
||||||
|
const isTeam = config.TGroup === TGroup.Team || config.TGroup === TGroup.Ally;
|
||||||
|
const isAll = config.TGroup === TGroup.All;
|
||||||
|
if (isSelf) return [caster];
|
||||||
|
const currentPos = caster.node.position;
|
||||||
|
const list: { view: HeroViewComp; dis: number; lane: number }[] = [];
|
||||||
|
ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).forEach(ent => {
|
||||||
|
const targetAttrs = ent.get(HeroAttrsComp);
|
||||||
|
const targetView = ent.get(HeroViewComp);
|
||||||
|
if (!targetAttrs || !targetView || !targetView.node || targetAttrs.is_dead) return;
|
||||||
|
if (targetView === caster) return;
|
||||||
|
const isSameFac = targetAttrs.fac === casterAttrs.fac;
|
||||||
|
if (isEnemy && isSameFac) return;
|
||||||
|
if (isTeam && !isSameFac) return;
|
||||||
|
if (!isEnemy && !isTeam && !isAll) return;
|
||||||
|
const dis = Math.abs(currentPos.x - targetView.node.position.x);
|
||||||
|
if (dis > range) return;
|
||||||
|
const lane = Math.abs(currentPos.y - targetView.node.position.y);
|
||||||
|
list.push({ view: targetView, dis, lane });
|
||||||
|
});
|
||||||
|
list.sort((a, b) => {
|
||||||
|
if (a.lane !== b.lane) return a.lane - b.lane;
|
||||||
|
return a.dis - b.dis;
|
||||||
|
});
|
||||||
|
const maxTargets = Math.max(GameConst.Skill.MIN_TARGET_COUNT, config.t_num || 1);
|
||||||
|
return list.slice(0, maxTargets).map(item => item.view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,9 +71,11 @@ export class Skill extends ecs.Entity {
|
|||||||
mLogger.error(this.debugMode, 'Skill', "[Skill] 预制体加载失败:", path);
|
mLogger.error(this.debugMode, 'Skill', "[Skill] 预制体加载失败:", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const node: Node = instantiate(prefab);
|
const node: Node = Skill.getFromPool(path) || instantiate(prefab);
|
||||||
|
this.prefabPath = path;
|
||||||
|
this.skillNode = node;
|
||||||
var scene = smc.map.MapView.scene;
|
var scene = smc.map.MapView.scene;
|
||||||
node.parent = scene.entityLayer!.node!.getChildByName("SKILL")!;
|
node.parent = scene.entityLayer!.node!.getChildByName("SKILL") || parent;
|
||||||
// 设置节点属性
|
// 设置节点属性
|
||||||
let face=caster.node.scale.x < 0 ? -1 : 1
|
let face=caster.node.scale.x < 0 ? -1 : 1
|
||||||
node.setScale(v3(node.scale.x*face,node.scale.y,1))
|
node.setScale(v3(node.scale.x*face,node.scale.y,1))
|
||||||
|
|||||||
Reference in New Issue
Block a user