Hey all, I’m just now getting started with importing animations into Unity, and I have what will probably end up being a really basic question.
So I have a simple character, non-deforming. I’m animating him to bob up and down very slowly along the positive y axis in Maya, so the animation goes from like 0 to 1 on y and then back down again. Now in Unity, this animation comes in fine. However, my character is positioned away from the origin in Unity, and whenever I hit the play button to preview the animation, the character snaps back to the origin (since that was where the y translation was keyed in Maya).
My question is this: is there any way to say “Hey Unity, I want to play this animation local to where the character is currently positioned”? In other words, if the character is positioned off-origin in the Unity game-world, is there a way to have him animate in place wherever he is positioned? Or maybe I need to go about the animations in Maya a different way?
You just need to place the animated object inside an empty parent object. The animation will then be positioned in the parent’s coordinate space, and you can move the parent to reposition the visible object.
doesn’t this seem a bit of a long winded approach? surely just being able to flag an animation as ‘Local’ would suffice and would be a trivial addition to animations? Perhaps in the AnimationState class?
Even if parenting (say you have planets under a Sun parent) you may still want an animation to be absolute/global even though it’s parented!
For whatever reason, you may want the planets to bob up and down locally as they orbit… but then play a global space anim if you select them, forcing an absolute position… just one example!
So letting users decide how the anim transforms are applied could open up more flexibility and do away with redundant busy work!
It much easier to say that than to do it and keep proper backwards compatibility. It just doesn’t fit current Unity design. The way it works: Animatoin component just overrides values in Transform - that how you get “world space” animation. What you’re suggesting is that Animation should add values to Transform (that how you would get "local space animation), which means Animation component would have to store the original values somewhere and then if you want to change the “world space” on which animation is played you would have to change it not on Transform, but somewhere else where Animation component stored it, so it just becomes a mess. Does it make sense?
So just parent your game object to empty game object, or add another root in your 3D file and do not animate it (then animation should not affect it).
I also need to move animations around and have them keep their local movement. But when I parent 6 animated objects to an empty Transform, as soon as I push “Play” all my animated objects disappear!
If I de-parent them from the empty Transform, they play as normal. What’s going on!?
This is a tricky topic and has taken me a while to figure out, though I did find a solution that may help others. You can use a script to offset an animation by applying the offset during LateUpdate. It won’t work during Update because the transform values will get overwritten by the animation. As pointed out by Paulius, the animation clip simply sets values to the transform. You can add your own values to the transform afterward:
hey walkerfx, in your script, where did you define myOffset?
I’ll give that a shot!
hey Paulius - it makes total sense what you say yet I don’t see the problem, in principle at least, with how you described approaching the issue? What I suggested would still be backward compatible as well - the default setting for the new Local/Absolute enum (or however you implement it) would be what the normal behaviour in previous versions would have been.
I understand of course that in practice modifying a component at the source level isn’t as simple as “just” adding a new enum.
Hey there, just in case someone is struggling with this as well and finds this topic by googling, I managed to put together a very simple script file (in C#) that makes the animation of the object play locally:
using UnityEngine;
[RequireComponent(typeof(Animation))]
public class LocalAnimation : MonoBehaviour
{
Vector3 localPos;
bool wasPlaying;
void Awake()
{
localPos = transform.position;
wasPlaying = false;
}
void LateUpdate()
{
if (!animation.isPlaying !wasPlaying)
return;
transform.localPosition += localPos;
wasPlaying = animation.isPlaying;
}
}
It’s very brute force but quite simple, all you need to do is to add it to your object that has the animation. It will check if the animation is playing and modify the position of the object accordingly.
What about introducing a new component type (or even subclass of “animation” ) called “LocalAnimation” ( or “AnimationLocal”, or “AnimationAdditive” or something ) ? That surely would keep backward compatibility while give the user some comfort…
If i re-think about it: why not just introduce a boolean property to the Animation component called “additive” or “local” or whatever, which is off by default ?
Just in case someone else runs into what I did, be sure to create your empty game object first. Then drag your model from the Project panel to the new empty game object in the Hierarchy panel.
In my case, having the model already in the hierarchy panel > creating empty game object > moving model inside empty game object > same undesired result with model position jumping around.
Thank you oooo lord i was like 3 hours on that and it was just drawing fomr the project apnel and not into the hierarchy and then etc …GOOD BLESS YOU MAN YOU ROCK !
I am having the same problem with jumping. I am using the free version of unity 4 but I am following a tutorial that was created with unity 3.5. Of course they don’t talk about the animator controller in the tutorial but I was able to figure that out. So now the animation is running when I hit play.
However I am having issues with the character jumping back to the origin. I have tried creating an empty game object and parenting the character to it. I even tried creating the empty game object then putting the character in it from the project window as suggested by thesfid.
Which tutorial is it ? You are using the legacy system, right ? If you are using Mecanim the parent game object trick will not work and its probably a different problem you are having.
I’m doing the lynda.com unity 3.5 essential training
Yeah I was trying to use the Mecanim Animator component. Which was giving me the “jumping to origin problem” even with parenting to an empty game object.
I then tried the Legacy animation component. The character stayed put, but the animation doesn’t play and I made sure to add the animation clips to the component.
With mecanim there is similar trick to parenting but its a lot more tedious and needs to be done in the animation file and Unity. Since Legacy will be completely phased out by Mecanim in the future, it would be nice to be able to have a similar trick with mecanim to have animations played at local position on objects which don’t have bones. Currently to animate a non-rigged object with mecanim and have them play locally they need to be inside two parents to make it work…
Anyways about your problem on legacy, Did it give you any errors or warnings ? Are you using code to animate your character or you just put some animation on the animator component and had Play Automatically checked ?
When the animation appears not to play, it’s because the name of what is suppose to be animated does match the object name inside of the animation clip. When it jumps, it’s because it’s a global animation. Meaning the parent is the target of the animation.