unity中使用spine详解

一.Spine概述

Spine 是一款针对游戏开发的 2D 骨骼动画编辑工具。 Spine 旨在提供更高效和简洁 的工作流程,以创建游戏所需的动画。

Spine原理:将一个模型,根据动画的需求分成一些骨骼,一个骨骼对应一张贴图,控制骨骼位置、缩放、旋转等形成动画;

Spine工作流程如下所示:

参考:认识Spine

二.导入spine-unity 运行时

下载spine-unity unitypackage

下载完成后将其拖入到Project视图中, Import,完成导入,新增Spine和Spine Examples目录

Important:spine运行时版本需要和导入的spine资源一致,若导入不一致的spine资源时,会弹出对话框并报错

参考:spine-unity 下载

三.导入spine资源

3.1 spine导出的文件转unity资产

 通过spine编辑器导出的unity资源如图所示

  1. skeleton-name.json 或 skeleton-name.skel.bytes, 其中包含了skeleton和动画数据.
  2. skeleton-name.atlas.txt, 保存的是texture atlas的信息.
  3. 单个或数个 .png 文件, texture atlas中的一页就对应着这样一个文件, 而texture atlas则包含了skeleton所需的全部图片.

将导出的文件(或包含它们的文件夹)拖到Unity的项目面板中的某个目录下

spine-unity运行时在检测到文件添加后会自动生成Unity所需的资产文件.

自动生成具体会产生以下资产:

  1. 一个代表texture atlas文件 (.atlas.txt)的 _Atlas 资产文件. 它包含对material(材质)和 .atlas.txt 文件的引用.
  2. 一个代表各 texture atlas页 (.png) 的 _Material 资产文件. 它包含对着色器和 .png texture的引用.
  3. 一个存储了skeleton数据 (.json.skel.bytes) 的 _SkeletonData 资产文件. 它包含了对 .json 或 .skel.bytes 文件的引用以及对自动生成的 _Atlas 资产的引用. 它还可以自定义的skeleton导入和设置skeleton动画.

3.2 更新spine资源

在实际开发过程中, 你可能经常需要更新Spine skeleton数据和texture atlas文件. 直接覆盖这些文件其实就能更新这些文件 (.json.skel.bytes.atlas.txt.png). 只需从Spine编辑器中重新导出资产, 并将新导出的文件复制到项目中 Assets 文件夹的子文件夹中覆盖现有文件即可.

Unity会检测这些文件的变化, 并自动重新导入修改后的资产. 自动重新导入会保持对Spine资产引用的完整性同时使用最新数据.

3.3 动画预览

选中*_SkeletonData,在Inspector中可以预览动画,获取动画名称

所有时间轴事件以紫色标记显示. 在播放预览时将鼠标悬停在标记上, 就能显示事件名称.

注意:play模式下无法预览

点击 Create Animation Reference Assets 按钮即可为skeleton的所有动画生成引用资产. AnimationReferenceAsset 和一个引用了 Spine.Animation 的Unity资产行为完全一致, 也可以将它用在Unity检查器的组件属性中.

参考:资产

四.Editor中创建动画对象

  1. 将*_SkeletonData文件拖入Hierarchy视图中
  2. 选择需要的组件
  3. 设置Animation Name

五.spine运行时核心概念(重点)

5.1 混合(重中之重)

Spine支持动画之间的混合, 混合主要有以下两方面的应用场合

  • A.多个动画同时播放,形成新的,较复杂的动画
  • B.动画之间的平滑过渡,而不是从一个姿势突然变成另一个姿势

其实这种需求是动画上的通用需求,Unity的Animator动画通过Transition(过渡),Layer(分层),blend tree(混合树)支持了混合在3D动画上的应用

5.2 通道(Track)

Track可分层应用动画,每个track存储了一个动画和播放参数。Track编号从零累加(track索引在内部是一个数组索引)。在将AnimationState应用到一个骨架后,track动画会从最低的track号开始依序应用。

Track有许多用途,例如,没有任何关键帧的动画可在高层track中运行,只覆盖有关键帧的低层track。例如,Track 0可以有行走、奔跑、游泳或其他动画,track 1可以有一个只为手臂和开枪设置了关键帧的射击动画。此外,为高层track设置TrackEntry alpha可使其与下面的轨道混合。例如,track 0可以有一个行走动画,track 1可以有一个跛行动画。当玩家受伤时,track 1的alpha值会增加,跛行会加重。

5.3 播放

在一个通道上播放动画通过调用setAnimation完成。将使用指定的动画取代该track中的当前动画和任何已排队的动画。如果在前一动画和当前动画之间定义了混合动画时间,则当前动画将在混合动画时间上混出,让动画过渡更流畅。

5.4 排队

要排队动画在将来播放,可调用addAnimation,安排该动画在此track当前动画或最后排队的动画后播放。如果此track空了,则等于调用setAnimation。

5.5 空动画

空动画是spine中比较常用和重要的概念,主要有以下两种应用情况

A.立刻停止轨道上的所有动画,调用setEmptyAnimation

B.当多个动画混合播放(比如动画a0在track0播放,动画a1在track1播放),当a1停止后需要过渡到只有a0播放的状态,调用addEmptyAnimation

Case1:a1播放完后什么都不做(track1未进入empty状态),则a0和a1会混合失败,动画整体或局部静止。

Case2:调用setEmptyAnimation让a1静止,则可能a1播放中途停止,动画表现比较突兀,不是想要的效果。

参考:应用动画

六.主要API

6.1 SetAnimation

​​​​​

setAnimation(int trackIndex, string animationName, bool loop)

setAnimation(int trackIndex, Animation animation, bool loop)

在轨道trackIndex立刻播放animationName这个动画,关于轨道的概念参考底部运行时术语

  • loop 若为true则循环播放动画. 若为false则不会循环播放, 
SkeletonAnimation skeletonAnimation = GetComponent<SkeletonAnimation>();
skeletonAnimation.AnimationState.SetAnimation(SpineBlinkPlayer.BlinkTrack, "blink", false);

6.2 AddAnimation

addAnimation(int TrackIndex, Animation animation, bool loop, float delay)

添加一个待播放动画, 在某轨道的当前或最后一个排队动画之后播放. 若该轨道为空, 则相当于调用setAnimation

SkeletonAnimation skeletonAnimation = GetComponent<SkeletonAnimation>();
skeletonAnimation.AnimationState.SetAnimation(0, "anim1", false);
skeletonAnimation.AnimationState.AddAnimation(0, "anim2", true, 0);

6.3 setEmptyAnimation

setEmptyAnimation (	int trackIndex, float mixDuration)

在轨道上设置一个空动画并移除队列中的全部动画, 同时设置轨道条目的mixDuration. 空动画没有时间轴, 它被当作淡入淡出的占位符.

6.4 addEmptyAnimation

addEmptyAnimation (	int trackIndex, float mixDuration, float delay)

添加一个空动画, 在某轨道的当前或最后一个排队动画之后播放, 同时设置该轨道条目的 mixDuration. 若该轨道为空, 则相当于调用 setEmptyAnimation

API参考文档

七.回调事件

7.1 不包括混合(mixing)/淡入淡出(crossfading)的事件

触发流程图

  • Start 当动画开始播放时触发,
    • 当调用SetAnimation时立刻触发.
    • 它也可以在一个队列中的动画开始播放时触发.
  • End 当动画从轨道中被移除(或中断)时触发,
    • 当当前动画快要播放完成时你调用SetAnimation中断了它, 该事件将被触发.
    • 当使用ClearTrack或者ClearTracks清除了轨道时, 该事件也会被触发.
    • 在混合(mix)/淡入淡出(crossfade)期间,在mix完成后End事件将被触发.
    • 当注册到AnimationState时, 永远不要End事件处理中调用SetAnimation, 它会引发无限递归. 请看下面的警告. 可以注册一个TrackEntry.End来替代.
    • 注意, 默认情况下, 非循环动画的TrackEntries不再在动画的持续时间内停止. 相反, 会继续无限期地保持最后一帧, 直到你移除它或用其他动画取代它. 如果你想让你的TrackEntry达到其动画持续时长(duration)时清空轨道, 请将TrackEntry.TrackEnd设置为动画持续时长.
  • Dispose 当AnimationState释放一个(在其生命周期结束时的)TrackEntry时, 会对TrackEntry触发.
    • 像spine-libgdx和spine-csharp这样的运行时会把TrackEntry对象缓存,以减小非必要的GC压力。这在Unity中尤为重要,因为Unity的GC实现有较为老旧低效.
    • 当TrackEntries被释放后,一定要记得移除对它们的所有引用,因为它们可能稍后就会被写入多余数据或触发意外事件.
    • Dispose事件会在End事件后立即触发.
  • Interrupt 当设置了新的动画且当前有一个动画还在播放时触发.
    • 当一个动画开始mixing/crossfading到另一个动画时触发.
  • Complete 当动画完成时触发,
    • 当一个非循环的动画播放完毕时触发,无论是否存在下一个在排队的动画.
    • 在循环动画每次循环结束后,也会触发.
  • Event 任何用户自定义事件被监听到时触发.
    • 这些事件点在Spine编辑器的动画中设置的。它们显示围为紫色的关键帧。在树状视图中也可以看到一个紫色的icon.
    • 为了区分不同的事件,你需要检查Spine.Event eName参数。(或者Data引用).
    • 当你想要按照动画节点去播放声音时它会非常有用,比如播放脚步声。它也可以根据Spine动画去同步或者通知非Spine系统,比如Unity的粒子系统或者产生单独的特效,甚至是诸如对齐发射子弹的时刻这样的游戏逻辑(如果你真的想这么做的话).
    • 每个TrackEntry都有一个EventThreshold属性. 它定义了在淡入淡出的哪些时间点上不触发用户事件.

在一个动画播放完成后,另一个队列中的动画即将开始播放的时候,事件触发的顺序为: CompleteEndStart

7.2 混合动画的事件

当你有设置了mix time(或者在你Skeleton Data Asset中设置了Default Mix),下一段动画开始播放且透明度逐渐增加,同时前一段动画依然在skeleton上生效, 这需要一小段时间.

我们把这段时间称为"淡入淡出"或"混合(mix)".

一个TrackEntry的EventThreshold控制在混合期间如何处理用户事件.

  • 默认值为0,当下一段动画开始播放时,立即停止触发用户事件.
  • 若置为0.5,就会在淡入淡出/混合过程到一半再停止触发用户事件.
  • 若置为1,将继续触发事件,直到淡入淡出/混合过程的最后一帧.

给动画设置合适的EventThreshold值是很重要的,因为你可能有交叠(overlapping)的相同动画,而它们不应该触发同一个事件,或者你希望即使动画已被中断但仍然触发其事件.

// Sample written for for Spine 3.7
using UnityEngine;
using Spine;
using Spine.Unity;

// Add this to the same GameObject as your SkeletonAnimation
public class MySpineEventHandler : MonoBehaviour {

   // The [SpineEvent] attribute makes the inspector for this MonoBehaviour
   // draw the field as a dropdown list of existing event names in your SkeletonData.
   [SpineEvent] public string footstepEventName = "footstep"; 

   void Start () {
      var skeletonAnimation = GetComponent<SkeletonAnimation>();
      if (skeletonAnimation == null) return;

      // This is how you subscribe via a declared method.
      // The method needs the correct signature.
      skeletonAnimation.AnimationState.Event += HandleEvent;

      skeletonAnimation.AnimationState.Start += delegate (TrackEntry trackEntry) {
         // You can also use an anonymous delegate.
         Debug.Log(string.Format("track {0} started a new animation.", trackEntry.TrackIndex));
      };

      skeletonAnimation.AnimationState.End += delegate {
         // ... or choose to ignore its parameters.
         Debug.Log("An animation ended!");
      };
   }

   void HandleEvent (TrackEntry trackEntry, Spine.Event e) {
      // Play some sound if the event named "footstep" fired.
      if (e.Data.Name == footstepEventName) {
         Debug.Log("Play a footstep sound!");
      }
   }
}

参考:Spine事件 & AnimationState回调函数

八.Spine运行时术语

Atlas 纹理集(atlas), 也被称为纹理图集(texture atlas), 是一个存储了一个纹理的命名区域. Spine可以打包纹理来新建一个图集, 也可以使用像Texture Packer Pro(大多数运行时使用的是 "libgdx "图集格式)这样的外部工具来创建图集.

Animation 动画(Animation)是一个存储了多条时间轴的列表. 每条时间轴都存储着许多关键帧, 每个关键帧都包含一个时间点以及一个/多个值. 当应用动画时, 时间轴使用这些关键帧来操作骨架(skeleton)、触发事件等. 动画不会存储任何状态.

AnimationState 动画状态(AnimationState)是一个方便的类, 它包含可用于骨架(skeleton)的一个或多个动画状态. 它有一个"轨道"的概念, 其索引号从零开始. 在每一帧中依次应用每条轨道中的动画, 且可以在动画轨道之上应用动画. 每个轨道都可以队列动画以便稍后播放. 当当前动画发生变化时, 动画状态还可以处理动画间的Mix(比如淡入淡出).

Attachment 附件(Attachment)放置在槽位中, 由此便附加于骨骼上. 它可以是一块texture区域也可以是边界框.

AttachmentLoader SkeletonJson使用附件加载器(AttachmentLoader)创建附件. 这个钩子函数用于注入自定义的附件实现, 例如实现惰性加载. 附件加载器最常见的用途是用于定制区域附件的图片源.

Bone 一个骨骼包含局部变换(SRT), 其子骨骼也会继承该变换. 一个骨骼也有世界变换, 它是所有父骨骼变换与局部变换的组合. 世界变换使用和根骨骼相同定义的坐标系.

Bounding box attachment 一个用于执行撞击检测、物理模拟等功能的多边形附件.

Draw order 绘制顺序(Draw order)是骨架(skeleton)上槽位的一个列表. 该列表的顺序表示从后到前绘制每个槽位中附件的顺序.

Mixing 混合(Mixing), 也被称为淡入淡出, 是通过在当前pose和动画pose间进行线性混合(blend)来使用动画的一种方式.

Region attachment 一个附件(attachment)包含一个纹理(texture)区域和一个偏移SRT, 这个偏移量用于对齐相对于附件的骨骼区域.

Slot 槽位(Slot)是骨骼上的一个占位符. 一个槽位既可包含一个附件也可不包含附件. 它也有自己的颜色且记录其附件切换后的保持时长.

Skeleton 骨架(Skeleton)保存着一个骨架的状态. 这包括当前pose、骨骼、槽位、绘制顺序等.

SkeletonBounds 骨架边界(SkeletonBounds)是一个方便的类, 它使用当前附加的边界框附件为骨架进行碰撞检测.

SkeletonData 骨架数据(SkeletonData)包含骨架信息(绑定pose的骨骼、槽位、绘制顺序、附件、皮肤等)和动画, 但不保存任何状态. 多个骨架可以共享同一个骨架数据

SkeletonJson 用于从JSON中加载SkeletonData.

SkeletonRenderer 骨架渲染器(SkeletonRenderer)在骨架的绘制顺序中重复遍历各插槽位, 并负责渲染各种附件.

Skin 皮肤(Skin)是一个映射(map), 其键(key)是槽位和名称, 值为附件. 皮肤是一个间接层, 它可以按槽位和名称来找到某个附件. 例如, 一个皮肤可能的键为[slot:head,name:head], 值为[attachment:redHead]. 另一个皮肤的同样的键值则为[attachment:greenHead]. 在动画中使用名称可使具有不同附件的骨架通过改变附件的方法复用动画.

SRT 缩放(Scale)、旋转(Rotation)和平移(Translation). 也被称为"变换(transform)".

Transform 缩放(Scale)、旋转(Rotation)和平移(Translation).

参考:

Spine概述

spine-unity 运行时文档

Spine运行时指南

Spine运行时文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/980661.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【计网】计算机网络概述

第一章 计算机网络概述 1.2 因特网概述1.2.1 网络、互联网和因特网1.2.2 因特网发展的三个阶段1.2.3 因特网的标准化工作1.2.4 因特网的组成 1.3 三种交换方式1.3.1 电路交换1.3.2 分组交换1.3.3 报文交换1.3.4 三种交换的对比 1.4 计网的定义与分类1.4.1 定义1.4.2 分类 1.5 计…

基于Linux系统的物联网智能终端

背景 产品研发和项目研发有什么区别&#xff1f;一个令人发指的问题&#xff0c;刚开始工作时项目开发居多&#xff0c;认为项目开发和产品开发区别不大&#xff0c;待后来随着自身能力的提升&#xff0c;逐步感到要开发一个好产品还是比较难的&#xff0c;我认为项目开发的目的…

[密码学实战]Java实现SM4加解密(ecb,cbc)及工具验证

前言 在现代信息安全领域,数据加密技术是保障数据安全的核心手段之一。SM4作为中国国家密码管理局发布的对称加密算法,因其高效性和安全性,广泛应用于金融、政务、通信等领域。本文将详细介绍如何使用Java实现SM4的加解密操作,并深入探讨SM4的几种常见加密模式及其原理。 …

StableDiffusion本地部署 3 整合包猜想

本地部署和整合包制作猜测 文章目录 本地部署和整合包制作猜测官方部署第一种第二种 StabilityMatrix下载整合包制作流程猜测 写了这么多python打包和本地部署的文章&#xff0c;目的是向做一个小整合包出来&#xff0c;不要求有图形界面&#xff0c;只是希望一键就能运行。 但…

‘ts-node‘ 不是内部或外部命令,也不是可运行的程序

新建一个test.ts文件 let message: string = Hello World; console.log(message);如果没有任何配置的前提下,会报错’ts-node’ 不是内部或外部命令,也不是可运行的程序。 此时需要安装一下ts-node。 npm install

(done) MIT6.S081 Interrupts Lecture 学习笔记

url: https://mit-public-courses-cn-translatio.gitbook.io/mit6-s081/lec09-interrupts/9.1-memory-in-real-os 9.1 真实操作系统内存使用情况 今天课程的内容是中断。但是在具体介绍中断之前&#xff0c;我想先回顾一下上周一些有趣的内容。因为上周的课程主要是讲内存&…

40岁开始学Java:Java中单例模式(Singleton Pattern),适用场景有哪些?

在Java中&#xff0c;单例模式&#xff08;Singleton Pattern&#xff09;用于确保一个类只有一个实例&#xff0c;并提供全局访问点。以下是详细的实现方式、适用场景及注意事项&#xff1a; 一、单例模式的实现方式 1. 饿汉式&#xff08;Eager Initialization&#xff09; …

【计算机网络基础】-------计算机网络概念

1.什么是计算机网络 定义&#xff1a; 图解&#xff1a; 2.最简单的计算机网络 其中&#xff1a; 结点可以是计算机、集线器、交换机、路由器等链路可以是有线链路、无线链路 2.1集线器 2.2交换机 3.互连网&#xff08;internet&#xff09;与 路由器 路由器 与 家用路由…

Qt 自带颜色属性

Qt 系统自带颜色如下&#xff1a; enum GlobalColor {color0,color1,black,white,darkGray,gray,lightGray,red,green,blue,cyan,magenta,yellow,darkRed,darkGreen,darkBlue,darkCyan,darkMagenta,darkYellow,transparent};对应颜色如下&#xff1a; color0: 这是自定义颜色…

数据结构(初阶)(七)----树和二叉树(前中后序遍历)

实现链式结构的二叉树 实现链式结构的二叉树遍历前序遍历中序遍历后序遍历 节点个数叶子节点个数⼆叉树第k层结点个数⼆叉树的深度/⾼度查找值为X的节点二叉树的销毁 层序遍历判断二叉树是否为完全二叉树 ⽤链表来表⽰⼀棵⼆叉树&#xff0c;即⽤链来指⽰元素的逻辑关系。 通常…

哔哩哔哩IT私塾python爬虫视频教程中的项目文件

视频链接&#xff1a; Python课程天花板,Python入门Python爬虫Python数据分析5天项目实操/Python基础.Python教程_哔哩哔哩_bilibili 视频教程中要访问的链接&#xff1a; 豆瓣电影 Top 250 httpbin.org seo推广公司网站模板_站长素材 Examples - Apache ECharts WordCloud…

实验:k8s+keepalived+nginx+iptables

1、创建两个nginx的pod&#xff0c;app都是nginx nginx1 nginx2 2、创建两个的pod的service 3、配置两台keepalived的调度器和nginx七层反向代理&#xff0c;VIP设置192.168.254.110 keepalived调度器master keepalived调度器backup 两台调度器都配置nginx七层反向代理&#…

【Cadence仿真学习笔记】ADS Dynamic Link报错model is reserved的解决办法

首先创建好原理图 创建symbol 在library manager下就会出现symbol了 在Cadence的CIW窗口中运行ADS dynamic link 打开ADS后&#xff0c;创建对应的cellview 加入控件OPTIONS 加入网表netlist 这个时候的Netlist没有路径 点击加载symbol 把原来的netlist include删掉…

【星云 Orbit • STM32F4】06. 串口密码:USART 数据传递

1. 引言 STM32F407是一款高性能的微控制器&#xff0c;具有丰富的外设和强大的处理能力。串口&#xff08;USART&#xff09;是STM32F407的重要外设之一&#xff0c;广泛应用于数据通信、调试和控制等领域。本教程旨在帮助小白从零开始&#xff0c;手动配置STM32F407的串口功能…

Win32 C++ 电源计划操作

CPowerCfgUtils.h #pragma once#include <Windows.h> #include <powrprof.h>// https://learn.microsoft.com/zh-cn/windows/win32/api/powrprof/?sourcerecommendations//节能 //DEFINE_GUID(GUID_MAX_POWER_SAVINGS, 0xA1841308, 0x3541, 0x4FAB, 0xBC, 0x81, …

MySQL—使用binlog日志恢复数据

一、binlog日志恢复数据简介 在 MySQL 中&#xff0c;使用二进制日志&#xff08;binlog&#xff09;恢复数据是一种常见的用于故障恢复或数据找回的方法。以下是详细的使用步骤&#xff1a; 确认 binlog 已启用&#xff1a;首先需要确认 MySQL 服务器已经启用了二进制日志功…

基于springboot+vue实现的宠物救助及领养平台(源码+L文+ppt)43-21

摘 要 宠物救助及领养平台是一个专注于宠物保护和幸福的在线平台。它致力于连接那些需要帮助的宠物与愿意给予它们关爱的家庭。通过这个平台&#xff0c;人们可以报告丢失的宠物、寻求救助资源&#xff0c;以及浏览可领养的宠物信息。该平台不仅提供了一个渠道&#xff0c;让…

人大金仓国产数据库与PostgreSQL

一、简介 在前面项目中&#xff0c;我们使用若依前后端分离整合人大金仓&#xff0c;在后续开发过程中&#xff0c;我们经常因为各种”不适配“问题&#xff0c;但可以感觉得到大部分问题&#xff0c;将人大金仓视为postgreSQL就能去解决大部分问题。据了解&#xff0c;Kingba…

【Java分布式】Nacos注册中心

Nacos注册中心 SpringCloudAlibaba 也推出了一个名为 Nacos 的注册中心&#xff0c;相比 Eureka 功能更加丰富&#xff0c;在国内受欢迎程度较高。 官网&#xff1a;https://nacos.io/zh-cn/ 集群 Nacos就将同一机房内的实例划分为一个集群&#xff0c;一个服务可以包含多个集…

派可数据BI接入DeepSeek,开启智能数据分析新纪元

派可数据BI产品完成接入DeepSeek&#xff0c;此次接入标志着派可数据BI在智能数据分析领域迈出了重要一步&#xff0c;将为用户带来更智能、更高效、更便捷的数据分析体验。 派可数据BI作为国内领先的商业智能解决方案提供商&#xff0c;一直致力于为用户提供高效、稳定易扩展…