- Home /
Can someone please answer my questions for once please.
I have had this problem for months now. The transitions in mecanim are unpredictable. My character, depending on the root's next rotation value will spin around clockwise or counter clockwise. (This is how quaternions work). Now my two questions:
Is it true that mecanim transitions are based on quaternion rotations?
How do I access a transition and how can i reverse the quaternion's rotation?
Thank you,
Dave
Answer by Daemonhahn · Nov 09, 2017 at 11:15 AM
Not exactly, and Yes.
This is not your problem, your problem is that you are not defining the exit time or transition time / controlling it. If you just let it auto blend it will do very weird stuff.
I recommend reading:
https://docs.unity3d.com/Manual/class-Transition.html
and
https://answers.unity.com/questions/355576/how-to-make-a-instant-transition-with-mecanim.html
If you set the transition period and exit time correctly, it will trim or skip that initial bit of quaternion blending and you will get a smooth animation, with no crazy rotations.
If after all this you still have issues, then it is to do with the state machine itself. Perhaps you need some extra animations that work as interstitials between the rotations you already have? Perhaps you need to align all the pivots and starting rotations and use root motion instead to move.
There's many different ways to get this to stop happening, as well as many things that could cause this. But its not just the way mecanim works, it works very well when set up correctly :)
Please select my answer as correct if I have helped you! :)
I was still working out your solution. You helped me understand transitions a lot better now thanks to confir$$anonymous$$g that it works with quaternions. Quaternions will always find the shortest distance on the sphere and I noticed in my 2.5d platformer that my character's pose facing left has a different rotational value in the root. An animation inbetween will definitely fix it and i'll set the transition duration to zero in the mean time. An ideal solution because I have a lot of asymmetry in my game's animations. Your answer really helped me figure out a problem I've had for months. :) Thanks a lot!
This was exactly what I needed: "Perhaps you need some extra animations that work as interstitials between the rotations you already have?"
No problem glad I Could help!
Take a look at statemachine behaviours for more advanced state machine magic!
And for a better understanding of the weirdness that is transitions, check out:
Good luck and feel free to P$$anonymous$$ me in the future for any unity related issues!
Answer by YTGameDevDave · Nov 11, 2017 at 06:33 PM
I counter rotated the rotation of the transition to reverse it.
this is the code for in your character's controller script, should be in LateUpdate.
RootHips is the variable that carries the gameobject of the actual root of your rig (not the parent root but the hips of the skeleton, the actual root of the skeleton).
if (ReverseTransitionRotation == true) {
n += Time.deltaTime * 10f;
if (n >= 1) {
n = 1;
}
a = Mathf.Lerp (0f, 360f, n);
RootHips.transform.eulerAngles = new Vector3 (RootHips.transform.eulerAngles.x, RootHips.transform.eulerAngles.y - a, RootHips.transform.eulerAngles.z);
} else {
n -= Time.deltaTime * 10f;
if (n <= 0) {
n = 0;
}
a = Mathf.Lerp (0f, 360f, n);
RootHips.transform.eulerAngles = new Vector3 (RootHips.transform.eulerAngles.x, RootHips.transform.eulerAngles.y - a, RootHips.transform.eulerAngles.z);
}
this is the code for in the animator, add this script to any clip you want the transition rotation reversed.
public class InverseTransitionRotation : StateMachineBehaviour {
int li;
float t;
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
animator.GetComponent<Player1Controls>().ReverseTransitionRotation = true;
t = 0;
}
override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
li = layerIndex;
t += Time.deltaTime;
//in this if-statement insert your input for the first transition's 'transition duration'
if (t >= 0.1f) {
if (animator.IsInTransition (li) == true) {
animator.GetComponent<Player1Controls> ().ReverseTransitionRotation = false;
}
}
}
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
t = 0;
}
}