Hi all,
Apologies if this is all handled in some Unity tutorial, I’ve watched a few and haven’t seen it yet.
I’ve got this simple controller script that demonstrates two ways of moving a spaceship forward. The problem is that the AddForce() method is too realistic, in that if the player rotates the ship 180’, they will still be travelling backwards until their velocity equalises. If I just set it to zero when the player moves, that isn’t going to be good either, as I don’t know the final outcome is that they want to face the other way.
Thanks Mr Newton.
Do most space games tend to ignore that physics lesson and turn ships on a knife edge, regardless of how much force might be required in the real world?
I’ve got another method which is naughty and directly manipulates the position, I get my desired playability, but now the colliders only half work (they collide, stop me or move around me a little, but generally don’t react the same way as when AddForce is used).
How do I change this code so that I can get the rigid body collision to work as expected, and be able to turn around quickly, without looking like I’ve stopped/started? And setting velocity=0 is probably going to be a harsh result and mess with the results of a natural rigid body collision.
public class PlayerInput : MonoBehaviour {
// rotation of both pitch and roll
public float finalRotationSpeed = 3.0f;
public float rotationAcceleration = 1.00f;
public float fThrust = 1.0f; // thrust per second? not quite.
Rigidbody rigidBody;
public struct Axis
{
public string axisName;
public float fRotation;
};
private Axis rollAxis;
private Axis pitchAxis;
// Use this for initialization
void Start () {
rollAxis.axisName = "Horizontal";
pitchAxis.axisName = "Vertical";
rigidBody = GetComponent<Rigidbody> ();
}
private void UpdateAxis( ref Axis axis )
{
// get the input (smoothed & fractional between -1 and 1)
float fInput = Input.GetAxis (axis.axisName);
// move the current rotation value towards the strength of the joystick position
// and the terminal rotation speed, doing so with an acceleration factor.
// this allows us to have a feeling of inertia, as we don't immediately stop, nor do we
// immediately switch direction if the user banks hard in the opposite direction.
axis.fRotation = Mathf.Lerp (axis.fRotation, fInput*finalRotationSpeed, rotationAcceleration * Time.fixedDeltaTime);
}
private void FixedUpdate()
{
UpdateAxis (ref rollAxis);
UpdateAxis (ref pitchAxis);
transform.Rotate (new Vector3 (pitchAxis.fRotation, 0, -rollAxis.fRotation));
// this makes it feel like real space - you have to have an equal and opposite reaction
// but awful to control!
// bonus: using AddForce, we can use velocity to determine speed and asteroids bounce off nicely
//if (rigidBody.velocity.magnitude < 3.0f ) {
// rigidBody.AddForce (transform.forward * fThrust * Time.fixedDeltaTime, ForceMode.Acceleration);
//}
// using this feels like an aircraft rather than shuttle
// and it's a lot nicer, and collisions kinda work, but not as natural as above.
// Also, here we have to control the velocity at all times.
transform.Translate(transform.forward * 0.5f * Time.fixedDeltaTime, Space.World);
}
}