• Bugs
  • Creating Spine SkeletonAnimation using c#

Related Discussions
...

I want to create a Spine SkeletonAnimation that uses C#script using Unity3D like this:

public void CreateCharacter()
{
    SkeletonAnimation playerAnim;
    SkeletonDataAsset playerData;
    AtlasAsset atlasdata;
    string name = "01_01_ani";

atlasdata = ScriptableObject.CreateInstance<AtlasAsset> ();
playerData = ScriptableObject.CreateInstance<SkeletonDataAsset> ();
atlasdata.atlasFile = (TextAsset)Resources.Load (name + ".atlas");
Material[] materials = new Material[1];
materials [0] = new Material (Shader.Find ("Transparent/Diffuse"));
Texture aa = (Texture)Resources.Load (name);
materials [0].mainTexture = aa;

atlasdata.materials = materials;

playerData.atlasAsset = atlasdata;
playerData.skeletonJSON = (TextAsset)Resources.Load (name + ".json");

GameObject player = new GameObject();
player.transform.localPosition = Vector3.zero;
player.transform.localScale = new Vector3 (1f, 1f, 1f);

playerAnim = (SkeletonAnimation)player.AddComponent ("SkeletonAnimation");
playerAnim.skeletonDataAsset = playerData;
playerAnim.calculateNormals = true;
playerAnim.AnimationName = "running";
playerAnim.loop = true;
}

But It brought on an error like this:

"Missing SkeletonData asset." "NullReferenceException: Object reference not set to an instance of an object" "ArgumentException: Getting control 1's position in a group with only 1 controls when doing Repaint Aborting"

I would like to find out what the problem with this such method and would like to know how to create a Spine Skeleton Animation using C#script from Unity3D? Is there any other way(other than the method I used)to create a Spine Skeleton Animation using C#script from Unity3D?

Thanks in advance.

public void CreateCharacter()
{
   SkeletonAnimation playerAnim;
   SkeletonDataAsset playerData;
   AtlasAsset atlasdata;
   string name = "Knight";

   atlasdata = ScriptableObject.CreateInstance<AtlasAsset> ();
   playerData = ScriptableObject.CreateInstance<SkeletonDataAsset> ();
   playerData.fromAnimation = new string[0];
   playerData.toAnimation = new string[0];
   playerData.duration = new float[0];
   playerData.scale = 0.01f;
   playerData.defaultMix = 0.15f;


   atlasdata.atlasFile = (TextAsset)Resources.Load (name + ".atlas", typeof(TextAsset));
   Material[] materials = new Material[1];
   materials [0] = new Material (Shader.Find ("Spine/Skeleton"));
   Texture aa = (Texture)Resources.Load (name, typeof(Texture2D));
   materials [0].mainTexture = aa;
   
atlasdata.materials = materials;
playerData.atlasAsset = atlasdata; playerData.skeletonJSON = (TextAsset)Resources.Load (name, typeof(TextAsset));
GameObject player = new GameObject(); player.transform.localPosition = Vector3.zero; player.transform.localScale = new Vector3 (1f, 1f, 1f);
playerAnim = (SkeletonAnimation)player.AddComponent ("SkeletonAnimation"); playerAnim.skeletonDataAsset = playerData; playerAnim.calculateNormals = true; playerAnim.loop = true; }

I've tweaked this a bit for you.

Most notably:

These must all be initialized (this is a flaw in the runtime, @Nate, I'll submit a pull request soon to fix) before the Skeleton JSON file is parsed or the SkeletonDataAsset.GetSkeleton function will take a poop.

playerData.fromAnimation = new string[0];
playerData.toAnimation = new string[0];
playerData.duration = new float[0];
atlasdata.atlasFile = (TextAsset)Resources.Load (name + ".atlas");
playerData.skeletonJSON = (TextAsset)Resources.Load (name + ".json");

This is where Unity gets obnoxious. the Atlas file is actually a .txt file with .atlas on the end so that line will work.
The Skeleton / Spine file is a .json file so it cannot be accessed by including the extension .json using Resources.Load.
Additionally, because of the same-name issue, Resources.Load(name) (without the json extension...) will return either the Texture or the JSON...
So you must specify the type of asset you wish to return using the overload of the Resources.Load function.

playerData.skeletonJSON = (TextAsset)Resources.Load (name, typeof(TextAsset));

Finally, the SkeletonAnimation.AnimationName property cannot be used until after SkeletonAnimation has initialized its AnimationState, which is best accomplished by waiting a frame for it to call its own Reset function and get your stuff setup.

playerAnim.AnimationName = "running";

Don't do this until after a frame has passed after creating your game object.

Related topic (plain Unity case instead of TK2D):
viewtopic.php?f=7&t=2670

The conclusion last time was that this should theoretically work (and it kinda does work) but the runtime does some things that prevent it from doing so cleanly.

1 个月 后

One thing to keep in mind: If your atlas export from Spine created more than one png files, you have to create a material for each of those images.