Skip to content

自动挂载模型表现 ​

系统文档:docs/systems/AutoAttachedModelPresentationSystem.md。基础 Actor 概念见 docs/systems/ActorSystem.md;物品槽位和装备生命周期见 docs/systems/ItemSystem.md。

与 GameGraph 下钻接口的表里关系 ​

“附加模型”是被挂到宿主上的外观模型;本 Skill 的“自动挂载模型表现”是通过 Actor 与数据配置自动维护它的上层功能。GameGraph 的 AnimatedModelComponent.AttachAdditionModel(...) 是该功能的下钻版本,复用相同的挂载、骨骼跟随与可选宿主网格裁剪机制;下钻后宿主选择、挂载时机和 AdditionModelAttachment.Detach() 生命周期由调用方管理。ActorAdditionModel 继续属于 Actor 层。

直接 GameGraph 角色、代码控制换装或外观预览,转到 GameGraph 附加模型挂载;上层单位/物品/Buff 自动外观继续走本 Skill。下钻无需 model link 或附加模型 Actor,也不会自动监听物品槽位变化。不要让两条路线重复创建同一外观。

词汇边界 ​

面向外部用户时说“自动挂载模型表现”“附加模型 Actor”“携带/装备后的外观表现”。不要使用底层渲染实现名或项目内分类名。公开字段名可以使用,例如 GameDataActorAdditionModel、ActorArray、CullHostMesh。

选择配置入口 ​

用户需求写到哪里
物品装备或携带后给主人显示模型/光效GameDataItemMod.Modifications[ItemSlotType.*].ActorArray
单位出生就自带外观GameDataUnit.ActorArray
Buff、技能、效果持续期间显示外观对应数据的 ActorArray
直接 GameGraph 角色、换装预览、显式挂载与解除GameGraph 下钻 Skill
地上掉落物自身模型GameDataItem.Unit 指向的 GameDataUnit
地上掉落物品质光效GameDataItemQuality.ActorArray
服务端权威碰撞或命中判定不用表现 Actor;改用 Unit、物理或 replicated Node

标准物品配方 ​

  1. 定义 GameDataModel,填资源路径。
  2. 定义 GameDataActorAdditionModel,通常只填 Model;不要填挂接槽位,填写 Socket 也不会生效。不要把 Offset / Rotation / Scale 当成此功能的主要对齐方案。
  3. 把该 Actor link 放进 GameDataItemMod.Modifications[ItemSlotType.Equip].ActorArray 或目标槽位。
  4. 不写客户端手动创建/销毁逻辑;槽位变化时框架自动维护表现。

美术资源前置条件 ​

生成方案前先确认资源是否适合自动挂载模型表现:

  • 美术资源应使用目标宿主的原始骨架制作;程序侧不会通过 Socket 指定手、背、头等槽位。
  • 在宿主 Bind Pose 下把模型放到正确位置。
  • 把模型蒙皮到宿主骨骼:刚性手持物通常对手骨或表现用骨骼做 100% 权重;衣服、披风等按身体骨骼正常蒙皮。
  • 可以只保留实际使用的骨骼及必要父骨骼;骨骼名称必须和宿主完全一致,避免 DCC 工具自动添加命名空间或改名。
  • Bind Pose、坐标轴、单位和骨骼初始变换必须与宿主一致,否则可能漂移、变形,甚至影响宿主蒙皮。
  • 导出带 Skin 和骨骼的 FBX,不要导成纯静态模型;通常不需要动画。
  • 不同体型、职业或骨架如果摆放不同,优先使用不同模型资源或不同 GameDataActorAdditionModel。
  • 需要覆盖宿主主体的大面积外观,才考虑 CullHostMesh = true;普通手持物、背饰、挂件、头饰通常保持 false。
  • 如果用户反馈位置不对,优先建议检查 Skin、骨骼名、Bind Pose、坐标轴、单位、导出版本和资源适配体型,不要建议填写 Socket,也不要把普通 Actor 偏移当成主方案。
csharp
using GameCore.ActorSystem.Data;
using GameCore.Container;
using GameCore.ItemSystem.Data;
using GameCore.ResourceType.Data;
using GameData;

static readonly GameLink<GameDataModel, GameDataModel> VisualModel =
    new("$GameEntry.Models.HandHeldLantern"u8);
static readonly GameLink<GameDataActor, GameDataActorAdditionModel> VisualActor =
    new("$GameEntry.Actors.HandHeldLantern"u8);
static readonly GameLink<GameDataItem, GameDataItemMod> Item =
    new("$GameEntry.Items.Lantern"u8);

static void RegisterItemVisual()
{
    _ = new GameDataModel(VisualModel)
    {
        Asset = "deco/example/lantern/model.prefab"u8,
    };

    _ = new GameDataActorAdditionModel(VisualActor)
    {
        Model = VisualModel,
        // 无需填写挂接槽位;填写 Socket 也不会生效。
        // 位置、朝向和骨骼跟随由美术资源本身决定。
        CullHostMesh = false,
    };

    _ = new GameDataItemMod(Item)
    {
        DisplayName = "提灯",
        Unit = MyItemUnits.LanternOnGround,
        Modifications = new()
        {
            [ItemSlotType.Equip] = new()
            {
                ActorArray = [VisualActor],
            },
        },
        StackStart = 1,
        StackMax = 1,
    };
}

CullHostMesh 规则 ​

CullHostMesh 是公开配置字段,含义是“附加模型覆盖宿主主体时,减少宿主网格与附加模型重叠显示”。默认保持 false。

只在这些情况考虑 true:

  • 附加模型是外套、披风、整套外观或覆盖身体大面积区域的模型。
  • 宿主模型和附加模型发生明显穿插或重叠闪烁。

不要为了普通手持物、背饰、头饰、挂件默认开启。开启后必须实际预览,因为它影响的是宿主显示效果,不是碰撞、判定或服务端逻辑。

生成代码时的注意事项 ​

以下规则适用于 Actor 上层;GameGraph 下钻接口使用具体组件与 Prefab 资源,不套用 ActorArray / actor link 配方。两条路线共用美术资源适配要求。

  • GameDataActorAdditionModel 与引用它的物品/单位数据应在双端可见的数编初始化里注册;不要只放进 #if SERVER。
  • ActorArray 存 actor link,不存 model link。
  • 不要填 Socket。自动挂载模型表现无需填写挂接槽位,填写也不会生效;不要生成依赖 Socket 的方案。
  • 不要把 Offset / Rotation / Scale 当成自动挂载模型的主要对齐方案;位置问题优先回到美术资源检查。
  • 装备外观跟随物品槽位生命周期;不要额外写客户端常驻列表去重复创建同一个模型。
  • 表现 Actor 不做玩法判定。需要命中、碰撞、拾取范围或服务端权威位置时,另建逻辑对象或物理节点。

排错速查 ​

症状优先检查
装备后没显示当前槽位是否有 ActorArray;物品需求是否满足;客户端是否能解析 actor/model link
地上能看到,装备后看不到地上表现配在 GameDataItem.Unit,但装备表现漏配 Modifications[slot].ActorArray
装备能看到,地上看不到装备表现和地面物品表现是两条配置;检查 GameDataItem.Unit
位置不对Skin、骨骼名、Bind Pose、坐标轴、单位、导出版本;不要依赖 Socket 或普通 Actor 偏移
不同角色位置差异很大资源只适配一种体型/骨架;拆不同模型资源或不同 Actor 配置
主体穿插只对覆盖主体的大面积附加模型尝试 CullHostMesh = true