- Home /
rigidbody.velocity is queued for processing after rigidbody.position
While following the Space Shooter tutorial, I had the impression that rigidbody.velocity gets queued for processing by the phisics processor after rigidbody.position, regardless of the order I set them in the code. This is the code I'm using:
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Boundary
{
public float xMin, xMax, zMin, zMax;
}
public class PlayerController : MonoBehaviour {
public float speed;
public Boundary boundary;
public float tilt;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
Vector3 velocity = movement * speed;
rb.velocity = velocity;
rb.position = new Vector3
(
Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax),
0.0f,
Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax)
);
rb.rotation = Quaternion.Euler(0.0f, 0.0f, rb.velocity.x * -tilt);
}
}
The problem with that code is that when the ship gets to the boundary I've set (xMin, xMax...), it still moves 0.2 further into the boundary. My current Fixed Timestep is set to 0.02, but if i change it to 0.05, the ship will actually move 0.5 into the boundary. That happens because I have set the speed to 10 and so:
Vector3 velocity = movement * speed;
I believe the phisics processor multiplies that by fixedstep and thats why i get to advance into the boundary. If I set the timestep to 0.02 and the speed to 100, the ship will move 2 into the boundary. I think the position is the first one to be set and then i move movement speed Time.deltaTime into the boundary in the first cycle. In the next cycle i repeat the whole process: clamp position to xMin and xMax and only then set the velocity to movement speed Time.deltaTime.
I couldn't find this behaviour explained anywhere in the documentation and so I want to ask you guys if I'm getting it right. I actually solved this problem by clamping the transform.position in the Update() function so I was sure that nothing would get rendered passed the boundary.
I also tried to solve it by predicting the next cycle's rigidbody position but I couldn't get it to work. What am I doing wrong? This is what i tried:
float finalXPosition = rb.position.x + velocity.x * Time.deltaTime;
if(finalXPosition < boundary.xMax || finalXPosition > boundary.xMin)
rb.velocity = velocity;