Jamie

Hi guys,

I'm not sure if my brain has just stopped working but I'm hoping someone can help me. I have a feeling I've solved this myself before, but I can't for the life of me figure out how to do it right now.

So, in Unity, I have a Mecanim Animator Controller containing the basic character animations created in Spine - for example, idle, walk, run - and the transitions to and from each state. But I have now added additional animations in Spine - such as crouch and jump - and re-exported it from Spine. However, I can't figure out how to add the new animations to the existing controller without messing up the existing states and transitions. If I bake a new controller, that works fine, but I'd need to recreate all of the transitions and conditions. Rather than start over with a new controller everytime I create a new animation, I just want to add the new animation to the existing controller.

Seems like such an obvious thing, so I'm sure I'm just having brain issues.

tl;dr - How do I add newly-created Spine animations to an existing Mecanim Animator Controller?

Thanks
Jamie
  • Beiträge: 8

clandestine

I'm not set up to check this right now, but I believe you just need to look at the Controller asset in Project view. It should have a list of clips underneath it that you can drag into the Animator view to assign / create states, and it should automatically update to match new animations, I think.
Benutzeravatar
clandestine
  • Beiträge: 48

Jamie

Hi, clandestine.

Thanks for the reply, but no, it doesn't appear to behave like this. When I re-export from Spine with new animations and then go back to Unity, the relevant Controller isn't automatically updated, regardless of whether it's in the default "Baked" folder or has been moved elsewhere in the project. It seems the only way to get the new anim to appear is to re-bake it, but of course that creates a brand new Controller that doesn't contain any Mecanim transistions, variables or triggers that have already been created - it just lists each of the states in their default, err, state.

Thanks again for the reply, though.
Jamie
  • Beiträge: 8

blinz117

Hi Jamie,

I'm not sure how things work with baked objects, but with the built-in integration with Mecanim, you can simply drag the animations from the project view into the animator window (where all of your existing states/transitions live). I'm not sure if it that is exactly the answer you are looking for, but I think the Mecanim Animator system is generally set up for drag and drop creation of states.

Hope that helps.
Benutzeravatar
blinz117
  • Beiträge: 5

Jamie

Hi blinz,

Yeah, that's what I'm hoping to be able to do, and indeed that was exactly what I did when setting up the original Controller. The problem is is that the new animations don't show up in the project window for the original Controller automatically. Only when I use the bake system does it create a new Controller file with all of the new and existing animations shown as children of it in the project window. The original Controller component just retains the original animations as children.

I think I can technically re-bake it to create a new controller (which has none of the previously set up Mecanim functionality but does have all of the animations), and then drag the new animations from the new Controller file onto the Animator window for the original Controller, but this seems like a recipe for confusion to me. Even when I do this, it still doesn't show the new animations as children of the original Controller file in the project window, even though it is shown in the Animator window... (Yep, I've just tested this and can confirm that's true).

So, I can get it to work in a bit of a hacky way, but it seems counter-intuitive to have to do the followings steps:

1) Export from Spine
2) Re-bake animations
3) Find newly-created Controller
4) Drag new animations one-by-one from there to original Controller Animator window (which does not visually update the children of the original Controller)
5) Edit Animator transitions

I just assumed it would make more sense if it went:

1) Export from Spine
2) New animations shown automatically
3) Add new animations to Controller Animator window in any of the usual ways
4) Edit Animator transitions

Perhaps I'm just missing something about the way that is has to work.

And I realise this is probably quite a difficult problem to visualise without being able to see exactly when I mean - it's definitely a tricky one to try to describe! :)
Jamie
  • Beiträge: 8

blinz117

Is there a reason you need to bake your Spine objects? If you need/want to use Mecanim, I know that if you use the Mecanim integration built into the runtime, then it works like I described (animation updates/additions show up in the same controller and can be dragged into the animator window). All you have to do is instantiate a Mecanim instance rather than a SkeletonAnimation instance at the start. I realize you would still probably have to redo your state machine if you did this, but at least it would be more robust if you needed to add animations later on.
Benutzeravatar
blinz117
  • Beiträge: 5

Jamie

To be honest, as a relative novice with Unity, I'm not really sure on the difference between baking and not baking. And when I say "I'm not really sure", I mean I have no idea what it means! :) That's something I plan to research a little later in my learning process.

But, if I right-click the SkeletonData and Instantiate Mecanim, that doesn't refresh the animations either, I'm afraid. That simply spawns a new player and aims its Animator at the original, non-baked Controller (as in, the one that I'm currently using for the Mecanim transitions). It doesn't refresh the list of child animations shown under the controller, so I still have no way of adding the new animations into Mecanim without creating a baked version first and then dragging the animations from that new Controller back into the original one that was created with right-click > Instantiate Mecanim. I have a feeling that may work if I first deleted my original Controller and I would then be able to see all the new animations, but, as you said, I'm assuming that would still delete all the state machines I have in Mecanim and I'd be back at square one anyway!

So, I still haven't found a great work-around this problem for now. Still having to bake a new controller and drag the individual animations around every time I add new animations. It isn't a terrible problem, but it just seems like there must be a more straight-forward and slightly less confusing way to do it.

Thanks very much for the suggestions though, guys. I really appreciate them.
Jamie
  • Beiträge: 8

clandestine

This might be useless, but have you watched the video about the baking feature? I assume it mentions that somewhere...
Benutzeravatar
clandestine
  • Beiträge: 48

blinz117

The basic idea behind baking objects is that it converts them to native Unity objects. This means after baking, your objects no longer rely on the Spine runtime to function (I believe the video references this).

Being fairly new to Unity and Spine myself, I'm certainly no expert, but I would probably say not to bake your objects unless you really have a reason to do so. There are some cool elements to the Spine runtime (check out the features on this page: viewtopic.php?f=3&t=3318 ... Thanks, Mitch!) that you lose out on when baking. (I'm sure some more experienced Spine/Unity users may disagree with me on this :) )

As far as getting things to work the way I was suggesting, I just tested and confirmed that the animation controller does update correctly. Here are the steps that I used (note that I am using Windows and Unity 5, although I'm pretty sure this worked the same in 4.6):

1) Export your animation from Spine and import into Unity (I usually just do this by dragging the files from Windows Explorer into the project window in Unity).
2) Right click on the SkeletonData.asset file that was generated, and click Spine>Instantiate (Mecanim). The object is added to the scene. Note, also, that an animation controller is added to your project that contains your animations. This animator is also automatically associated with the object in the scene.
3) Make a new animation in Spine and re-export
4) THIS STEP IS IMPORTANT: Open your Unity project folder in Window explorer (right click on any of the Spine data in the project window and select "Show in Explorer"), and in another Explorer window open the location where you exported your Spine data. Copy the atlas, png, and json files FROM the Spine export folder TO the Unity asset folder where your old Spine data exists. This will probably ask if you want to overwrite the files, and say yes for all files. (As a side note, I tried dragging the data directly into Unity, but this simply created a new copy and did not update the data that was already there)

At this point, when you go back to Unity, the data will be refreshed, and the animator controller that was already there should be updated with the new data (including your new animation). Additionally, the state machine (the animations and transitions) should be preserved, and you can simply drag and drop your new animations.

Hopefully that made some amount of sense. Let me know if this process works for you. If not, I'd consider making a video tutorial if that would be useful to you.

Good luck!
Benutzeravatar
blinz117
  • Beiträge: 5

Jamie

Thanks for that, Blinz. It hasn't actually worked, but I think I can see why (and I wouldn't be surprised if this is why it wasn't working for me at all to start with). I followed your steps and it didn't appear to work, but I noticed I'm getting the following error in the Console:

"NullReferenceException: Object reference not set to an instance of an object
SpineEditorUtilities.ResetExistingSkeletonData (System.String skeletonJSONPath) (at Assets/spine-unity/Editor/SpineEditorUtilities.cs:382)"

ResetExistingSkeletonData! That sounds very much like the kind of function I need. I've just looked in the SpineEditorUtilities.cs file and can see the following code:
static void ResetExistingSkeletonData (string skeletonJSONPath) {

string dir = Path.GetDirectoryName(skeletonJSONPath);
TextAsset textAsset = (TextAsset)AssetDatabase.LoadAssetAtPath(skeletonJSONPath, typeof(TextAsset));
DirectoryInfo dirInfo = new DirectoryInfo(dir);

FileInfo[] files = dirInfo.GetFiles("*.asset");

foreach (var f in files) {
string localPath = dir + "/" + f.Name;
var obj = AssetDatabase.LoadAssetAtPath(localPath, typeof(Object));
if (obj is SkeletonDataAsset) {
var skeletonDataAsset = (SkeletonDataAsset)obj;

if (skeletonDataAsset.skeletonJSON == textAsset) {
if (Selection.activeObject == skeletonDataAsset)
Selection.activeObject = null;

skeletonDataAsset.Reset();

string guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(skeletonDataAsset));
string lastHash = EditorPrefs.GetString(guid + "_hash");

if (lastHash != skeletonDataAsset.GetSkeletonData(true).Hash) {
//do any upkeep on synchronized assets
UpdateMecanimClips(skeletonDataAsset);
}

EditorPrefs.SetString(guid + "_hash", skeletonDataAsset.GetSkeletonData(true).Hash);
}
}
}
}
That all looks fine to me, but I'm no expert, and obviously something has gone wrong. The ".asset" file is in the correct place, so I'm not sure what could be causing this.

Do you think I should start a new thread specifically for this error?
Jamie
  • Beiträge: 8

blinz117

Yep, that is likely your problem. The line that is having that error is the first line below (based on the Git repo: https://github.com/EsotericSoftware/spi ... ilities.cs). That means the "UpdateMechanimClips" method is never getting called.
if (lastHash != skeletonDataAsset.GetSkeletonData(true).Hash) {
//do any upkeep on synchronized assets
UpdateMecanimClips(skeletonDataAsset);
}
One thing that you can try is to change "true" in that line to "false". That parameter specifies if the GetSkeletonData function spits out debugging info. If you set it to false, you can see the debug info and maybe get a better idea of what is going on.
Benutzeravatar
blinz117
  • Beiträge: 5

clandestine

I just tested this with and without baking, and here's the behaviour I get:
- With baking, animations aren't updated in the controller unless you choose "Bake All Skins" or "Bake [Skin]" from the actual SkeletonData asset. This makes sense, because baking animations into clips is much slower than creating a dummy asset to mirror Mecanim.
- Without baking, animations are automatically updated in the controller when you export new animations.

My guess here is that your SkeletonData asset is pointing at the wrong / an invalid asset or something. Can you post:
- Your directory layout (just a screen of the window in Unity)
- Your Inspector window for the SkeletonData asset.
Benutzeravatar
clandestine
  • Beiträge: 48

Mitch

Yea... I should handle baking better...

Unity 5 solved a lot of problems with not being able to access Controllers through editor code so I was holding off. I'll take another pass at dealing with updating existing clips for Baking as long as they're still in the same folder.
Benutzeravatar
Mitch
  • Beiträge: 978

Jamie

Thanks for your replies.

I've uploaded two images:

--- unity_project.png ---
This shows the Project window. You can see the "character_suit_constraints_Controller" file only has 6 animations under it, and never gets updated automatically when I export new animations. At the moment, when I bake the SkeletonData, it goes into the "Baked" folder. That's where the updated Controller with all of the animations lives. When I add a new animations, I re-bake and go find the new Controller in that folder, then drag the new animation up a level into the Animator window for the Controller in the "characters > pc > data" folder.

--- unity_inspector.png ---
This is the Inspector for the SkeletonData file. You can see it's linked to the correct controller that's shown in the previous image. You'll also notice that there are 11 animations shown, only 6 of which are shown in the Controller in the previous image.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Jamie
  • Beiträge: 8

clandestine

Okay, I've just done a test to figure out updating baked controllers. It looks like you can edit the controller and bake over it while maintaining transitions, so that's probably what you want to do. You could also use two controllers, but since you're doing baking the SkeletonData asset should not point at any controller. That's only for the Mecanim-connected SkeletonAnimator, which is separate from baking.

You said earlier that baking over the same controller was messing with your states / transitions, right? That's not happening for me - what version of Unity do you have?
Benutzeravatar
clandestine
  • Beiträge: 48

Jamie

I'm using Unity 5 now. If I try rebaking over the existing one, I get an error, but it's fine. I'm giving up on worrying about this for now. I'm sure it's just got something to do with how I originally set up my project, and I imagine I wouldn't encounter the same problems in future if I just make sure I edit the correct Controller in the first place. I can work around it anyway.

And you were right: If I bake a new Controller, edit it, then rebake, it does update the animations and retain the existing transitions.
Jamie
  • Beiträge: 8

Majicpanda

I'm actually experiencing this exact issue.. so there is no way to "Generate Mecanim Controller" and preserve your states and transitions?

I have just started my project so doing it the right way from scratch is no problem, but it seems very confusing what the proper workflow should be ;)

There are a ton of things I'd like to use in the Spine controller like swapping out attachments as sprites for equipping items on a player that I don't think you can do if you bake?
Majicpanda
  • Beiträge: 197

Pharan

That's right. Baking doesn't support a lot of features. Baking is a workaround in case you don't need/don't want to use or rely on the Spine runtime— which includes publishing stuff to the Unity Asset store (though I heard that this is actually okay).

As for Mecanim controller stuff, I'll send a message to Mitch to let him know you're having problems.
Benutzeravatar
Pharan
  • Beiträge: 5366

Majicpanda

Small bit to add. I just tried exporting after making a new animation and then went into Unity, made sure the SkeletonData had the Animation Controller still hooked up in the inspector and then did Instantiate(Mecanim). This appears to update and if not existing, create a new animation controller which might work great except that it duplicated a ton of clips under my controller and now I can't get them out. Any idea why this would have occured?

Edit: It seems unity auto updates the controller after you build over to unity so not sure what caused all the dupe clips now unfortunately...
Majicpanda
  • Beiträge: 197

Xelnath

Hmmm... I've done some work with Mechanim states and such... I'll see if my programming buddy or I can solve this problem and share the script.
Xelnath
  • Beiträge: 408

Pravus

Hello, i know this thread has been inactive for a couple of months but i came to share my solution to the same problem the opener asked about (since i'm having the same issue).

I use the spine animations in unity without baking them, instead i use a SkeletonAnimator with the auto-generated Mecanim controller.

What i did was create manually a new Animator Controller that uses the animations from the Spine-created controller, so when i export new animations from the Spine project i just delete the Spine-created animator and create it again with right click on the SkeletonData file -> Spine -> Instantiate (Mecanim).
And then i just drag & drop the new animations from the spine-created controller (from the project view) into my manually created animator controller (which has all the transitions and logic between states).

So my character on scene has its animator component using the AnimatorController i created manually.

I hope this workaround helps somebody, it's the best solution i came up with.

Cheers
Pravus
  • Beiträge: 1

OperationT

I am also having this problem without baking. According to clandestine, automatic update of the list of animations as children of the automatically generated Controller worked when not baking, and didn't work when baking. However, I am not baking, and still unable to get the automatic update to work.

Thanks for suggesting this work around, Pravus. I think I will have to use this method for now. This will be quite a hassle to re-link each animation to their respective states in the separate Controller, since these links are lost when you delete the auto-generated Controller, which carry all the animation clips. In addition, all of the in-animation events/function calls have to be recreated as well - all of this each time you export new animations from Spine.

It would be so great if someone could point us in the right direction.
OperationT
  • Beiträge: 12

Mitch

will address this over the coming weekend.
Benutzeravatar
Mitch
  • Beiträge: 978

Majicpanda

Not sure what the exact issues are still but my work flow is:
1) Export to unity
2) Right click SkeletonData file - Instantiate (Mecanim)
3) Save to prefab, delete scene object
4) Ensure prefab has anim controller that is auto-generated
5) Update spine animation, even add a new one.. export to unity (direct file path to unity project)
6) auto generated controller has new animation, everything appears to still be in-tact.
7) Drag new animation clip to Animator window in unity for usage.

Nothing seems to be getting deleted.. not sure what could have possibly changed. I used to have issues but now I don't, sorry for not much info to go off of but somehow things work fine for our workflow. I have seen issues sometimes where the auto built animator won't update properly.

Do you guys all export directly into unity or are you trying to drag and drop files into the inspector etc? I build directly to file path IN my unity assets folder and wait a few seconds and then click into Unity to see changes. If for some reason the auto built controller doesn't update I export again and everything is good.
Majicpanda
  • Beiträge: 197

OperationT

I'm happy to say that I've found the problem for my specific case. Hopefully this will help others as well.

The problem, for me, was adding extension .txt to the .json file as well, which I learnt from following this tutorial https://www.youtube.com/watch?v=x1umSQulghA, as was suggested in a few other posts. After reading a few threads on the forum, I've learnt that this used to be required in Unity 4.x. I suppose Unity 5.x can handle .json files now. I have reproduced this problem a few times by using .json.txt a few times, so I am certain that this was causing the Controller to not update itself when I re-exported from Spine.

Solution: I've deleted the previous Spine export files in Unity and re-exported them from Spine, this time adding only .txt to the .atlas file and leaving .json as it is, and now the auto-generated Animation Controller updates itself by adding/deleting animations as its children every time I export from my modified Spine project. Just awesome.
OperationT
  • Beiträge: 12


Zurück zu Unity