You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让带Skinned Mesh Renderer的装备预制体实例化时绑定到玩家Avatar?

模块化装备系统骨骼绑定异常解决方案

问题背景

我正在开发一套模块化装备系统,玩家可更换多件装备并在角色模型上看到变化,最终希望通过Addressables系统加载装备。目前遇到的问题是:模块化装备预制体实例化后会丢失对玩家骨骼(Rig)的引用,导致渲染异常。

我尝试通过C#代码为预制体的Skinned Mesh Renderer重新绑定所有骨骼,但效果不佳。左侧是实例化后的预制体(渲染异常),右侧是未从场景删除的新预制体(未丢失骨骼引用,渲染正常):

装备渲染对比:左侧异常,右侧正常

使用的代码如下:

void AssignArmorToArmature()
{
    // 实例化装备预制体
    GameObject armorInstance = Instantiate(armorPrefab, Vector3.zero, Quaternion.identity, playerArmature.parent.parent);
    armorInstance.transform.localPosition = Vector3.zero;
    armorInstance.transform.localRotation = Quaternion.identity;

    // 获取装备实例的SkinnedMeshRenderer
    SkinnedMeshRenderer armorRenderer = armorInstance.GetComponentInChildren<SkinnedMeshRenderer>();

    armorRenderer.bones = playerArmature.GetComponentsInChildren<Transform>();
    armorRenderer.rootBone = playerArmature; 
}

已确认模型权重绘制正确且骨骼名称一致,此为非问题原因,寻求其他解决方法。


解决思路与方案

1. 按名称精准匹配骨骼(核心修复)

当前代码直接将角色所有子Transform赋值给装备的骨骼列表,会导致骨骼顺序、数量与装备原始绑定的骨骼不匹配——装备仅需绑定它实际用到的骨骼,而非角色全量骨骼。修改代码按名称匹配对应骨骼:

void AssignArmorToArmature()
{
    // 直接将装备挂到角色骨骼节点下,避免层级偏移
    GameObject armorInstance = Instantiate(armorPrefab, playerArmature);
    armorInstance.transform.localPosition = Vector3.zero;
    armorInstance.transform.localRotation = Quaternion.identity;

    SkinnedMeshRenderer armorRenderer = armorInstance.GetComponentInChildren<SkinnedMeshRenderer>();
    List<Transform> matchedBones = new List<Transform>();

    // 遍历装备原始绑定的骨骼,从角色骨骼树中找到同名节点
    foreach (var originalBone in armorRenderer.bones)
    {
        Transform targetBone = playerArmature.Find(originalBone.name);
        if (targetBone != null)
        {
            matchedBones.Add(targetBone);
        }
        else
        {
            Debug.LogWarning($"未找到对应骨骼:{originalBone.name}");
        }
    }

    // 赋值匹配后的骨骼与根骨骼
    armorRenderer.bones = matchedBones.ToArray();
    armorRenderer.rootBone = playerArmature;

    // 强制刷新渲染状态
    armorRenderer.enabled = false;
    armorRenderer.enabled = true;
    armorRenderer.sharedMesh = armorRenderer.sharedMesh; // 触发网格绑定刷新
}

2. 检查预制体序列化问题

如果预制体是外部导入后直接生成,可能存在骨骼引用序列化丢失:

  • 打开预制体,选中SkinnedMeshRenderer组件,确认Bones列表完整且正确,重新保存预制体
  • 若使用Addressables,确保加载的是完整预制体资源,而非仅部分GameObject

3. 层级结构对齐

实例化装备时,优先将其挂载到playerArmature节点下,而非上层节点,避免层级结构差异导致的骨骼引用失效。

4. 启用Offscreen刷新

在SkinnedMeshRenderer组件中勾选Update When Offscreen,确保装备在屏幕外时也能完成骨骼绑定刷新,避免切换视角时出现异常。


内容的提问来源于stack exchange,提问作者Yecats

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:23:08