rigidbody, lookrotation

Hi,

I decided to ditch the character controller and go back to use a rigidbody.
the interactivity with other objects is a must for our game, so we better
embrace Unity’s built-in physics, instead of applying it manually :slight_smile:

My question is related to this older thread on Lookrotation and rigid bodies:
http://forum.otee.dk/viewtopic.php?t=1435&highlight=force+rotation

The problem is that the character starts acting very weird (rotating like crazy) when standing still. I read that Otee warns about Lookrotation with rigidbody, so I want to try another option. I can’t rotate a child for practical reasons (as mentioned as a solution in the thread).

So, my intention is to add torque to my character until it reached the right direction. But how can I calculate how much torque needs to be applied, and which direction?

current method:

private var lastPosition = Vector3.zero;
private var thisPosition = Vector3.zero;
var turnSpeed = 10.0;

function FixedUpdate () 
{
	thisPosition = transform.position;
	thisPosition.y = 0;

	if (lastPosition != thisPosition) {
		moveRotation = Quaternion.LookRotation (thisPosition - lastPosition, transform.TransformDirection(Vector3.up));
		transform.rotation = Quaternion.Lerp (transform.rotation, moveRotation, turnSpeed * Time.deltaTime);
	}

	lastPosition = transform.position;
	lastPosition.y = 0;
}

We definately do recommend using rigidbody.freezeRotation and rotating through the transform interface.

If you are making a first person controller you should:

  1. Use freezeRotation
  2. Make sure you are using the Capsule collider. Make sure the capsule center is at the pivot point of the transform.

If you follow that, you can safely modify rotation through the transform interface with no problems.

The only case when using freezeRotation might be a problem is when the pivot point of the transform is very far off from the rigidbodies center of mass. This is seldomly the case.

Do you mean pushing other objects or being pushed by objects?
If it is only for pusing other objects. This is really easy to do with the character controller.

        var pushForce = 300.0;
	// Push all rigdibodies forward when running into them!
	function OnControllerColliderHit (hit: ControllerColliderHit)
	{
		var body : Rigidbody = hit.collider.rigidbody;
		// Only rigid bodies
		if (body)
		{
			var normal = transform.TransformDirection(Vector3.forward);
			body.AddForce(normal * pushForce);
		}
	}

Hi Joachim,

Cool! I could even calculate the current char.controller velocity and apply a dynamic value to the rigidbodies.

However…its because of the interaction both ways: let’s say my character jumps on platforms with a spring attached. Or floating platforms in water. Thats so much easier with physics.

EDIT:
http://www.stickystudios.com/etc/har.html

I have replaced it with a capsule collider (it already did freezerotation). Do you see the crazy rotation when standing still?

You mean when you are running and then stop he does a 180 degree turn?

I don’t think this is related to freezeRotation. Can you post your script.

Hi Joachim, exactly! Sometimes he even keeps turning, turning…

This is the script that rotates the character.
ps: I tried fixedUpdate and Update too.

var lastPosition = Vector3.zero;
var thisPosition = Vector3.zero;

function LateUpdate () 
{
    thisPosition = transform.position;
    thisPosition.y = 0;
    
    if (lastPosition != thisPosition)
    {
        moveRotation = Quaternion.LookRotation (thisPosition - lastPosition, transform.TransformDirection(Vector3.up));
        transform.rotation = Quaternion.Lerp (transform.rotation, moveRotation, 5 * Time.deltaTime);
    }
    
    lastPosition = transform.position;
    lastPosition.y = 0;
}

9672--352--$afbeelding_112.jpg

moveRotation = Quaternion.LookRotation (thisPosition - lastPosition, transform.TransformDirection(Vector3.up));

The thisPosition - lastPosition is causing the problem.

There are two things you can do:

  1. Derive the move rotation from the keyboard presses
  2. Add an epsilon for checking the movement direction eg.
var move = thisPosition - lastPosition;
var minimumDelta = 0.1 * Time.deltaTime;
if (move.sqrMagnitude > minimumDelta * minimumDelta)

The code worked!
Magical! Thanks!

What was going wrong? Is this new code actually detecting if there was any movement? (if movement is larger > 0.1?). What does sqrMagnitude stand for?

Thanks again! I would not have found the solution myself.

sqrMagnitude is the square length (length^2).
You often use square length for comparison instead of length to avoid the square root which is involved when calculating the length of a vector.

Cool!

Check out the cool result:
http://www.stickystudios.com/etc/har.html

The mini game is going to be about ships attacking your base. You can blast them with your handcannon, but if you’re not fast enough, they’ll aim at your tower. The longer you remain on the tower, the better your score.

I hope I’ll be able to calculate how the cannonballs must be shot so that they will hit the tower from every direction though :smile:

And btw, the collision responds doesnt always return “true” when I touch other elements in the scene, as a result of this the char doesnt always jump when pressing space. Thats odd.