unity 在代码中创建spine动画组件

项目中用到了spine动画,使用Assetbundle打包后,在手机上运行会出现丢材质的情况。如果不进行打包,直接放到Resources目录下是可以正常加载的,但是,这样包就会很大,而且也不能进行热更新。进过测试,发现在代码中创建spine组件是可以解决这个问题,于是就有了下面的方案。

我们先说方案,再说问题。

方案:

spine动画制作人员提供的spine动画三个文件分别是.json,.atlas,.png,把这三个文件放到unity(我用的unity版本是5.3.4f1)中,会自动生成atlas.asset,.mat,skeletondata.asset三个文件,我们只使用.mat文件,因为mat文件上已经关联了.png文件,所以我们实际要打包的文件是三个源文件.json,.atlas,.png和.mat文件,而.png文件实际上是作为.mat的依赖打包的,下面在代码中创建spine组件如下:

GameObject addSpineComponent(UnityEngine.Object obj)

{

GameObject go = GameObject.Instantiate(obj) as GameObject;

go.name = obj.name;

GameObject.DontDestroyOnLoad(go);

SkeletonAnimation sa;

SkeletonDataAsset sda;

sda = ScriptableObject.CreateInstance<SkeletonDataAsset>();

sda.fromAnimation = new string[0];

sda.toAnimation = new string[0];

sda.duration = new float[0];

sda.scale = 0.01f;

sda.defaultMix = 0.15f;

//SpineNameInfo中存着.json,.atlas,.mat的名称

SpineNameInfo sni = dicMonsterSpineInfos[go.name];

AtlasAsset[] arrAtlasData = new AtlasAsset[sni.AtlasFileNames.Length];

for (int i = 0; i < arrAtlasData.Length; i++)

{

string atlasFileName = sni.AtlasFileNames[i];

AtlasAsset atlasdata = ScriptableObject.CreateInstance<AtlasAsset>();

atlasdata.atlasFile = GetObj(atlasFileName) as TextAsset;

string[] mNames = sni.GetMaterialNames(atlasFileName);

atlasdata.materials = new Material[mNames.Length];

for (int j = 0; j < mNames.Length; j++)

{

//Material m  = dicPreloadAssets[mNames[j]] as Material;

atlasdata.materials[j] = GetObj(mNames[j]) as Material;

}

//atlasdata.materials = mats;

atlasdata.Reset();

arrAtlasData[i] = atlasdata;

}

sda.atlasAssets = arrAtlasData;

sda.skeletonJSON = GetObj(sni.JsonFileName) as TextAsset;

sa = go.AddComponent<SkeletonAnimation>();

sa.skeletonDataAsset = sda;

sa.calculateNormals = true;

sa.skeletonDataAsset.Reset();

sa.AnimationName = "run";

sa.loop = true;

sa.Initialize(false);

return go;

}

public class SpineNameInfo

{

private Dictionary<string, string[]> dicAtlasFileNames = new Dictionary<string, string[]>();

//.json文件名

public string JsonFileName = string.Empty;

//.atlas文件名,可能有多个.atlas文件(虽然我的项目中只有一个)

public string[] AtlasFileNames

{

get

{

string[] s = new string[dicAtlasFileNames.Count];

dicAtlasFileNames.Keys.CopyTo(s, 0);

return s;

}

}

//.mat文件名,可能有多个mat文件

public string[] GetMaterialNames(string atlasFileName)

{

if (dicAtlasFileNames.ContainsKey(atlasFileName))

return dicAtlasFileNames[atlasFileName];

return new string[0];

}

public void Add(string atlasFileName, string[] m)

{

if (!dicAtlasFileNames.ContainsKey(atlasFileName))

dicAtlasFileNames.Add(atlasFileName, m);

}

}

//这里是我项目中用到的对象池,根据资源名,获取资源对象

public UnityEngine.Object GetObj(string name)

{

if (pool.ContainsKey(name))

return pool[name];

return null;

}

可能您会注意到,怎么没有.png文件呢,我刚才在上面也提到,png文件会作为mat文件的依赖打包进assetbundle,所以在加载mat文件的时候png自然也已经被加载好了。

以上是我的解决方案。可能有点乱,如果有什么不明白的,我再提供两个链接,也是网上的一些解决方案。

http://answers.unity3d.com/questions/710571/spine-creating-spine-skeletonanimation-using-cscri.html

http://zh.esotericsoftware.com/forum/Creating-Spine-SkeletonAnimation-using-c-3091

下面说一下问题:

使用上述方案以后,发现一个问题,就是创建spine动画很耗时。因为有大量的怪物要创建,这样就导致原先的场景预加载时间很长,长到不能接受。好在虽然怪物数量庞大,但种类不是很多,复用也很高,所以就把spine动画的创建和预加载放到了游戏数据初始化中,时间虽然会有点长,但因为游戏刚开始初始化的东西不多,就还能接受,后面再加载场景怪物的时候,直接获取预加载的种类的对象,然后实例化就OK了。

到此,问题解决。

时间: 2024-10-08 10:08:15

unity 在代码中创建spine动画组件的相关文章

Unity 4.0 中的新动画系统——MecAnim

分享一个文档资料,关于动画系统的,版本应该很老了,但是有借鉴意义的: Unity 4.0 已于 2012 年 11 月 15 日正式发布,Unity 每一次版本的提升,都给游戏开发者带来惊喜,这一次也不例外,该版本最大变化之一就是引入了新动画系统--MecAnim,通过 MecAnim 新的动画系统,开发者在 Unity 中可以非常方便地实现角色动画.所以 Unity 4.0 的启动画面都突出了新的动画系统这一最新功能  . 这里需要说明的是,在 Unity 4.0 中,开发者还是可以使用原有的

WPF在代码中创建DataTemplate时候的异常

今天写段程序用到了在代码中手动创建DataTemplate, var factory = new FrameworkElementFactory(typeof(OperationColumn));    returnnewDataTemplate() { VisualTree = factory }; 运行的时候出现如下异常: FrameworkElementFactory 必须位于此操作的密封模板中. 在 System.Windows.FrameworkElementFactory.Insta

本地C代码中创建Java对象

创建Java域的对象就是创建Java类的实例,再调用Java类的构造方法. 以Bitmap的构建为例,Bitmap中并没有Java对象创建的代码及外部能访问的构造方法,所以它的实例化必然是在JNI的c中实现的. BitmapFactory.java中提供了得到Bitmap的方法,时序简化为: BitmapFactory.java ->BitmapFactory.cpp -> GraphicsJNI::createBitmap()  [graphics.cpp] GraphicsJNI::cre

Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵

我们现在准备好在代码中添加透视投影了.Android的Matrix类为它准备了两个方法------frustumM()和perspectiveM().不幸的是,frustumM()的个缺陷,它会影响某些类型的投影,而perspectiveM()只是从Android的ICS版本开始才被引入,在早期的Android版本里并没有这个方法.我们可以简单地支持ICS及其以上的版本,但是这样会丢掉很大一部分市场,一些用户依然运行早期的Android版本. 作为替代,我们可以创建我们自己的方法来实现投影矩阵.

代码中创建新终端 以及的把新终端的输出打印到文件,用于调式。

转自:http://blog.chinaunix.net/uid-20682147-id-4981769.html cat term.c #include<stdio.h> #include<stdbool.h> #include<stdlib.h> #include<string.h> #include<sys/prctl.h> #include<unistd.h> #include<utmp.h> #include&l

在代码中创建布局的方法

第一种imageView = new ImageView(this);FrameLayout decorView = (FrameLayout) getWindow().getDecorView();decorView.addView(imageView);FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams();layoutParams.width = DubDi

Spine动画在Cocos2d-x中,多动画切换播放出现残影的解决方法

最近在做的一个项目,NPC的动画是用Spine来做的.游戏中随着不同的状态变化,会导致NPC在"待机"."准备进攻"."进攻"."眩晕"."死亡"等等多种状态之间来回切换,NPC每切换一种状态,随之就要立刻播放该状态对应的动画. 游戏中播放spine动画是用SkeletonAnimation对象调用setAnimation方法,我遇到的问题是,在多种动画这样切换播放时,有的动画被切换后仍有残影存留,直到再一

动态修改spine动画渲染层次

在unity中做2D游戏开发的时候我们使用sprite比较多,sprite的层次修改我们手动修改sprite renderer下面的Order in Layer属性就行了.也可以动态的获取它的层次属性进行修改,那么怎么动态修改spine动画的层次呢,如下:   我们创建spine动画的时候,在这个物体上会有一个Mesh Renderer的组件.我们通过他来改变Skeleton Animation中的Order in Layer的值.--------------------- void Start

使用lua实现Spine动画的预加载

创建spine动画有两种方法,分别是createwithfile和createwithdata. createWithFile是通过加载动作数据马上进行创建,如果spine动画中的json文件大小超过100k时,会出现卡顿现象,如果动画文件偏小,可以使用这个方法来创建动画. createWithData是通过预加载,保存动画数据在spSkeletonData中,然后通过实现创建动画,这个方法可以使用在spine动画偏大的情况下使用. cocos2dx 自带的LuaSkeletonAnimatio