fix(boss): keep phase outline authoritative over level tint and pool reuse

Reuse existing outline-green/outline-glow materials (P2 green / P3 red); phase outline now takes priority over level tint during boss lifetime (init/lv_up both route through BossPhaseComp), and HeroViewComp.reset clears the material back to default so pooled monster nodes never inherit a boss's red/green edge.
This commit is contained in:
panFD
2026-10-10 00:40:47 +08:00
parent a122d0904c
commit 74d03facd9
2 changed files with 30 additions and 22 deletions

View File

@@ -16,6 +16,7 @@ import { Tooltip } from "../skill/Tooltip";
import { timedCom } from "../skill/timedCom";
import { oneCom } from "../skill/oncend";
import { FlashSprite } from "./hit-flash-white/scripts/FlashSprite";
import { BossPhaseComp } from "./BossPhaseComp";
const { ccclass, property } = _decorator;
@@ -89,7 +90,6 @@ export class HeroViewComp extends CCComp {
this.deadCD = 0;
this.lastBarUpdateTime = 0;
this.status_change("idle");
// 初始化头顶状态栏
const topNode = this.node.getChildByName("top");
this.topBar = topNode.getComponent(HeroTopBarComp) || topNode.addComponent(HeroTopBarComp);
@@ -98,8 +98,13 @@ export class HeroViewComp extends CCComp {
/** 方向 */
this.node.setScale(this.scale * Math.abs(this.node.scale.x), 1 * this.node.scale.y); // 确保 scale.x 为正后再乘方向
// 🔥 重置描边
this.applyOutlineByLevel();
// 🔥 重置描边:Boss 阶段描边优先(Boss 存活期不被等级描边覆盖),其余按等级
const phaseComp = this.ent ? this.ent.get(BossPhaseComp) : null;
if (phaseComp && phaseComp.index > 0) {
this.applyBossPhaseOutline(phaseComp.index);
} else {
this.applyOutlineByLevel();
}
}
/**
@@ -162,8 +167,13 @@ export class HeroViewComp extends CCComp {
public lv_up() {
this.spawnTimedFx("game/skill/buff/buff_lvup", this.node, 1.0);
// 升级时同步更新描边
this.applyOutlineByLevel();
// 升级时同步更新描边:Boss 阶段描边优先(与 init 口径一致)
const phaseComp = this.ent ? this.ent.get(BossPhaseComp) : null;
if (phaseComp && phaseComp.index > 0) {
this.applyBossPhaseOutline(phaseComp.index);
} else {
this.applyOutlineByLevel();
}
}
/** 按英雄等级应用描边(升级/初始化共用入口) */
@@ -577,6 +587,13 @@ export class HeroViewComp extends CCComp {
this.deadCD = 0
this.lastBarUpdateTime = 0
// 清掉描边材质:防 Boss 阶段描边(绿/红)随对象池节点复用串到小怪/英雄身上
const flashSprite = this.getFlashSprite();
if (flashSprite && flashSprite.defaultMaterial) {
flashSprite.orginalFlashMaterial = flashSprite.defaultMaterial;
flashSprite.sprite?.setSharedMaterial(flashSprite.defaultMaterial, 0);
}
// 清理伤害队列
this.damageQueue.length = 0;
this.isProcessingDamage = false;

View File

@@ -7,15 +7,9 @@ export class FlashSprite extends Component {
@property(Material)
hitFlashMaterial: Material | null = null;
@property({ type: Material, tooltip: '绿色描边材质(2级)' })
@property({ type: Material, tooltip: '绿色描边材质(2级 / Boss阶段2)' })
outlineMatGreen: Material | null = null;
@property({ type: Material, tooltip: '淡绿描边材质(Boss阶段2)' })
outlineMatGreenLight: Material | null = null;
@property({ type: Material, tooltip: '深绿描边材质(Boss阶段2备选)' })
outlineMatGreenDark: Material | null = null;
@property({ type: Material, tooltip: '蓝色描边材质(3级)' })
outlineMatBlue: Material | null = null;
@@ -25,8 +19,8 @@ export class FlashSprite extends Component {
@property({ type: Material, tooltip: '黄色描边材质(5级)' })
outlineMatYellow: Material | null = null;
@property({ type: Material, tooltip: '红色描边材质(Boss阶段3)' })
outlineMatRed: Material | null = null;
@property({ type: Material, tooltip: '红色描边材质(Boss阶段3,即 outline-glow)' })
outlineMatGlow: Material | null = null;
orginalFlashMaterial: Material | null = null;
defaultMaterial: Material | null = null; // 缓存最原始的无描边材质
@@ -75,12 +69,11 @@ export class FlashSprite extends Component {
/**
* 按 Boss 阶段设置描边材质(优先级高于等级描边)
* Why: Boss 阶段是战斗强反馈(绿色警告 / 红色危险),与英雄等级成长是两套视觉语言,
* 用独立通道避免污染 setOutlineByLevel 的等级语义
* Why: Boss 阶段是战斗强反馈(P2 绿=警告 / P3 红=危险),与英雄等级成长是两套视觉语言,
* 用独立通道避免污染 setOutlineByLevel 的等级语义;材质复用现有 outline-green / outline-glow
* @param phase 阶段索引:1=P2 绿 / 2=P3 红 / 0=P1 恢复默认
* @param greenShade P2 绿色色调:'light' 淡绿(默认)/ 'dark' 深绿
*/
public setOutlineByBossPhase(phase: number, greenShade: 'light' | 'dark' = 'light') {
public setOutlineByBossPhase(phase: number) {
if (!this.sprite) {
this.sprite = this.node.getComponent(Sprite);
}
@@ -88,11 +81,9 @@ export class FlashSprite extends Component {
let targetMat: Material | null = null;
if (phase === 1) {
targetMat = greenShade === 'dark'
? (this.outlineMatGreenDark ?? this.outlineMatGreenLight ?? this.outlineMatGreen)
: (this.outlineMatGreenLight ?? this.outlineMatGreenDark ?? this.outlineMatGreen);
targetMat = this.outlineMatGreen;
} else if (phase >= 2) {
targetMat = this.outlineMatRed ?? this.outlineMatYellow;
targetMat = this.outlineMatGlow ?? this.outlineMatYellow;
} else {
targetMat = this.defaultMaterial;
}