Dragonbones是一套由Egret团队制作的独立的骨骼动画编辑器,用来编辑骨骼动画可以运用到游戏中,这里简单介绍一下在unity中怎么使用dragonBones骨骼动画。
关于Dragonbones软件的动画制作学习,可以参考官网的学习网页,链接DragonBones学习,这里面有视频教学也有文档教学,很全面。
下载运行库(C#)
- 在GitHub中下载https://github.com/DragonBones,找到下图的文件,下载压缩包。
下载后找到下图中的DragonBones文件夹,拖到unity工程里即可
- DragonBones官方提供一个UnityPackage包DragonBonesUnityPackage,找到下图中文件下载,并把下载好的unityPackage包导入到unity工程里
导入的包里有很多教学场景,可以用来学习,但是一般在真正项目里这些都会删掉
DragonBones动画在unity里的使用
首先先在dragonbones里导出动画
这里我们数据类型选择json格式,版本使用5.5,涵盖的功能更全面一点。导出的纹理的类型这里选择纹理集,另一种格式是碎图
可以看到导出的有三个文件
XXXXX_ske.json //骨骼数据文件
XXXXX_tex.json //纹理集配置文件
XXXXX_tex.png //纹理集
我们在unity里新建一个场景用来测试加载动画,新建Resources文件夹,将刚刚导出的三个文件复制到Resources文件夹里
编辑器手动创建
在unity选中Dragon_ske.json文件(注意是_ske.json文件),右键Create->DragonBones->ArmatureObject,即可创建出动画物体,同时会自动生成一个UnityDragonBonesData文件和Dragon_tex_Mat文件
下图是控制动画的组件, 可以看到椭圆的地方就是刚刚自动生成的UnityDragonBonesData文件,矩形地方可以切换不同的动画,当然还可以设置层级播放次数等。
代码创建,每个项目只包含单个动画文件时
接下来使用代码创建测试一遍,当前是一个DragonBones项目里只有一个动画文件时,直接使用文件路径创建,先直接贴代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DragonBones;
public class DragonBonesManager : MonoBehaviour
{
//创建动画实例之前,需要先把动画的三个文件加载缓存起来
//这里使用一个字典,记录一下哪些动画的数据已经加载过了,格式为 <骨架数据json文件路径,(动画的骨架名称ArmatureName,动画缓存实例名称)>
Dictionary<string, List<string>> datas = new Dictionary<string, List<string>>();
//记录的已缓存数据,<SkeJsonPath,(ArmatureName,CacheName)>
//SkeJsonPath是动画骨骼数据json文件的路径,在这里作为字典的key值
//ArmatureName是骨架名称,这个是在DragonBones软件里设置的,参考代码结束下的图
//CacheName就是我们指定的骨架和纹理集缓存实例名称,指定缓存实例名称的目的是防止在多个项目里存在相同骨架名称的动画文件时,创建动画实例出错
/// <summary>
/// 用来加载缓存动画数据
/// </summary>
/// <param name="skeJsonPath">动画骨架数据json路径</param>
/// <param name="texJsonPath">动画纹理集数据json路径</param>
/// <returns>龙骨数据</returns>
DragonBonesData InitLoadDragonBonesData(string skeJsonPath, string texJsonPath)
{
//LoadDragonBonesData(string dragonBonesJSONPath, string name = "", float scale = 0.01f)
//第二个参数name是 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)
//在这可以不设置,他就会默认使用创建出的龙骨数据的名字
DragonBonesData data = UnityFactory.factory.LoadDragonBonesData(skeJsonPath);//加载骨架数据
if (data == null)//如果骨架数据加载失败,直接返回Null
{
return null;
}
//这里是一样的,在这里我们指定图片的缓存实例为刚刚创建出来的龙骨数据的名字
UnityFactory.factory.LoadTextureAtlasData(texJsonPath, data.name);//加载图片数据
return data;
}
/// <summary>
/// 创建动画
/// </summary>
/// <param name="skeJsonPath">动画骨架数据json路径</param>
/// <param name="texJsonPath">动画纹理集数据json路径</param>
/// <returns>动画组件</returns>
UnityArmatureComponent CreateAnimationObject(string skeJsonPath, string texJsonPath)
{
List<string> armatureAndName = null;
datas.TryGetValue(skeJsonPath, out armatureAndName);//先在已缓存数据里查找当前要创建的动画是否已加载缓存,如果已缓存则直接创建
if (armatureAndName == null || armatureAndName.Count < 2)
{
var data = InitLoadDragonBonesData(skeJsonPath, texJsonPath);//没有加载缓存,则执行缓存操作
if (data == null)
{
return null;//缓存失败,直接返回
}
List<string> dragon = new List<string>();//缓存成功,则把skeJsonPath,骨架名称data.stage.name,缓存实例名称data.name保存起来
dragon.Add(data.stage.name);
dragon.Add(data.name);
datas.Add(skeJsonPath, dragon);//保存
armatureAndName = dragon;//赋值,下面可以执行创建
}
UnityArmatureComponent com = UnityFactory.factory.BuildArmatureComponent(armatureAndName[0], armatureAndName[1]);//根据骨架数据名称和骨架缓存实例名称来创建动画
return com;
}
private void Start()
{
//根据ske.json文件和tex.json文件创建,这种情况下一般一个DragonBones项目里只有一个动画
var dragonbones = CreateAnimationObject("Dragon_ske.json", "Dragon_tex.json");
if (dragonbones != null)
{
dragonbones.animation.Play("walk");//播放动画
}
}
}
项目里动画文件的骨架名称ArmatureName:
代码创建,单个项目里包含多个动画文件时
当一个DragonBones项目里只有一个动画文件时,有多少个动画就需要导出多少个纹理集,当动画很多时,导出的纹理集空间占用太大,就会让包体变大。如果有的项目需要追求包体大小时,这时候可能就要选择在一个DragonBones项目里放入多个动画文件,这样多个动画文件的资源只会导出一个纹理集,空间利用率就会变大,也会缩小包体的大小。
下面测试一下当一个项目里有多个动画文件时,怎么创建每个动画文件
先在DragonBones里新建一个项目,导入两个动画文件,如下图,一个龙动画,一个羊动画
导出面板:会发现龙和羊的图片资源都在一个纹理集里了,将导出的三个文件复制到unity Resources文件夹里
简单改写下代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DragonBones;
public class DragonBonesManager : MonoBehaviour
{
/// <summary>
/// 用来加载缓存动画数据
/// </summary>
/// <param name="skeJsonPath">动画骨架数据json路径</param>
/// <param name="texJsonPath">动画纹理集数据json路径</param>
/// <returns>龙骨数据</returns>
DragonBonesData InitLoadDragonBonesData(string skeJsonPath, string texJsonPath)
{
//LoadDragonBonesData(string dragonBonesJSONPath, string name = "", float scale = 0.01f)
//第二个参数name是 为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)
//在这可以不设置,他就会默认使用创建出的龙骨数据的名字
DragonBonesData data = UnityFactory.factory.LoadDragonBonesData(skeJsonPath);//加载骨架数据
if (data == null)//如果骨架数据加载失败,直接返回Null
{
return null;
}
//这里是一样的,在这里我们指定图片的缓存实例为刚刚创建出来的龙骨数据的名字
UnityFactory.factory.LoadTextureAtlasData(texJsonPath, data.name);//加载图片数据
return data;
}
//根据骨架名称armatureName创建
UnityArmatureComponent CreateAnimationObject(string armatureName)
{
UnityArmatureComponent com = UnityFactory.factory.BuildArmatureComponent(armatureName);
return com;
}
private void Start()
{
//直接提前加载骨骼文件
InitLoadDragonBonesData("MultipleTest_ske.json", "MultipleTest_tex.json");
//根据骨架名称armatureName创建
var dragonbones = CreateAnimationObject("Dragon");//创建龙的动画
if (dragonbones != null)
{
dragonbones.animation.Play("walk");//播放动画
dragonbones.gameObject.transform.localPosition = new Vector3(-3f, 0f, 0f);
}
var sheep = CreateAnimationObject("Sheep");//创建羊的动画
if (sheep != null)
{
sheep.animation.Play("goat_walk_anim");//播放动画
sheep.gameObject.transform.localPosition = new Vector3(3f, 0f, 0f);
}
}
}
运行效果如下:
这里只介绍了创建动画,缓存动画数据,记录已缓存数据基本用法,一般都会根据项目需求再扩展,具体的一些创建完之后的动画切换,控制播放,换装,添加监听事件等等操作,在导入的教学场景里都有示例,具体的可以去看他的示例场景和代码。