PAYATHON 2026

GML 中背包描述 Sequence 被其他内容遮挡,如何设置 depth?

数据小陈

结论

给物品描述 Sequence 单独创建一个图层,使该图层的 depth 小于绘制背包的实例的 depth。layer_sequence_create() 写在代码中的位置,不能保证 Sequence 覆盖前面绘制的内容。

你提到的 End Step 代码也可能影响绘制顺序。不过,目前还不知道 "Instances" 图层的 depth、背包绘制实例的实际 depth,以及代码所在的 Draw 事件类型,无法确定唯一原因。

为什么放在代码后面仍然被遮挡?

在同一个 Draw 事件中,直接调用的绘制函数通常按语句顺序绘制。例如,后调用的 draw_sprite() 可以覆盖前面绘制的矩形。

下面这行代码则是在指定图层上创建 Sequence 元素,绘制由引擎的图层流程处理:

desc_seq = layer_sequence_create("Instances", CameraMiddleX(), CameraMiddleY(), sqDescAnimation_1);

代码指定的图层是 "Instances"。这个函数不会把整个 Sequence 当作一条立即执行的绘制命令插入当前 Draw 事件。官方文档:layer_sequence_create

GameMaker 的图层 depth 数值越小,绘制位置越靠前。例如,depth 为 -200 的图层会覆盖 depth 为 -100 的图层。不同图层的 depth 相同时,不应依赖固定的先后顺序。官方文档:layer_create

End Step 中的排序如何影响这里?

原代码会根据实例包围盒的底边位置更新 depth,on_ui_layer 为真的实例除外:

with (all)
{
    if (!on_ui_layer) depth = -bbox_bottom;
}

如果负责绘制背包的实例没有被 on_ui_layer 排除,它的 depth 也会变化。背包实例可能因此移动到另一个绘制深度,而新建的 Sequence 仍位于指定的 "Instances" 图层,二者的前后关系就可能与预期不同。GameMaker 的官方 Sequence 教程也说明,按 -bbox_bottom 修改实例 depth 后,需要单独考虑 Sequence 图层。官方教程:Sequences 与实例 depth

还要区分 Sequence 元素和其中的对象实例:with (all) 遍历实例,不会直接修改 Sequence 元素的 depth;如果 Sequence 包含对象轨道,其生成的对象实例也可能进入这个循环。只给背包控制对象设置 on_ui_layer = true,不会自动保护这些对象。

如何设置独立的描述图层?

下面的示例适用于背包在普通 Draw 事件中绘制,且背包实例采用固定 depth 的情况。

在负责绘制背包的对象的 Create 事件中初始化:

// Exclude this instance from world depth sorting.
on_ui_layer = true;

// Example UI depth; adjust it to suit the room.
depth = -10000;

// Draw the description in front of the inventory.
desc_layer = layer_create(depth - 1, "InventoryDescription");

show_desc = false;

-10000 只是示例值,实际应根据房间里其他内容的 depth 选择,并保持在正常可绘制范围内。描述图层的 depth 需要小于背包实例的 depth;如果背包还包含其他绘制实例,也要考虑它们的深度。

保留原有的背包开启判断和鼠标命中判断,将点击分支改为:

if (mouse_check_button_pressed(mb_left) && !show_desc) {
    desc_seq = layer_sequence_create(
        desc_layer,
        CameraMiddleX(),
        CameraMiddleY(),
        sqDescAnimation_1
    );

    show_desc = true;
}

这样,Sequence 就会使用单独的描述图层。不要每次点击都重新创建图层,同一房间内复用已经创建的 desc_layer 即可。如果控制对象会跨房间保留,需要在进入新房间时重新取得或创建对应图层。

show_desc = true 用来避免窗口打开期间重复创建 Sequence。关闭窗口时,再按交互需要清理旧 Sequence 并恢复这个标志。原片段没有展示关闭逻辑,不能判断其他位置是否已经处理。

如果背包是在 Draw GUI 中绘制呢?

这时仅调整普通房间图层的 depth 不够。Draw GUI 在普通房间绘制之后执行,因此普通图层上的 Sequence 仍可能被 GUI 中的背包覆盖。官方说明:Draw 事件顺序

先确认代码实际放在哪个事件中:

  • 如果是普通 Draw,使用上面的独立图层方案,并固定背包及描述的相对 depth。
  • 如果是 Draw GUI,需要让描述窗口也通过相应的 GUI 绘制方案呈现,统一安排背包和描述的顺序。普通图层名称中包含 UI 或 GUI,不会改变它的绘制阶段。

改用 GUI 绘制时,还要同步调整坐标和鼠标命中检测。原代码使用房间坐标和相机偏移,不能直接假定它们与 GUI 坐标一致。

建议将点击检测和 Sequence 创建逻辑放在 Step 中,Draw 只负责绘制。迁移时,应在 Step 中重新计算物品命中区域所需的坐标,避免引用仅在 Draw 内存在的局部变量。

备注:内容仅供参考。