fix(map, mission): 修复槽位布局与重置位置异常问题
1. 为英雄组件clearBySystem增加位置重置判断,避免未初始化时将槽位重置到原点 2. 重构任务面板槽位布局逻辑,统一使用三等分水平布局 3. 新增布局辅助方法,处理预制体Widget组件冲突问题 4. 禁用多个冗余的任务预制体节点,清理无效引用
This commit is contained in:
@@ -6029,7 +6029,7 @@
|
||||
"node": {
|
||||
"__id__": 348
|
||||
},
|
||||
"_enabled": true,
|
||||
"_enabled": false,
|
||||
"__prefab": {
|
||||
"__id__": 354
|
||||
},
|
||||
@@ -7599,7 +7599,7 @@
|
||||
"node": {
|
||||
"__id__": 456
|
||||
},
|
||||
"_enabled": true,
|
||||
"_enabled": false,
|
||||
"__prefab": {
|
||||
"__id__": 462
|
||||
},
|
||||
@@ -8571,7 +8571,7 @@
|
||||
"node": {
|
||||
"__id__": 522
|
||||
},
|
||||
"_enabled": true,
|
||||
"_enabled": false,
|
||||
"__prefab": {
|
||||
"__id__": 528
|
||||
},
|
||||
@@ -9562,7 +9562,7 @@
|
||||
"node": {
|
||||
"__id__": 590
|
||||
},
|
||||
"_enabled": true,
|
||||
"_enabled": false,
|
||||
"__prefab": {
|
||||
"__id__": 596
|
||||
},
|
||||
@@ -14349,7 +14349,7 @@
|
||||
"__id__": 530
|
||||
},
|
||||
"equip_refresh": {
|
||||
"__id__": 530
|
||||
"__id__": 464
|
||||
},
|
||||
"shop_refresh": {
|
||||
"__id__": 598
|
||||
|
||||
@@ -578,11 +578,16 @@ export class CHeroComp extends CCComp {
|
||||
/**
|
||||
* 系统清槽:任务开始/结束时强制重置。
|
||||
* 清空数据与 UI 并隐藏节点。
|
||||
*
|
||||
* 仅在 setSlotPosition 初始化过静止位置后才恢复位置,
|
||||
* 否则 restPosition 为默认 (0,0,0),会把所有槽位重置到中心。
|
||||
*/
|
||||
clearBySystem() {
|
||||
this.cardData = null;
|
||||
this.isPurchased = false;
|
||||
this.node.setPosition(this.restPosition);
|
||||
if (this.hasFixedBasePosition) {
|
||||
this.node.setPosition(this.restPosition);
|
||||
}
|
||||
this.applyEmptyUI();
|
||||
this.node.active = false;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
* - smc.vmdata.mission_data —— 局内数据(coin / hero_num / hero_max_num)
|
||||
*/
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { _decorator, instantiate, Label, Node, NodeEventType, Prefab, Tween, tween, Vec3, UITransform } from "cc";
|
||||
import { _decorator, instantiate, Label, Node, NodeEventType, Prefab, Tween, tween, Vec3, UITransform, Widget } from "cc";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { GameEvent } from "../common/config/GameEvent";
|
||||
@@ -155,10 +155,13 @@ export class MissionCardComp extends CCComp {
|
||||
/** 英雄数量显示节点(含 icon + num 子节点) */
|
||||
@property(Node)
|
||||
hero_num_node: Node = null!
|
||||
/**技能刷新按钮节点 */
|
||||
/** 技能刷新按钮节点 */
|
||||
@property(Node)
|
||||
skill_refresh: Node = null!
|
||||
|
||||
/** 槽位水平坐标(屏幕 720 三等分,卡片 230,列宽 240) */
|
||||
private readonly slotPosX: number[] = [-240, 0, 240];
|
||||
|
||||
/** 装备刷新按钮节点 */
|
||||
@property(Node)
|
||||
equip_refresh: Node = null!;
|
||||
@@ -221,7 +224,6 @@ export class MissionCardComp extends CCComp {
|
||||
onLoad() {
|
||||
this.bindEvents();
|
||||
this.cacheCardComps();
|
||||
this.layoutCardSlots();
|
||||
this.initCardsPanelPos();
|
||||
this.initPanelLayout();
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "onLoad init", {
|
||||
@@ -542,6 +544,9 @@ export class MissionCardComp extends CCComp {
|
||||
// 根据物品数量设置列表面板高度
|
||||
this.resizeListBox(this.shopBoxNode, targetCount);
|
||||
|
||||
// 三等分水平布局
|
||||
this.layoutSlotsHorizontal(this.itemCardComps);
|
||||
|
||||
// 默认显示商店面板
|
||||
if (this.shopPanNode) {
|
||||
this.shopPanNode.active = true;
|
||||
@@ -556,6 +561,7 @@ export class MissionCardComp extends CCComp {
|
||||
/**
|
||||
* 确保药品槽位数量足够。
|
||||
* 优先复用现有槽位,不足时从 itemPrefab 实例化补充。
|
||||
* 实例化后立即按 slotPosX 定位,避免堆叠在 (0,0)。
|
||||
*/
|
||||
private ensureItemSlots(targetCount: number) {
|
||||
if (!this.shopBoxNode || !this.itemPrefab) return;
|
||||
@@ -570,6 +576,7 @@ export class MissionCardComp extends CCComp {
|
||||
const comp = node.getComponent(ItemListComp) || node.addComponent(ItemListComp);
|
||||
this.itemCardComps.push(comp);
|
||||
}
|
||||
this.layoutSlotsHorizontal(this.itemCardComps);
|
||||
}
|
||||
|
||||
/** 清空商品列表(复用槽位,仅清空数据) */
|
||||
@@ -1015,6 +1022,9 @@ export class MissionCardComp extends CCComp {
|
||||
// 根据物品数量设置列表面板高度
|
||||
this.resizeListBox(this.equipsBoxNode, targetCount);
|
||||
|
||||
// 三等分水平布局
|
||||
this.layoutSlotsHorizontal(this.equipCardComps);
|
||||
|
||||
// 默认显示装备面板
|
||||
if (this.equipsPanNode) {
|
||||
this.equipsPanNode.active = true;
|
||||
@@ -1029,6 +1039,7 @@ export class MissionCardComp extends CCComp {
|
||||
/**
|
||||
* 确保装备槽位数量足够。
|
||||
* 优先复用现有槽位,不足时从 equipPrefab 实例化补充。
|
||||
* 实例化后立即按 slotPosX 定位,避免堆叠在 (0,0)。
|
||||
*/
|
||||
private ensureEquipSlots(targetCount: number) {
|
||||
if (!this.equipsBoxNode || !this.equipPrefab) return;
|
||||
@@ -1043,6 +1054,7 @@ export class MissionCardComp extends CCComp {
|
||||
const comp = node.getComponent(EquipListComp) || node.addComponent(EquipListComp);
|
||||
this.equipCardComps.push(comp);
|
||||
}
|
||||
this.layoutSlotsHorizontal(this.equipCardComps);
|
||||
}
|
||||
|
||||
/** 清空装备列表(复用槽位,仅清空数据) */
|
||||
@@ -1088,6 +1100,9 @@ export class MissionCardComp extends CCComp {
|
||||
// 根据技能数量设置列表面板高度
|
||||
this.resizeListBox(this.skillBoxNode, targetCount);
|
||||
|
||||
// 三等分水平布局
|
||||
this.layoutSlotsHorizontal(this.skillCardComps);
|
||||
|
||||
// 默认显示技能面板
|
||||
if (this.skillPanNode) {
|
||||
this.skillPanNode.active = true;
|
||||
@@ -1102,6 +1117,7 @@ export class MissionCardComp extends CCComp {
|
||||
/**
|
||||
* 确保技能槽位数量足够。
|
||||
* 优先复用现有槽位,不足时从 sCardPrefab 实例化补充。
|
||||
* 实例化后立即按 slotPosX 定位,避免堆叠在 (0,0)。
|
||||
*/
|
||||
private ensureSkillSlots(targetCount: number) {
|
||||
if (!this.skillBoxNode || !this.sCardPrefab) return;
|
||||
@@ -1112,10 +1128,15 @@ export class MissionCardComp extends CCComp {
|
||||
// 补充实例化不足的槽位
|
||||
while (this.skillCardComps.length < targetCount) {
|
||||
const node = instantiate(this.sCardPrefab);
|
||||
// 先禁用根节点 Widget 再挂到父节点:
|
||||
// 否则 addChild 激活当帧 lateUpdate 时 Widget 会对齐覆盖 position
|
||||
const widget = node.getComponent(Widget);
|
||||
if (widget) widget.enabled = false;
|
||||
this.skillBoxNode.addChild(node);
|
||||
const comp = node.getComponent(SCardComp) || node.addComponent(SCardComp);
|
||||
this.skillCardComps.push(comp);
|
||||
}
|
||||
this.layoutSlotsHorizontal(this.skillCardComps);
|
||||
}
|
||||
|
||||
/** 清空技能卡槽(复用槽位,仅清空数据) */
|
||||
@@ -1232,6 +1253,10 @@ export class MissionCardComp extends CCComp {
|
||||
if (this.cardPrefab && this.cards_node && this.cards_node.isValid) {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const node = instantiate(this.cardPrefab);
|
||||
// 先禁用根节点 Widget 再挂到父节点:
|
||||
// 否则 addChild 激活当帧 lateUpdate 时 Widget 会对齐覆盖 position
|
||||
const widget = node.getComponent(Widget);
|
||||
if (widget) widget.enabled = false;
|
||||
this.cards_node.addChild(node);
|
||||
const comp = node.getComponent(CHeroComp) || node.addComponent(CHeroComp);
|
||||
this.cardComps.push(comp);
|
||||
@@ -1246,6 +1271,8 @@ export class MissionCardComp extends CCComp {
|
||||
cardPrefabValid: this.cardPrefab.isValid
|
||||
});
|
||||
}
|
||||
// 实例化后立即按 slotPosX 定位,避免堆叠在 (0,0)
|
||||
this.layoutCardSlots();
|
||||
} else {
|
||||
mLogger.log(this.debugMode, "MissionCardComp", "cacheCardComps failed", {
|
||||
cardPrefabValid: this.cardPrefab?.isValid,
|
||||
@@ -1503,7 +1530,49 @@ export class MissionCardComp extends CCComp {
|
||||
}
|
||||
|
||||
private layoutCardSlots() {
|
||||
// 布局由 cHero.prefab 根节点 Widget 约束控制,代码不再覆盖位置
|
||||
// 走 CHeroComp.setSlotPosition,同步更新其 restPosition,
|
||||
// 避免 clearBySystem 恢复位置时与布局结果不一致
|
||||
for (let i = 0; i < this.cardComps.length && i < this.slotPosX.length; i++) {
|
||||
const comp = this.cardComps[i];
|
||||
if (comp && comp.node && comp.node.isValid) {
|
||||
const widget = comp.node.getComponent(Widget);
|
||||
if (widget) widget.enabled = false;
|
||||
comp.setSlotPosition(this.slotPosX[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 三等分水平布局:
|
||||
* 按固定坐标数组 slotPosX 排列槽位,超出数量的槽位不处理。
|
||||
*
|
||||
* Why: 各卡池根节点的 Layout 组件已移除,槽位水平位置改由代码统一控制。
|
||||
* 部分预制体根节点残留 Widget 组件(对齐父节点中心),
|
||||
* 启用时会在 lateUpdate 覆盖代码设置的 position,需先禁用。
|
||||
*
|
||||
* @param comps 槽位组件数组(CHeroComp / EquipListComp / SCardComp / ItemListComp)
|
||||
*/
|
||||
private layoutSlotsHorizontal(comps: Array<CHeroComp | EquipListComp | SCardComp | ItemListComp>) {
|
||||
for (let i = 0; i < comps.length && i < this.slotPosX.length; i++) {
|
||||
const node = comps[i]?.node;
|
||||
if (!node || !node.isValid) continue;
|
||||
// 禁用根节点 Widget,防止其在对齐刷新时覆盖 position
|
||||
const widget = node.getComponent(Widget);
|
||||
if (widget) widget.enabled = false;
|
||||
const pos = node.getPosition();
|
||||
node.setPosition(this.slotPosX[i], pos.y, pos.z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟一帧执行布局:
|
||||
* 首次实例化的嵌套预制体在首帧会先恢复到原始位置,
|
||||
* 等下一帧预制体初始化完成后再定位,避免首帧堆叠在 (0,0)。
|
||||
*/
|
||||
private layoutSlotsHorizontalDeferred(comps: Array<CHeroComp | EquipListComp | SCardComp | ItemListComp>) {
|
||||
this.scheduleOnce(() => {
|
||||
this.layoutSlotsHorizontal(comps);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
private playButtonPressAnim(node: Node | null) {
|
||||
|
||||
Reference in New Issue
Block a user