<div style="padding:15px 15px 2px 20px; border-radius:2px; margin-bottom:20px; border:1px solid #ddd">

<callout>
<p style="margin-bottom:0.75em"><b>Licensing</b></p>!!
将 Spine 官方运行时整合到自建应用程序中[需要持有 Spine 许可证](/git/spine-runtimes/spine-unity#licensing).
</callout>

<div style="font-size: 1.6em; margin: 0 0 .5em;">spine-unity 运行时文档</div>!!
* [安装运行时](/spine-unity-installation)
* [示例](/spine-unity-examples)
* [资产](/spine-unity-assets)
* [主要组件](/spine-unity-main-components)
* [工具组件](/spine-unity-utility-components)
* [渲染](/spine-unity-rendering)
* [时间轴扩展 UPM 软件包](/spine-unity-timeline)
* [懒加载扩展 UPM 软件包](/spine-unity-on-demand-loading)
* [常见问题(FAQ)](/spine-unity-faq)
</div>!!

# 常见问题(FAQ)

## 导入问题

你将Skeleton导入Unity时如果遇到错误, 那么其原因可能五花八门异彩纷呈, 从Spine导出设置有误到Unity中设置不对都有可能. 因此可参考以下视频, 它将帮助你解决导入过程中出现的常见问题, 并展示应如何正确设置导入导出参数.

<iframe width="560" height="315" src="https://www.bilibili.com/blackboard/html5mobileplayer.html?bvid=BV1BD4y1Y7By&page=1&high_quality=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="100%" height="500"></iframe>!!


> **为什么弹出一个"无法为......自动设置AtlasAsset"的窗口然后导入失败了?**  

![](/img/spine-runtimes-guide/spine-unity/CommonError-AtlasAsset.png)  

请确保你的atlas文件的扩展名为`.atlas.txt`而非`.atlas`. 详见 [基本Spine Unity导出流程](/spine-unity-assets#基本Spine-Unity导出流程) 一节.

如果文件扩展名正确但问题仍然存在，请检查您的骨架中是否缺少任何附件.可能是由于引用无效，导致某些纹理未正确打包.  
您可以通过在树视图中打开[查找和替换](/spine-tree#查找和替换)窗口并启用 `缺少图片` 选项来快速检查这一点.

![](/img/spine-runtimes-guide/spine-unity/CommonError-MissingImages.png)

> **从git下来的UPM包中打开场景时, 为什么会出现 "Opening scene in read-only package!"(打开的场景位于只读包中!) 错误?**

![Opening scene in readonly package](/img/spine-runtimes-guide/spine-unity/opening-scene-readonly-package.png)

如果你从git URL下载的包中直接打开场景, Unity的一个bug会引发错误: `"Opening scene in read-only package!"`. 因此应该用系统中的文件管理器(*Explorer*或*Finder*)先将包目录中的场景文件复制到你项目中的 `Assets` 目录下, 再打开包中附带的示例场景.

## 视效问题

> **为什么附件图像的透明区域有一圈黑框?**  

![](/img/spine-runtimes-guide/spine-unity/CommonError-PMA-as-Straight.png)  

最有可能的原因是你导出了 `Premultiply alpha` (PMA) 的textures, 但你在Unity中的Material或Texture的设置与此不匹配. 原理与解决方案详见[Premultiplied导入和Straight Alpha导入](/spine-unity-assets##进阶操作-Premultiplied和Straight-Alpha导入)一节. 如果你用的是 `Linear` 色彩空间, 请注意它是不支持PMA texture的.

另一种可能是, 在使用了straight alpha工作流程后, 在texture导入设置中启用了 `Generate Mip Maps`, 但没有对所有透明像素进行渗色(color bleed)处理. 即使从Spine导出时启用了 `Bleed` 选项, 若图像编辑器中再次修改了导出的texture, 仍可能会发生这种情况. 有些软件不能正确地在alpha为0的透明区域重新进行渗色, 而使像素的RGB值变为黑色或白色. 如果导出的texture未经修改且能正确显示, 而修改后的texture却不能正确显示, 那么缺少了渗色操作可能就是症结所在.

> **为什么我的附件图像的透明区域出现了彩纹?**  

![](/img/spine-runtimes-guide/spine-unity/CommonError-Straight-as-PMA.png)  

最有可能的原因是你把你的textures导出为了straight alpha (`Bleed`), 但你在Unity中的Material或Texture的设置与此不匹配. 原理与解决方案详见[Premultiplied导入和Straight Alpha导入](/spine-unity-assets#进阶操作-Premultiplied和Straight-Alpha导入)一节.

> **为何在启用Mip Maps生成后附件图像出现了了一圈白框?**  

![](/img/spine-runtimes-guide/spine-unity/CommonError-PMA-sRGB-Mipmaps.png)  

最有可能的原因是你导出了 `Premultiply alpha` (PMA) 的textures, 但你在Unity中的texture导入设置却启用了 `sRGB (Color Texture)`. 原理与解决方案详见[Premultiplied导入和Straight Alpha导入](/spine-unity-assets##进阶操作-Premultiplied和Straight-Alpha导入)一节.

> **为什么在Material设置中启用Tint Black选项后, Skeleton会显示错误的颜色?**

![](/img/spine-runtimes-guide/spine-unity/CommonError-Tint-Black.png)  

你得在 SkeletonRenderer 组件上启用 `Advanced - Tint Black` 功能.

> **给MeshRenderer分配材质(material)却被失败了. 尼玛的为什么?**

Materials的每一帧均由 `SkeletonRenderer` 控制, 详见[Materials](/spine-unity-rendering#Materials).
如果你需要替换某个实例的materials或某个槽位上的materials, 请阅读该节: [更改每个实例的Materials](/spine-unity-rendering#更改特定实例的Materials)..

> **为什么URP项目里某些Spine内置的着色器显示不正确?**

spine-unity 运行时只提供了兼容于 [**Built-In Render Pipeline(内置渲染管线)**](https://docs.unity3d.com/Manual/built-in-render-pipeline.html) 的着色器, 它们与 [**Universal Render Pipeline(通用渲染管线)**](https://unity.com/srp/universal-render-pipeline) 项目并不兼容. 如果你需要使用通用渲染管线, 请换用 [Spine URP着色器扩展UPM包](/spine-unity-rendering#URP着色器扩展UPM包) 中的 URP 着色器.

> **URP项目中的Outline着色器显示且仅显示了轮廓, 为毛啊?**

![](/img/spine-runtimes-guide/spine-unity/CommonError-Outline-URP.png)  

可能的原因有二:

1. 你在URP目中使用了内置渲染管线的着色器, 比如`Spine/Skeleton`或`Spine/Outline/Skeleton`. 内置渲染管线着色器和URP项目并不兼容. 请换用 [Spine URP着色器扩展UPM包](/spine-unity-rendering#URP着色器扩展UPM包) 中的 URP 着色器.

2. 若你用的正是 URP 着色器`Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly`, 那么它只渲染了轮廓是因为它是一个单pass的着色器. 加轮廓的正常做法是用 [`RenderExistingMesh`](/spine-unity-utility-components#renderexistingmesh) 组件来重渲染skeleton网格, 同时调用这个只渲染轮廓的着色器在skeleton下层加一圈轮廓, 这样看上去的效果才是对的.

更多详情见 [Spine URP着色器扩展UPM包](/spine-unity-rendering#URP着色器扩展UPM包) 一节里的示例场景`com.esotericsoftware.spine.URP-shaders/Examples/Outline Shaders URP`.

> **轮廓着色器给skeleton部件间的边缘都渲染了轮廓, 这是为毛啊?**

![](/img/spine-runtimes-guide/spine-unity/CommonError-Outline-Inner.png)  

当Skeleton需渲染多个materials时, 内置的轮廓着色器会试着渲染每个子网格而不是渲染skeleton整体. 最好的解决办法是在skeleton上只使用一个materials. 这一点可以通过分别打包各个atals, 或者通过 [运行时重打包](/spine-unity-main-components#组合皮肤) 功能来实现. 如果实在需要多个materials, 你可以使用 [`RenderCombinedMesh`](/spine-unity-utility-components#RenderCombinedMesh) 组件重渲染组合后的skeleton网格, 并使用仅轮廓(outline-only)着色器在skeleton下层加一圈轮廓. 仅轮廓着色器有用于内置渲染管线的`Spine/Outline/OutlineOnly-ZWrite` 和用于URP的 `Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly` 两种.

> **怎么替换某个槽位的Materials?**

解决方案详见 [更改特定实例的Materials](/spine-unity-rendering#更改特定实例的Materials) 一节.

> **我要在skeleton上使用normalmap, 但这效果咋看起来不对?**  

必须要在 `SkeletonRenderer` 组件上启用 `Advanced - Solve Tangents` 选项才行啊.

> **调整CanvasGroup alpha来淡出UI面板时, 为啥SkeletonGraphic会变亮?**

![](/img/spine-runtimes-guide/spine-unity/CommonError-CanvasGroupBright.png)

原因及解决方案详见 [SkeletonGraphic组件-CanvasGroup alpha](/spine-unity-main-components#CanvasGroup-alpha) 一节.

> **为啥在alpha淡出时仍会显示某部分的skeleton?**

![](/img/spine-runtimes-guide/spine-unity/CommonError-AlphaFadeOut.png)

这是个在有交叠的三角形在绘制过程中调整其透明度时经常出现的渲染问题. 原因及解决方案详见 [淡入或淡出Skeleton](/spine-unity-rendering#淡入或淡出Skeleton) 一节.

> **为啥我重打包的皮肤在编辑器中能显示, 但构建好的程序里却只显示些白色多边形?**

![](/img/spine-runtimes-guide/spine-unity/CommonError-RepackSkin.png)

原因及解决方案详见 [运行时重打包](/spine-unity-main-components#组合皮肤) 一节, 该节的重要须知中列出了该问题的常见成因.

## 程序行为不一致问题

> **我用git URLs导入的UPM包, 为啥我的项目在不同机器上的逻辑不一样?**  

如果你用的git URL以 `#4.2` 结尾, 那么Unity Package Manager就会从 `4.2` 分支下载最新版. 当项目第一次安装这些包时, 它会一次性地下载完最新版本的包. 所以某台早些时候下载了这些包的机器, 其上的软件包版本会比现在这台刚下了包的机器上的版本旧. 你可以在Unity包管理器中选择该包, 然后点击 `Update` 按钮来重新下载最新版的包. 也可以把git URL中的`#4.2`替换为特定的git commit哈希值(如 `#5e8e4c21f11603ba1b72c220369d367582783744` )来避免小版本不一致的问题, 这样便能确保项目中的每个人软件包版本完全一致. 下文中描述了如何获得git commit哈希值. 需要注意的是, Unity包管理器似乎无法识别短哈希格式(如 `#5e8e4c21` ).

> **那么, 你说的这个包管理器可以用的git commit哈希值, 在哪儿能找到呢?**  

访问 [github commits 页面](https://github.com/EsotericSoftware/spine-runtimes/commits/4.2) 就能找到commit哈希值, 在页面里选好你需要的分支, 然后点击commit右侧的Copy按钮(会提示 "复制完整的SHA")就能把哈希值复制到剪贴板了.
![](/img/spine-runtimes-guide/spine-unity/copy-git-commit-hash.png)

## 性能问题

> **实例化一个skeleton就搞得fps下降或触发了内存GC分配. 怎么优化?**  

1. 如果你的skeleton是以 `.json` 格式导出的, 可以考虑改成导出 `.skel.bytes` 的二进制格式. 详见 [导出用于Unity的二进制格式](/spine-unity-assets#导出用于Unity的二进制格式)一节.
1. 若你在游戏过程中实例化skeleton prefabs遇到了这类性能问题, 可以考虑在关卡加载时加载skeleton, 同时使用对象池而不要实时地实例化和销毁prefabs. 在关卡加载时加载多个(比如说10个)实例来预热对象池. 启用并重定位这些对象, 就不必实时地生成新对象了; 同样地, 禁用对象(以及使用 `AnimationState` 的 `ClearTracks` 去清空)而不要去销毁它们.

> **我发现某个skeleton上有大量地绘制调用/batches/materials. 这是咋回事?**  

你多半绘制中交替使用了多个atlas页或者不同的Slot blend模式. 详细信息见 [Materials](/spine-unity-rendering#Materials) 和 [Material切换和绘制调用](/spine-unity-rendering#Material切换和绘制调用) 两节.
当需要使用组合皮肤或包含多个atlas textures的附件时, 可以考虑靠 [运行时重打包](/spine-unity-main-components#组合皮肤) 将附件重打包到单个atals texture上, 不过必须得承担一次重打包操作的开销.

> **怎么提高skeleton性能?**  

1. 尽量少用剪裁(clipping)多边形, 考虑用Unity的遮蔽(masking)功能来实现. 如果你需要使用剪裁附件, 在剪裁多边形上用尽可能少的顶点. 多边形的面积对性能影响不大, 只有顶点数高了才会显著降低性能————举个例子, 覆盖一个矩形区域应该考虑用一个大三角形, 而非两个小三角形.
1. 尽量少用网格变形key.
1. 使用尽可能少的顶点.
1. 移除不必要的key, 别啥玩意儿都往里key.
1. 把Spine编辑器的[指标视图](/spine-metrics#指标视图)中的指标在导出前就全给优化了.
1. 使用尽可能少的atlas page textures.
1. 当某个skeleton的确需要多个materials时, 尝试优化Spine中的绘制顺序来尽量减少materials的切换次数, 或者直接优化atlas texture, 使绘制顺序列表中彼此相邻的附件打包到同一个atlas page texture中去.
原理与步骤详见 [Materials](/spine-unity-rendering#Materials) 和 [Material切换和绘制调用](/spine-unity-rendering#Material切换和绘制调用) 两节.
1. 尽量尝试用一个较大的atlas texture服务多个skeleton. 比如可以把同一个AtlasAsset分配到不同skeleton的 [SkeletonDataAsset atlas资产数组](/spine-unity-assets#Skeleton-Data资产) 中. 做法和注意事项详见 [打包](/spine-texture-packer#打包) 一节. 也可以考虑 [按文件夹结构打包](/spine-texture-packer#文件夹结构) 或者用 [命令行界面](/spine-command-line-interface) 来打包.

[上一节: 懒加载扩展](/spine-unity-on-demand-loading)