- Home /
Gone back to the old animation route ..
Generic head rotation
Hi, I'm trying to rotate a head by its bone in Mecanim, the model is Generic so can't use _animator.SetLookAtPosition()
So what I've tried is first do the calculations in Update() like below -
// Rotate to face the Player
lookPos = player.position - mechTurret.position;
rotation = Quaternion.LookRotation(lookPos);
rotation *= Quaternion.Euler(-10, 0, 0);
Then in LateUpdate() I've got this -
mechTurret.rotation = Quaternion.Slerp(mechTurret.rotation, rotation, Time.deltaTime * 100);
But the turret does not look at the player smoothly their is some shaking, how can I remove the shaking or is their a better way to force the turret to look at the player? Thanks.
Answer by HappyMoo · Jan 01, 2014 at 12:22 PM
instead of
Time.deltaTime * 100
you want:
Time.deltaTime * rotationSpeed
and for rotationSpeed start with something like 2f .... and don't go over 20f
Happy$$anonymous$$oo, thanks for the input, but 2 is WAY to low for the rotation to take over $$anonymous$$ecanim control, at 100 I still see slight shaking that is unacceptable, and going even higher it's just to fast to look natural ..
Oh, you're also animating the turret with $$anonymous$$ecanim? You can't have two Systems pulling at the poor Turret at the same time.
Are you getting the shaking motion only when you are close to the target angle or all the time? Try small speed numbers to see when you get the shaking.
Also, what is that Quaternion.Euler(-10, 0, 0) for? Are you trying to correct where it looks, so it's not looking at the feet, but head of the player or something like that? Then better try to correct this by correcting at the lookpos like that or similar: Quaternion.LookRotation(lookPos+Vector3.up) Because we don't want to introduce possible gimbal lock problems with Euler angles. However, this may not be the problem.
If it turns out that you only get the shaking at the end, maybe the problem is float precision. In that case you could try to stop the animation once your rotation is close enough, or mathematically, if the Quaternion.Dot product between them is close to angleA.magnitude*angleB.magnitude
Yeah I know you shouldn't mix the two, the shaking is all the time it's trying to rotate as they both fight for control, yes the Quaternion.Euler(-10, 0, 0) is a correction to line up the view .. Why O Why can't you just no$$anonymous$$ate a bone in .SetLookAtPosition() in $$anonymous$$ecanim it would make life Sooooo much more fun .. :)
I've searched for hours and read loads this morning on this problem and it looks like it's not easy to do what I'd like to do.
Can you create a AvatarBody$$anonymous$$ask on your BaseLayer, and leave out the bone you want to turn via script?
Yeah I suppose I could do that as there is no animation on the turret, but it's a long winded way around the problem, so I've gone back to the $$anonymous$$ech with the old AI script I wrote using the old animation system and just used a bit of code in the animation section to Instantiate the dust cloud depending on the time of the animation the Instantiating it on either the left or right foot.
function walk(){
animation["Walk"].wrap$$anonymous$$ode = Wrap$$anonymous$$ode.Once;
animation.CrossFade("Walk");
// Instantiate the footDustCloud under the $$anonymous$$echs feet only if in viewing range
if(distanceToPlayer < seeFootDustDistance){
if(leftFootOrRight){
leftFootOrRight = false;
yield WaitForSeconds(1.0);
Instantiate(footDustCloud, leftFoot.position + -transform.forward * 1.1, Quaternion.identity);
CameraShake();
}
if(!leftFootOrRight){
leftFootOrRight = true;
yield WaitForSeconds(1.0);
Instantiate(footDustCloud, rightFoot.position + -transform.forward * 1.1, Quaternion.identity);
CameraShake();
}
}
}
And it's working fine, Happy$$anonymous$$oo I really do appreciate you taking the time to help, cheers.