- Home /
Reusing an Animator Controller for generic animations
Hello,
I've been trying to switch to the Mecanim animation system and I ran into a problem, to which I can't find a solution.
Let's say, I have 40 objects with animations. They all have different skeletons and animation lengths, but all objects have animations with the same names (e.g. "idle" and "action"). Is there a way to have a single Animator Controller for all of the objects (or maybe something similar)? Or do I have to create a controller for each object separately?
With legacy animations you could have a script, from which you run "idle" or "action" and it would work for all objects (no matter what skeletons or animation lengths they have). I'd like something similar and reusable for generic Mecanim animations.
Thanks in advance!
Answer by porygon · Aug 08, 2014 at 06:17 AM
At the very least, you can use AnimatorOverrideController, but you will still have to fill in the variables:
http://pekalicious.com/blog/unity3d-reusing-animator-controllers-with-animatoroverridecontroller/
Hi porygon,
although, it's been quite a while since I asked this question (I ended up using legacy animation back then), I ran into the same issue in another project just recently.
This time I actually used the AnimatorOverrideController (I scan all the animation clips of the imported model on Start and assign them to the AnimatorOverrideController). That way I only need one AnimatorController and one AnimatorOverrideController, as well as a script that reads animation clips and assigns them dynamically. It's still more complex than the legacy option, but at least a proper solution.
I think there was no AnimatorOverrideController a year ago, though :) So, it's great that we at least have that option now.
Answer by Volcanic-Penguin · May 03, 2013 at 01:23 AM
You can, with Unity Pro, where you can check Sync on state machine layers to have lots of layers with the exact same state machine but with different animation clips, and then you set weight to 0 on the base layer and set the layer that corresponds to the character to weight 1.
Other than that I just know that you can duplicate an Animator Controller, but that's not quite what you would want.
wow... never read that before... Thanks for sharing !!!
Beware of the "Copy current state machine" option.
I am pretty sure that the copied state machine could be modified by it. And I recommend you to enter "al mano" all parameter first and then past the state machine in the new controller. Otherwise, some of them are not copied and several transition could be lost while pasting.
Hi Volcanic-Penguin,
thanks a lot for your reply! I've tried it out and this feature seems very useful. On the other hand, it still means that I have to manually create 40 layers and drag the animation clips into each of them, right? This is much better than having 40 controllers, but still a bit sluggish in comparison to legacy animations (where you have to do nothing else, just call an animation from the script by name and you can use it on any object that has this animation; only one line of code, basically).
Hmm yeah I think so, unless you write some clever editor script or something but that's out of my league. I think this might be something the Unity $$anonymous$$m is improving for future versions.
I think editor script will not help much as the $$anonymous$$echanim API is not provided, at least for now...
But yes, Unity $$anonymous$$m is working on that and I really hope we will able to modify controller and states pretty soon for my own sanity ^^
Answer by Xelnath · Mar 20, 2015 at 06:49 AM
I am trying to create a script that auto repopulates an Animation Override Controller - but I can't seem to "write" to the animationClips property... it just resets.
Help :(
In case you're still struggling with this:
Without looking at your code, my guess would be that you're getting the AnimationClipPair
array off the override controller
, and looping through and setting each pair's override clip and calling it a day. I ran into this problem too, and it doesn't set like that.
You have to make a new AnimationClipPair[]
, and then when you change the overrideClip
on the old pair, put it into your new array and then set the clips on your AnimatorOverrideController
to this new array. Like this:
// get the number of clips on the AnimatorOverrideController
int numClips = controller.clips.Length;
// make a new array of that length
AnimationClipPair[] newClips = newAnimationClipPair[numClips];
// loop through each clip pair
for (int i = 0; i < numClips; i++) {
AnimationClipPair pair = controller.clips[i];
// get the appropriate clip from your model
string name = pair.originalClip.name;
AnimationClip clip = fbxClips.Get(name);
// if there is a model clip,
// set it as the overrideClip on the pair
if(clip != null) {
pair.overrideClip = clip;
}
// save the pair to your new clips array
newClips[i] = pair;
}
// when everything is properly set,
// replace the entire clips array
controller.clips = newClips;
Answer by plagas36 · May 12, 2016 at 02:51 PM
Hey, I've made an asset that can duplicate an animator controller and replace animation clips by new ones at the same time. Perfect if you have multiple character using the same kind of animator structure.
It can also detect changes in durations. Just check it out. I think it could help people with that kind of problem.
Here's an video where I have multiple characters with the same controller structure: Example
And another one where I show how curves and events are also kept during transfer: Presentation
Thanks guys
Your answer
Follow this Question
Related Questions
unity freezes when running sprinting animation 0 Answers
Using Override Animation Controllers (NOT WORKING) 0 Answers
Mecanim errors after animation clip import 1 Answer
Animation Mecanim - Parts of model displaces after animating 0 Answers
Back to "default transform" after animation interrupts 1 Answer