Hello,
I’m making a game utilizing zero gravity. I have a sphere that a character floats inside of, and when space is pressed a force is applied and the character is propelled along the character’s local up direction ( character.up
) towards the edge of the sphere.
When the character gets close to the edge of the sphere I’m trying to make the character rotate so it’s local up ( character.up
) is pointing towards the center of the sphere and therefore lands against the sphere edge standing on his feet.
I know I’ve got the correct newUp
direction because I’m using Debug.DrawLine
to visualise it and it’s correct.
So it seems to be a problem with the way I’m using Quaternion.Lerp
or possibly Quaternion.FromToRotation
.
Here’s the relevant portions of code:
void Update () {
if(targetWithinDistance) { //If getting close to target point on the sphere's edge
RotateToCenter();
}
bool jumpPressed = CrossPlatformInputManager.GetButtonDown("Jump");
if(jumpPressed) {
Jump();
}
}
void Jump() {
localUp = character.up;
RaycastHit hitInfo;
//Raycast to jump direction
// 0.1f is a small offset to start the ray from inside the character
//Start ray from inside character, ray is directed along localUp towards the edge.
if(Physics.Raycast(character.position + (localUp * 0.1f), localUp, out hitInfo, 1000f))
{
//Hit found.
targetPoint = hitInfo.point;
newUp = (center.position - hitInfo.point).normalized;
}
jump = localUp * jumpPower;
rigidbody.velocity = jump;
Debug.Log("localUp: "+localUp);
Debug.Log("newUp: "+newUp);
isGrounded = false;
targetWithinDistance = false;
}
void RotateToCenter() {
q = Quaternion.FromToRotation (localUp, newUp);
character.rotation = Quaternion.Lerp(character.rotation, q, Time.deltaTime );
}
The code works perfectly fine if the localUp
is exactly (0, 1, 0)
, but is wrong when it’s not. It won’t rotate at all when the player’s localUp
is (0,-1,0)
even though newUp
is displayed as (0,1,0) and therefore should require a rotation of 180 degrees on the y axis.
The Debug.Log
in the Jump()
Method shows:
localUp: (0.0, -1.0, 0.0)
newUp: (0.0, 1.0, 0.0)
Yet the Lerp rotation doesn’t rotate at all.
Any help in finding out why this problem exists would be greatly appreciated.
Dan
UPDATE*
I’ve been trying to narrow down the problem and it seems to be to do with the local rotation of the character.
I’ve changed the code to instantly apply the rotation without using Quaternions, as below:
if(targetWithinDistance) {
transform.eulerAngles = newUp;
//RotateToCenter();
}
when this is run: the character will still rotate to an incorrect rotation, when transform.up is not exactly (0, 1, 0). But I’ve noticed that the Rotation displayed in the Inspector for the character seems to show the character has been rotated as if the transform.up started at (0, 1, 0).
For Example: If I I set the scene so that the character is at position: x:0, y:0, z:0
, character’s rotation is x:0 y:0 z:315
in the inspector, the transform.up for the character is displayed as (0.7071066, 0.707107, 0)
.
When jump is pressed, the new rotation back to the center is (-0.7071066, -0.707107, 0)
, (newUp is set to this correctly)
Now when the rotation angles are set with: transform.eulerAngles = newUp;
the new transform.up should be set to (-0.7071066, -0.707107, 0)
, but this is not the case!
The new transform.up is now: (0.000152301, 0.9999238, -0.01234009)
.
Looking at the rotation of the character in the inspector though shows a rotation of: x:359.2929, y:359.2929, z:0
.
For some reason the character has had the newUp
angles minused from the rotation!
X: 0 (360) degrees - 0.7071066 = 352.2928934;
Y: 0 (360) degrees - 0.707107 = 359.292893;
Z: 0 - 0 = 0;