当前位置:   article > 正文

spine介绍和在Unity里面的应用_unity spine

unity spine

目录
介绍Spine.
Spine 是一款针对游戏开发的 2D 骨骼动画编辑工具。 Spine 旨在提供更高效和简洁 的工作流程,以创建游戏所需的动画。
最小的体积: 传统的动画需要提供每一帧图片。而 Spine 动画只保存骨骼的动画数据,它所占用的空间非常小,并能为你的游戏提供独一无二的动画。
美术需求: Spine 动画需要的美术资源更少,能为您节省出更多的人力物力更好的投入到游戏开发中去。
流畅性: Spine 动画使用差值算法计算中间帧,这能让你的动画总是保持流畅的效果。
装备附件: 图片绑定在骨骼上来实现动画。如果你需要可以方便的更换角色的装备满足不同的需求。甚至改变角色的样貌来达到动画重用的效果。
混合: 动画之间可以进行混合。比如一个角色可以开枪射击,同时也可以走、跑、跳或者游泳。
程序动画: 可以通过代码控制骨骼,比如可以实现跟随鼠标的射击,注视敌人, 或者上坡时的身体前倾等效果。

Spine导出的资源是什么,有哪些?
.json文件,它包含所有骨架信息。
.png文件,它包含当前版本所有图片的集合。
.atlas.txt文件,它包含打包的图集信息。
注意事项:将.atlas设置为.atlas.txt。如果不这么做可能会出现一些问题,因为Unity默认不会识别以.atlas后缀的文件,虽然Spine-Unity可以识别这个文件。不管怎么样,设置为.atlas.txt将避免大部分的问题

Spine再Unity里面是如何展现的。
Spine使用Unity的MeshRenderer和MeshFilter组件,还有材质资源进行渲染展现的。
这里写图片描述

每一个Spine动画对象都要手动绑定一个SkeletonAnimation脚本,每一个SkeletonAnimation又需要手段绑定一个SkeletonDataAsset资源文件,SkeletonDataAsset又需要手动绑定json文件和.asset资源文件。这样结合到一起SkeletonAnimation脚本才会有它的所有行为和数据。
这里写图片描述

Unity中如何播放Spine的动画,已及操作。
1.播放动画和简单的动态修改属性
//初始化SkeletonAnimation 组件
SkeletonAnimation skeletonAnimation;
//更改动画播放速度
skeletonAnimation.timeScale = 1.5f;
//是否循环
skeletonAnimation.loop = true;
//播放哪一个动画
skeletonAnimation.AnimationName = “run”;
2.左右方向动画
在Spine编辑器中不用设置动画的朝向,SkeletonAnimation的Skeleton对象有FlipX和FlipY属性,你可以根据需要设置骨骼的水平镜像(就是左右方向)。
// 如果你的角色已经是面向右边的,那么把FlipX设置为true,就是左边,相反就是右边。
skeletonAnimation.skeleton.FlipX = true;
注意:如果你的角色在设计时两边朝向的动画不一样。可以使用Spine的皮肤功能。一个皮肤表示向左,一个皮肤表示向右。
bool facingLeft = (facing != “right”);
skeletonAnimation.skeleton.FlipX = facingLeft;
skeletonAnimation.skeleton.SetSkin(facingLeft ?”leftSkin” : “rightSkin”);
3.复杂的动画系统
控制骨架的主要类是Spine.AnimationState。 SkeletonAnimation是基于AnimationState构建的,它的SkeletonAnimation.state引用就是Spine.AnimationState。它会在Awake中初始化,所以应该在Start或之后访问它。
AnimationState是Spine动画状态机的基础实现。
.// 在Trank0中播放“stand”动画。
skeletonAnimation.state.SetAnimation(0, “stand”, false);

// 在Track0中添加一个“run”动画,当Track0的最后一个动画播放结束后循环播放“run”动画。
skeletonAnimation.state.AddAnimation(0, “run”, true, 0f);
(通道)Track是把动画分层,让角色在同一时间可以播放几个Spine动画。// 跑步动画运行在Track 0,而射击动画运行在Track 1
skeletonAnimation.state.SetAnimation(0, “run”, true);
skeletonAnimation.state.SetAnimation(1, “shoot”, false);

你可以从任意时间节点(帧)开始播放动画。你可以在SetAnimation之后设置.Time的值,让动画从指定的帧数开始播放。但是要注意.Time的单位是秒。因为Spine
的摄影表每秒30帧,所以你需要把帧转换为秒,公式是 ime = (帧数/30f)

//第一种方式 从第10帧开始播放”dance”动画
var trackEntry = skeletonAnimation.state.SetAnimation(0, “dance”, false);
trackEntry.Time = 10f/30f;

// 第二种方式 你可以像这样更方便得设置Time,而不需要使用另一个变量去储存TrackEntry
skeletonAnimation.state.SetAnimation(0, "dance", false).Time = 10f/30f;
  • 1
  • 2

Unity中如何更换皮肤。

从SkeletonAnimation中获取Skeleton骨架类。骨架类包括所有的骨骼(Bone),插槽(Slot)等信息。
1.整套更换。
Skeleton提供了一个API,可以直接更换整套皮肤。该用该API的时候首先要确认json资源文件里面存不存在该皮肤,并且还要对应皮肤的名字,如果存在调用该API是可以成功更换的,如果不存在则更好失败,并且会报错“没找到该名字的皮肤”。
Skeleton.SetSkin(“皮肤名字”);
2.更好局部皮肤。
更换局部皮肤,首先要知道更换的是那个插槽,它下的附着物(图片),和新附着物(图片)。
废话不多说直接上代码。
我整理了一个SpineTool类,该类目前只做更换皮肤的功能。
目前更好局部皮肤整理了2中方法。
///
/// 动态局部换装。直接用精灵图片
///
/// 需要换装的skeleton
/// 需要换装的skin
/// 需要更换的新图片
/// 需要换装的附着物名字(图片名字)
/// 需要换装的插槽名字(节点名字)
public void DressUp(Skeleton skeleton, Skin skin, Sprite sprite, string slotName, string attachmentName)
{
RegionAttachment newHand = atlasAsset.GetAtlas().FindRegion(spriteName).ToRegionAttachment(“new hand”);
newHand.SetPositionOffset(Vector3.zero);
newHand.Rotation = 0;
newHand.UpdateOffset();
int handSlotIndex = skeleton.FindSlotIndex(slotName);
skin.AddAttachment(handSlotIndex, attachmentName, newHand);

    skeleton.SetSkin(skin);
    skeleton.SetToSetupPose();

    Resources.UnloadUnusedAssets();
}
  • 1
  • 2
  • 3
  • 4
  • 5

///
/// 动态局部换装。取图集里面的图片。
///
/// 需要换装的skeleton
/// 需要换装的skin
/// 换那一个图集里面的图片
/// 图集里面图片的名字
/// 需要换装的附着物名字(图片名字)
/// 需要换装的插槽名字(节点名字)
public void DressUp(Skeleton skeleton, Skin skin, AtlasAsset atlasAsset, string spriteName, string attachmentName, string slotName)
{
RegionAttachment newHand = atlasAsset.GetAtlas().FindRegion(spriteName).ToRegionAttachment(“new hand”);
newHand.SetPositionOffset(Vector3.zero);
newHand.Rotation = 0;
newHand.UpdateOffset();
int handSlotIndex = skeleton.FindSlotIndex(slotName);
skin.AddAttachment(handSlotIndex, attachmentName, newHand);

    skeleton.SetSkin(skin);
    skeleton.SetToSetupPose();

    Resources.UnloadUnusedAssets();
}
  • 1
  • 2
  • 3
  • 4
  • 5

Unity中如何把Spine与ParticleSystem结合使用。
比如我播放一个Spine的动画同时需要播放一个天马星空的特效,这个特效的节点必须要是Spine骨骼的节点,因为在游戏过程中Spine对象有可能是玩家或者怪物,他们是在移动的,如果你不绑定骨骼节点,你播放的特效节点100%对不上,让玩家看来这就是一个BUG。
因为Spine对象类似于一个单体,Hierarchy面板下面看不到任何节点,这时候怎么办呢。老规矩,把需要显示特效的节点自定义创建出来。官方网站资料并没有讲到这一点,但是官方的Demo很良心,我在他的Demo里面发现了有BoneFollower骨骼跟随这个类。好了继续我们的操作。在每一个节点上绑定BoneFollower这个类,然后把SkeletonAnimation赋值给BoneFollower的变量SkeletonRenderer。这时BoneFollower就自动拥有了该Spine所有骨骼节点名字。在我们自定义的节点上对应的修改选择BoneFollower骨骼节点名字即可。在游戏过程中想在那个节点上显示什么特性,直接加载播放即可。

更换局部皮肤和整体皮肤源码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Spine.Unity.Modules.AttachmentTools;
using Spine;
using Spine.Unity;


public class SpineTool
{

    private static SpineTool instance = null;

    public static SpineTool Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new SpineTool();
            }
            return instance;
        }
    }

    /// <summary>
    /// 动态局部换装。直接用精灵图片
    /// </summary>
    /// <param name="skeleton">需要换装的skeleton</param>
    /// <param name="skin">需要换装的skin</param>
    /// <param name="sprite">需要更换的新图片</param>
    /// <param name="slotName">需要换装的附着物名字(图片名字)</param>
    /// <param name="attachmentName">需要换装的插槽名字(节点名字)</param>
    public void DressUp(Skeleton skeleton, Skin skin, Sprite sprite, string slotName, string attachmentName)
    {
        RegionAttachment newWeapon = sprite.ToRegionAttachmentPMAClone(Shader.Find("Spine/Skeleton"));
        newWeapon.SetScale(1.5f, 1.5f);
        newWeapon.UpdateOffset();
        int weaponSlotIndex = skeleton.FindSlotIndex(slotName);
        skin.AddAttachment(weaponSlotIndex, attachmentName, newWeapon);

        skeleton.SetSkin(skin);
        skeleton.SetToSetupPose();

        Resources.UnloadUnusedAssets();
    }

    /// <summary>
    /// 动态局部换装。取图集里面的图片。
    /// </summary>
    /// <param name="skeleton">需要换装的skeleton</param>
    /// <param name="skin">需要换装的skin</param>
    /// <param name="atlasAsset">换那一个图集里面的图片</param>
    /// <param name="spriteName">图集里面图片的名字</param>
    /// <param name="attachmentName">需要换装的附着物名字(图片名字)</param>
    /// <param name="slotName">需要换装的插槽名字(节点名字)</param>
    public void DressUp(Skeleton skeleton, Skin skin, AtlasAsset atlasAsset, string spriteName, string attachmentName, string slotName)
    {
        RegionAttachment newHand = atlasAsset.GetAtlas().FindRegion(spriteName).ToRegionAttachment("new hand");
        newHand.SetPositionOffset(Vector3.zero);
        newHand.Rotation = 0;
        newHand.UpdateOffset();
        int handSlotIndex = skeleton.FindSlotIndex(slotName);
        skin.AddAttachment(handSlotIndex, attachmentName, newHand);

        skeleton.SetSkin(skin);
        skeleton.SetToSetupPose();

        Resources.UnloadUnusedAssets();
    }

    /// <summary>`这里写代码片`
    /// 更换套装
    /// </summary>
    /// <param name="skeleton"></param>
    /// <param name="skinName">套装的名字</param>
    public void DressUp(Skeleton skeleton,string skinName)
    {
        skeleton.SetSkin(skinName);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/118479
推荐阅读
相关标签
  

闽ICP备14008679号