• Runtimes
  • Spine 导入unity ,播放时每帧都在生成新的材质和Mesh

Spine 导入unity ,播放时每帧都在生成新的材质和Mesh,这样就不能代码更改材质信息,这个时什么问题,有的Spine没问题运行时只生成一个材质,有的不停生成

    Related Discussions
    ...

    lxw 很遗憾您遇到了问题。你能告诉我们更多关于如何实例化骨架数据资产的信息吗?

    I'm sorry to hear you're having trouble. Could you tell us a little more about how you are instantiating your skeleton data assets?

    • lxw replied to this.

      Misaki
      就是正常的拉到Hierarchy里,运行场景,打印材质球,每帧都生成新的

      • lxw replied to this.

        lxw 在spine制作的时候用到了裁剪,把裁剪去掉,材质不多生成了,但Mesh还是美帧在变

        lxw

        “SkeletonRenderer”组件(以及“SkeletonAnimation”等子类)根据当前活动的附件每帧填充“MeshRenderer”的材质数组。 这是故意的。 请参阅此处有关如何覆盖材质的文档:
        https://zh.esotericsoftware.com/spine-unity#Materials



        The SkeletonRenderer component (and subclasses like SkeletonAnimation) fills the materials array of the MeshRenderer every frame based on the currently active attachments. This is done on purpose. See the documentation here on how to override materials:
        https://zh.esotericsoftware.com/spine-unity#Materials

        • lxw replied to this.

          Harald 感谢!但是有的可以只生成一个,有的用spine的裁剪就多生成,这样不会造成GC吗,这没法优化吗?

          我不确定机器翻译是否正确翻译了您的消息。 如果您询问当所需材料的数量从 1 变为 2 再回到 1 时是否创建不同大小的 Material[] 数组,那么是的,这会导致运行时分配。

          这可以通过保存所有先前使用的大小的地图或数组来避免,这将避免分配,但是当骨架需要大量(交替)材料时,通过存储大量不必要的数组大小使情况变得更糟。 10.

          这里的主要限制是 Unity MeshRenderer API 仅提供基于数组的变体来设置材质,直到 MeshRenderer.SetSharedMaterials 被引入 团结2022.2。 不幸的是,我们支持 Unity 版本回溯到 2017.1,因此更改代码以从 Material[] 数组切换到 List<Material> 目前对我们来说并不是一个真正的选择(并且为此添加一个单独的代码分支会重复太多代码) )。

          但是,如果您认为值得付出努力,请随意根据您的喜好修改提供的 spin-unity 源代码。 然而,我们怀疑这些分配是否是 GC 的真正问题。



          I'm not sure machine translation translated your message correctly. If you're asking whether creating Material[] arrays of different sizes when the number of required materials changes from 1 to 2 and then back to 1, then yes, this causes an allocation at runtime.

          This could be avoided by holding a map or arrays for all previously used sizes, which would avoid the allocation, however make the situation worse by storing a lot of unnecessary array sizes when Skeletons require lots of (alternating) materials, e.g. 10.

          The main limitation here is that the Unity MeshRenderer API only provided an array-based variant to set materials until MeshRenderer.SetSharedMaterials was introduced in Unity 2022.2. Unfortunately we support Unity versions back to 2017.1, so changing the code to switch from Material[] array to List<Material> is not really an option for us currently (and adding a separate code branch for that duplicates too much code).

          Feel free to modify the provided spine-unity source code to your liking however, if you think that this would be worth the effort. However, we doubt that these allocations are a real problem regarding GC.

          • lxw replied to this.

            Harald 再次感谢!你所说的也是遇到的一个问题,我一般会要求压缩贴图尽量在一个材质了,避免1到多,尽量减少。但我遇到的是一个材质在运行时不停生成,Mesh也一样,他就是在每帧生成新的材质`public SkeletonAnimation SkeletonAnimation;
            public List< Material> Materials;
            public List <Mesh> Meshes;



            void Update()
            {
                if (Input.GetKeyDown(KeyCode.A))
                {
                    if (!Materials.Contains(SkeletonAnimation.GetComponent<MeshRenderer>().material))
                    {
                        Materials.Add(SkeletonAnimation.GetComponent<MeshRenderer>().material);
                    }
                    if (!Meshes.Contains(SkeletonAnimation.GetComponent<MeshFilter>().mesh))
                    {
                        Meshes.Add(SkeletonAnimation.GetComponent<MeshFilter>().mesh);
                    }
                }
            }`这是我测试的代码,有些spine会打印多个材质和mesh

            Harald
            用法就是正常拖到场景里,我用的是3.8

            正如我在上一篇文章中所说,每一帧的材质都会被覆盖。 本文档部分对此进行了解释:
            https://zh.esotericsoftware.com/spine-unity#Materials
            有什么不清楚为什么每帧都会生成材质吗?

            如果您确实需要修改材质和网格,并且无法使用上述文档中描述的材质覆盖逻辑,您可以通过 SkeletonAnimation.OnMeshAndMaterialsUpdated 钩子调用您的代码,然后在正确的时间调用它。 您不应该按照文档中的说明在“Update()”中调用更改材质的代码。



            Materials are overridden every frame as I said in my previous posting. This is explained in this documentation section:
            https://zh.esotericsoftware.com/spine-unity#Materials
            Is there anything not clear why materials are generated each frame?

            If you really need to modify the materials and the mesh and can't use the material override logic described in the above documentation, you can call your code via the SkeletonAnimation.OnMeshAndMaterialsUpdated hook, then it's called at the right time. You should not call your material-changing code in Update() as explained in the documentation.

            如果您使用的是spine-unity 3.8,并且刚刚开始一个新项目,我们强烈建议您使用spine-unity 4.1。 自 3.8 版本以来,进行了大量错误修复和改进。


            If you're using spine-unity 3.8, and you've just started a new project, we highly recommend using spine-unity 4.1 instead. A lot of bugfixes and improvements have been made since version 3.8.

            • lxw replied to this.

              Harald 谢谢!调用已经了解。只是发现会产生很多材质和Mesh,考虑到优化的事。毕竟不停的产生材质会生成GC,当游戏里大量用Spine的时候,要考虑优化。我们的游戏不是新的项目,已经开了2年多了。

              请注意,并不是创建了很多材质,而是创建了很多指向材质的数组。 每个阵列的典型大小为 1-5,如果您的大小为 10-20,您的插槽绘制顺序可能会得到改善。 正如我上面提到的,缓存任何以前的不同大小的数组会让事情变得更糟,所以我们不会在将来的任何脊柱统一更新中包含它。

              如果您认为这是一个问题,请随意修改 3.8 spin-unity 运行时。 我们不会再发布 3.8 的任何更新,因此您可以放心地假设不会有更新覆盖您的代码修改。

              既然您还提到了网格:您想在那里优化什么? 三角形索引数组已经不会在每一帧重新分配,它们会按需增长,并且在需要较少元素时不会收缩。

              如果您使用裁剪,您应该考虑是否可以避免这种情况,因为这是一项成本非常高的操作。 此外,您还应该尽可能避免首先需要多种材质。



              Note that it's not a lot of materials that are created, it's a lot of arrays of that are created which point to materials. Each array has a typical size of 1-5, if you have sizes of 10-20 your slot draw order can likely be improved. As I mentioned above, caching any previous arrays of different sizes would make matters worse, so we won't include this in any spine-unity update in the future.

              If you consider that a problem, feel free to modify the 3.8 spine-unity runtime. We won't release any updates for 3.8 anymore, so you are safe to assume that there will be no update overwriting your code modifications.

              Since you also mentioned Meshes: what would you want to optimize there? Triangle index arrays are already not re-allocated every frame, these grow on demand and don't shrink when fewer elements are needed.

              If you're using clipping, you should consider wheter this can be avoided, as it's a very costly operation. Also you should try to avoid requiring multiple Materials in the first place as much as possible.

              • lxw replied to this.

                Harald 了解了,谢谢你的讲解。在下个项目中我们会用4.0版本.

                请注意,我们建议在项目启动时使用最新的非测试版,目前是 4.1,而不是 4.0。
                Note that we recommend using the latest non-beta version at project start, which currently is 4.1, not 4.0.