Licensing
将 Spine 官方运行时整合到自建应用程序中需要持有 Spine 许可证.
工具组件
SkeletonRootMotion
spine-unity中的三种Spine skeleton组件均支持root motion. SkeletonRootMotion
组件可以附加到带有SkeletonAnimation 和 SkeletonGraphic (UI) 组件的GameObjects上, 同时为SkeletonMecanim单独提供了 SkeletonMecanimRootMotion 组件. 这个root motion组件类似于在Unity Mecanim的 Animator
组件上启用 Apply Root Motion
选项. 当启用了这个选项后, 运行时会根据动画里 Root Motion Bone
的运动来更改角色位置.
请注意: SkeletonMecanimRootMotion 组件仅能用于 SkeletonMecanim 对象. 将它用于
SkeletonAnimation
或SkeletonGraphic (UI)
组件时,SkeletonRootMotion
组件将无法正常工作.
参数
- Root Motion Bone. 该参数指定root motion的目标骨骼, 该骨骼的运动将驱动root motion.
- X. 启用后, 局部的横向(X轴)运动将用于root motion.
- Y. 启用后, 局部的纵向(Y轴)运动将用于root motion.
- Root Motion Scale (X). 缩放横向root motion移动变化量(delta). 可用于修正delta, 例如将一个跳跃动画拉伸到某个特定距离.
- Root Motion Scale (Y) 缩放纵向root motion移动变化量. 可用于修正delta, 例如将一个跳跃动画拉伸到某个特定高度.
- Animation Tracks. 可以指定root motion的计算中应该包含哪些 动画轨道.
可选参数
- Rigidbody2D. 当指定了
Rigidbody2D
组件后, 运行时将基于物理计算把运动应用于Rigidbody2D
而不是Transform
组件. 因此建议将检查器里skeleton动画组件的Advanced
-Animation Update
参数置为In FixedUpdate
. - Rigidbody. 当指定了
Rigidbody
组件后, 运行时将基于物理计算把运动应用于Rigidbody
而不是Transform
组件. 因此建议将检查器里skeleton动画组件的Advanced
-Animation Update
参数置为In FixedUpdate
.
请注意:
SkeletonRootMotion
类提供了AdjustRootMotionToDistance()
及其他方法来修正Delta. Delta修正在特定场景下 (例如将一个跳跃动画拉伸到一个特定距离) 会很有帮助. 你既可在动画开始时调整Root motion, 也可以用skeletonRootMotion.AdjustRootMotionToDistance(targetPosition - transform.position, trackIndex);
每帧都调整Root motion.
SkeletonMecanimRootMotion
该组件是SkeletonMecanim版的 SkeletonRootMotion 组件, 搭配 SkeletonMecanim 组件使用.
当启用了Unity Mecanim Animator
的 Apply Root Motion
选项时, 运行时会将 SkeletonMecanimRootMotion
组件自动添加到skeleton的GameObject上. 必须先禁用Animator的 Apply Root Motion
选项, 才能移除 SkeletonMecanimRootMotion
组件.
参数
- Root Motion Bone. 该参数指定root motion的目标骨骼, 该骨骼的运动将驱动root motion.
- X. 启用后, 局部的横向(X轴)运动将用于root motion.
- Y. 启用后, 局部的纵向(Y轴)运动将用于root motion.
- Root Motion Scale (X). 缩放横向root motion移动变化量(delta). 可用于修正delta, 例如将一个跳跃动画拉伸到某个特定距离.
- Root Motion Scale (Y) 缩放纵向root motion移动变化量. 可用于修正delta, 例如将一个跳跃动画拉伸到某个特定高度.
- Mecanim Layers. 可以指定root motion的计算中应该包含哪些 Mecanim图层.
可选参数
- Rigidbody2D. 当指定了
Rigidbody2D
组件后, 运行时将基于物理计算把运动应用于Rigidbody2D
而不是Transform
组件. - Rigidbody. 当指定了
Rigidbody
组件后, 运行时将基于物理计算把运动应用于Rigidbody
而不是Transform
组件.
请注意:
SkeletonMecanimRootMotion
类提供了AdjustRootMotionToDistance()
及其他方法来修正Delta. Delta修正在特定场景下 (例如将一个跳跃动画拉伸到一个特定距离) 会很有帮助. 你既可在动画开始时调整Root motion, 也可以用skeletonRootMotion.AdjustRootMotionToDistance(targetPosition - transform.position, trackIndex);
每帧都调整Root motion.
BoneFollower
该组件会引用 SkeletonAnimation 组件中的一根骨骼, 并在每次 Update
时将自己的transform置为该骨骼的transform.
请注意: SkeletonGraphic 对象有自己专用的 BoneFollowerGraphic 组件.
与 SkeletonUtilityBone 组件不同, BoneFollower
可以作为一个单独的GameObject使用, 无需任何父级骨骼对象.
使用该组件可以让粒子系统这样的对象跟随skeleton上的某根骨骼.
你可以在示例场景 Spine Examples/Getting Started/4 Object Oriented Sample 中查看如何设置 BoneFollower
组件.
BoneFollowerGraphic
该组件为 SkeletonGraphic 版的 Bone Follower 组件, 需搭配 SkeletonGraphic 组件使用.
与 SkeletonUtilityBone 组件不同, BoneFollowerGraphic
可以作为一个单独的GameObject使用, 无需任何父级骨骼对象.
使用该组件可以让粒子系统这样的对象跟随skeleton上的某根骨骼.
你可以在示例场景 Spine Examples/Getting Started/6 Skeleton Graphic 中查看如何设置BoneFollowerGraphic
组件.
PointFollower
该组件类似于 Bone Follower 组件, 但它跟随的是一个 PointAttachment 而非某根骨骼.
与 SkeletonUtilityBone 组件不同, PointFollower
可以作为一个单独的GameObject使用, 无需任何父级骨骼对象.
BoundingBoxFollower
该组件跟随的是skeleton槽位中的某个 边界框(bounding box). 它会获取边界外型并将其传递给 PolygonCollider2D
, 然后在每帧启用或禁用它来匹配当前动画.
请注意: 它不会自动跟随骨骼位置, 因此它通常搭配
BoneFollower
组件一起使用. 你可以在BoundingBoxFollower
检查器中使用Add Bone Follower
按钮来直接创建一个BoneFollower
组件.
请注意: 组件不会跟随顶点变形动画(边界框顶点会随时间移动的动画), 组件只会跟随边界框的初始形状.
更多信息请参见 Bone Follower 一节.
SkeletonUtilityBone
有时候需要在运行中程序化地修改骨骼位置, 以便对物理运动或用户输入做出反应.
SkeletonUtilityBone 组件提供了一个方便的接口, 既能让GameObjects跟随某根骨骼位置, 又能手动地或基于2D/3D物理运动修改某根骨骼的位置. 它可以配置为 跟随(follow) 骨骼局部位置, 也能配置为在每次 Update
时 覆盖(override) 骨骼位置. 当设置是 Override
时, 该组件将在SkeletonAnimation 组件更新世界transform之前设置骨骼位置.
重要提示:
SkeletonUtilityBone
使用局部transform. 这个transform与SkeletonUtilityBone
GameObjects的层次结构相关, 而该组件的GameObject层级结构正是skeleton层次结构的体现. 快速创建SkeletonUtilityBone
层次结构的推荐方法是使用 下文所述 的SkeletonUtility
组件.
SkeletonUtilityBone
的检查器也有一个界面来 (选择性或递归地) 创建额外的子骨骼或创建 2D 和3D铰链(hinge chain).
当创建了 SkeletonUtilityBones
的层次结构后, 层次结构面板会在 SkeletonUtilityBone
GameObject旁边显示不同的图标, 这两种图标对应的设置是
Follow
:- 或者
Override
:
示例用例
如果你需要让用户拖动skeleton的某根骨骼, 请在 Override
模式下使用 SkeletonUtilityBone
.
但如果只需要让一个GameObject跟随某根骨骼的位置, 则应使用 BoneFollower 组件来节省资源.
示例场景
你可以在 Spine Examples/Other Examples/SkeletonUtility Animated Physics
中找到一个演示了 SkeletonUtilityBone
用法的示例场景. 它展示了如何将 SkeletonUtilityBones
中的某些节点配置为 Follow
, 并在层次结构中作为 Override
节点的父节点.
2D与3D物理铰链
你有时需要为你角色的披风添加物理效果, 让角色拖拽重物或者给他装个流星锤. spine-unity运行时可以从已有的 SkeletonUtilityBone 层次结构 (见 创建SkeletonUtilityBones的层次结构 一节) 中生成 HingeJoint 或 HingeJoint2D 的物理绑定(physics rig).
选中一根骨骼作为首个 SkeletonUtilityBone
铰链条目, 然后在检查器中点击 Create 3D Hinge Chain
或 Create 2D Hinge Chain
就能生成物理绑定. 被选中的骨骼和其所有的 SkeletonUtilityBone
子节点都会被转换为一条铰链. 此后你便可以调整Rigidbody的阻力(drag)和质量(mass)参数来调整效果. 提高阻力值将使Rigidbody移动得更慢, 可以创造出物体沉重甚至风阻效果.
请注意, 铰链的根节点不再以skeleton的骨骼为父节点, 而是被放置到场景层级的顶层中. 这是基于在Unity中正确计算动量的需要. 请勿把铰链根节点再放回skeleton的骨骼层级中, 否则skeleton的运动将不再与铰链联动!
3D铰链
- 创建 SkeletonUtilityBone的层次结构.
- 在场景面板中选中一根骨骼作为首个铰链条目, 然后在检查器中选择
Create 3D Hinge Chain
来创建3D铰链绑定. - 这会使先前的父对象 (在本例中为
cape-root
) 移除铰链的GameObjects, 并在场景层级中新建一个HingeChain Parent
GameObject. 正如前文中所警示的: 切勿将该GameObject重新放回到skeleton中去! - 调整铰链中节点的Rigidbody的阻力和质量参数来实现你所需的效果.
Skeleton翻转后, HingeChain Parent
GameObject将自动旋转180度, 使铰链适应翻转后的骨骼位置.
2D铰链
- 创建 SkeletonUtilityBone的层次结构.
- 在场景面板中选中一根骨骼作为首个铰链条目, 然后在检查器中选择
Create 2D Hinge Chain
来创建2D铰链绑定. - 这会使先前的父对象 (在本例中为
cape-root
) 移除铰链的GameObjects, 并在场景层级中新建一个HingeChain Parent
GameObject. 正如前文中所警示的: 切勿将该GameObject重新放回到skeleton中去! - 调整铰链中节点的Rigidbody2D的阻力和质量参数来实现你所需的效果.
要注意该GameObject包含两个子对象: Hinge Chain
和 Hinge Chain FlippedX
. 翻转了skeleton后, 这些GameObjects将根据当前朝向自动启用或停用对应子对象.
SkeletonUtility
创建SkeletonUtilityBones的层次结构
SkeletonUtility
组件提供了一个快速创建 SkeletonUtilityBone
GameObjects层次结构的方法, 该层次结构是对skeleton中骨骼层次结构的映射.
添加 SkeletonUtility
组件的步骤: 选中 SkeletonAnimation 组件, 在检查器中展开 Advanced
部分并点击 Add Skeleton Utility
. 该组件创建后, Add Skeleton Utility
按钮将消失, 而 SkeletonUtility
组件将被附加到GameObject上.
SkeletonUtility
组件中有一个 Spawn Hierarchy
按钮, 点击后会出现以下选项:
Follow all bones
意在为层次结构中的所有骨骼创建SkeletonUtilityBone
GameObject, 并将其置为Follow
模式Follow (Root Only)
只创建根SkeletonUtilityBone
GameObject, 并将其置为Follow
模式Override all bones
会为层次结构中的所有骨骼创建SkeletonUtilityBone
GameObject, 并将其置为Override
模式Override (Root Only)
只创建根SkeletonUtilityBone
GameObject, 并将其置为Override
模式
每个 SkeletonUtilityBone
都能配置为覆盖skeleton的任意骨骼位置.
请注意:
Spawn Hierarchy
功能只是生成大致结构, 你也能稍后在SkeletonUtilityBone
检查器中添加额外的SkeletonUtilityBone
GameObjects. 之后删除多余的SkeletonUtilityBone
GameObjects来节省资源也可以. 只需记住务必要保持父子关系不变, 因此切勿删除层次结构中的GameObjects或改变其父节点.
SkeletonUtilityConstraint
C#
它是skeleton约束工具子类的基类. 它会自动在父类 SkeletonUtility
中注册自己并进行相应的更新.
关于如何编写自定义约束类的指南, 请参见示例约束类 SkeletonUtilityGroundConstraint
和 SkeletonUtilityEyeConstraint
的代码.
示例场景
spine-unity运行时内置了演示上文中两个约束类的示例场景. 你可以在 Spine Examples/Other Examples/SkeletonUtility GroundConstraint
和 Spine Examples/Other Examples/SkeletonUtility Eyes
中找到它们.
SkeletonRendererCustomMaterials
用于覆盖某个skeleton实例的material或者某个槽位的material. 该组件提供了一个检查器界面, 可以在SkeletonRenderer 组件(包括其子类 SkeletonAnimation 和 SkeletonMecanim) 上覆盖自定义的material.
右击 SkeletonRenderer 组件(包括其子类 SkeletonAnimation 和 SkeletonMecanim), 并选择 Add Basic Serialized Custom Materials
可以将该组件添加到渲染器中. 在 Custom Slot Materials
数组中添加条目就能覆盖某个槽位的material, 如果条目添加在 Custom Material Overrides
数组中, 可以替换掉整个skeleton当前的material. 请确保禁用了 Override Disabled
选项, 这样才能让各条目中设置的material覆盖生效.
请注意: 该组件的设计初衷里不包括用代码控制Material覆盖. 如果需要通过代码动态地设置SkeletonRenderer的material, 应直接通过
SkeletonRenderer.CustomMaterialOverride
来访问material覆盖数组, 或者SkeletonRenderer.CustomSlotMaterials
来访问槽位上的material覆盖数组.
SkeletonGraphicCustomMaterials
该组件是 SkeletonRendererCustomMaterials 的 SkeletonGraphic 专用版本. 该组件也有检查器界面, 可以为 SkeletonGraphic 设置自定义material和自定义texture覆盖.
右击 SkeletonGraphic 组件, 并选择 Add Basic Serialized Custom Materials
可以将该组件附加到渲染器上. 在 Custom Texture Overrides
数组中添加条目可以替换整个skeleton的texture. 在 Custom Material Overrides
数组中添加条目, 可以保留texture但替换material. 请确保禁用了 Override Enabled
选项, 这样才能让各条目中设置的texture或material覆盖生效.
请注意: 该组件的设计初衷里不包括用代码控制Material覆盖. 如果需要通过代码动态地设置SkeletonGraphic的material, 应直接通过
SkeletonGraphic.CustomMaterialOverride
来访问material覆盖数组, 或者通过SkeletonGraphic.CustomTextureOverride
访问texture覆盖数组.
SkeletonRenderSeparator
有时需要在角色的各部件之间显示其他的GameObjects, 例如角色爬到树上的过程中应该在树干图层之上显示一条腿, 同时在树干图层之下显示另一条腿. 对此可以使用 SkeletonRenderSeparator
组件, 它能将 SkeletonRenderer 组件(包括其子类 SkeletonAnimation) 分割为多个 SkeletonPartsRenderers
, 且可自定义其图层顺序(layer order).
请注意: SkeletonGraphic 组件在
SkeletonGraphic
检查器的Advanced
面板中直接提供了渲染分割功能, 它实现该功能无需添加任何额外组件.
请注意: 通常情况下, Spine渲染器组件使用单个渲染器显示整个skeleton网格. 不过在其部件(parts)之间就无法插入其他
UnityEngine.Renderers
(例如SpriteRenderer
,MeshRenderer
,ParticleSystem
等等) 组件了.
设置步骤
-
确定Skeleton的绘制顺序(draw order). 确定将Skeleton渲染分割为多个部件的槽位. 为方便起见, 在导出skeleton前应清晰地标注该槽位.
-
添加SkeletonRenderSeparator组件 选中Spine GameObject. 在检查器中右击 SkeletonAnimation 或 SkeletonRenderer 组件. 选择
Add Skeleton Render Separator
,SkeletonRenderSeparator
组件将被附加到GameObject上.
-
指定Separator槽位 这时检查器会显示一个警告, 因为separator列表现在是空的. 你可以在
Separator Slot Names
中选择所需的槽位, 而点击+
按钮能够添加额外的separator槽位.请注意: 该列表实际会在 SkeletonRenderer(及其子类 SkeletonAnimation 和 SkeletonMecanim) 组件中进行序列化,
SkeletonRenderSeparator
只是它的一个设置界面. -
添加部件渲染器 此时检查器会显示一个警告:没有部件渲染器. 点击
Add the missing renderers (n)
按钮, 会创建带有SkeletonPartsRenderer
组件的GameObjects. 运行时会将这些GameObjects自动分配到上面的Parts Renderers
列表中.请注意:
SkeletonRenderSeparator
会通过绘制顺序来检测当前所需的部件渲染器数量. 如果在运行时中修改了绘制顺序, 渲染器可能会要求添加额外的部件渲染器. 此时可以点击Add Parts Renderer
按钮来手动添加部件渲染器. -
设置
Sorting Layer
和Order in Layer
每个SkeletonPartsRenderers
都在检查器中提供了Sorting Layer
和Order in Layer
属性. 每个SkeletonPartsRenderer
中都能设置排序属性值, 值越大的部件渲染器渲染排序越靠前.
请注意:
SkeletonPartsRenderer
GameObjects不必作为Spine GameObject的子对象.SkeletonRenderSeparator
会自动维护引用, 所以你大可按需组织场景层次结构.
示例场景
在 Spine Examples/Other Examples/SkeletonRenderSeparator
中可以找到演示 SkeletonPartsRenderer
和 SkeletonRenderSeparator
用法的示例场景.
C#
组件的启用和禁用
默认情况下, SkeletonRenderSeparator
将禁用 SkeletonRenderer 组件并接管其网格渲染工作. 所以当禁用了 SkeletonRenderSeparator
之后, SkeletonRenderer 将重新接管渲染工作.
启用和禁用 SkeletonRenderSeparator
的方法同其他组件一致:
skeletonRenderSeparator.enabled = false; // separation is disabled.
更改分割点
分割点并没有存储在 SkeletonRenderSeparator
中.
它由 SkeletonRenderer 组件(包括其子类 SkeletonAnimation 和 SkeletonMecanim) 中的separator槽位存储. 若需在运行中更改separator槽位, 可以用代码访问 SkeletonRenderer.separatorSlots
列表, 然后像操作普通列表一样调用它的 Add
, Remove
和 Clear
方法.
skeletonAnimation.separatorSlots.Clear();
skeletonAnimation.separatorSlots.Add(mySlot);
在运行中动态添加SkeletonRenderSeparator
使用静态方法 SkeletonRenderSeparator.AddToSkeletonRenderer
可以添加并初始化一个新的 SkeletonRenderSeparator
组件.
skeletonAnimation.SeparatorSlots.Add(mySlot); // see above
// Add the SkeletonRenderSeparator.
SkeletonRenderSeparator skeletonRenderSeparator = SkeletonRenderSeparator.AddToSkeletonRenderer(skeletonAnimation);
它将默认添加当前所需的 SkeletonPartsRenderers
组件. 它也为进阶用例提供了一些可选的参数, 详情请查看 代码文档.
示例组件
spine-unity附带了额外的示例组件, 它们展示了一些进阶用例的解决方案. 下文列出了一些最重要的示例组件.
SkeletonRagdoll
有时需要在一个可动的skeleton上实现类似木偶的布娃娃(Ragdoll)效果, 例如在角色死亡时物理地模拟摔倒. 这可以通过 SkeletonRagdoll
和 SkeletonRagdoll2D
示例组件来实现, 它们提供了一个简单界面, 可在SkeletonRenderer 组件(包括其子类 SkeletonAnimation 和 SkeletonMecanim) 上创建布娃娃物理组件.
在示例场景 Spine Examples/Other Examples/SkeletonUtility Ragdoll
中可以找到对 SkeletonRagdoll2D
组件的演示.
SkeletonRenderTexture
适用于需要将skeleton渲染到 RenderTexture 上而非直接渲染到屏幕上的情况, 比如需要 调整透明度来淡出一个skeleton. 该组件可以将skeleton以适当的尺寸和分辨率渲染到 RenderTexture
并显示于合适的四边形中, 如此便能无缝替换掉这个skeleton.
下文中的 SkeletonRenderTextureFadeout 组件需要将一个 SkeletonRenderTexture
或一个 SkeletonGraphicRenderTexture 组件作为输入. 在给GameObject添加了 SkeletonRenderTexture
组件后, 可以再添加一个 SkeletonRenderTextureFadeout
组件来实现淡出效果.
重要提示: 相较于直接将skeleton绘制到帧缓冲区中, 使用RenderTexture中间件进行渲染是开销较大的做法. 只有在必要之处才应使用该组件. 建议保持其禁用状态, 直到你确实需要展示效果的时候再启用它. 例如仅在淡出时启用
SkeletonRenderTexture
组件, 而在其他时间均保持其禁用.
SkeletonGraphicRenderTexture
SkeletonGraphic版的 SkeletonRenderTexture 组件.
SkeletonRenderTextureFadeout
适用于想调整透明度来淡出skeleton, 但又想避免 这类 附件交叠问题的情况. 该组件可以与 SkeletonRenderTexture 或 SkeletonGraphicRenderTexture 组件(需预先添加)搭配使用, 将一个不透明的skeleton渲染到一个临时的 RenderTexture 上, 然后在场景中以渐变不透明度的方式绘制这个 RenderTexture
中的内容.
SkeletonGhost
适用于给角色渲染一个运动轨迹(motion-trail)或运动模糊(motion-blur)效果来模拟速度或力量的情况.SkeletonGhost
组件可以附加在 SkeletonRenderer 组件(包括其子类 SkeletonAnimation) 上, 使用自定义material多次绘制skeleton.
SkeletonUtilityKinematicShadow
适用于需要让某些骨骼带有惯性或响应其他骨骼的运动的情况, 比如让披风以一种更真实的方式跟随角色运动的情况. 此时可以通过 SkeletonUtilityKinematicShadow
组件来实现. 它可以让铰链(hinge chains)从父级transform甚至无关的rigidbody的位置变化中继承速度矢量.
在示例场景 Spine Examples/Other Examples/SkeletonUtility Animated Physics
中可以找到 SkeletonUtilityKinematicShadow
组件的演示.
RenderExistingMesh
适用于试图在不同位置多次渲染同一个可动skeleton来压榨性能的情况, 比如渲染一大群相似的skeleton. 也适用于希望在选中网格后, 用URP着色器 (比如 Universal Render Pipeline/Spine/Outline/Skeleton-OutlineOnly
) 在其下层将它再渲染一次的场景. 该组件可以重新渲染一个已经播放了动画并更新过了的skeleton网格, 由此节省计算动画和计算网格的开销.
RenderCombinedMesh
当skeleton需使用多种material时, 运行时自带的轮廓着色器会渲染出每个子网格的轮廓, 而不会把skeleton作为整体渲染其轮廓. 使用该组件可以合并这些子网格, 并将其作为单个网格来渲染, 从而勾勒出正确的skeleton轮廓.