Daniel Burke
Daniel Burke

Reputation: 17

How to continue moving when I decrease speed

I am creating a game that is set in Zero-gravity. I am using a script that can be found here https://github.com/brihernandez/ArcadeSpaceFlightExample

The movement is controlled by a throttle that can be increased/decreased using the mouse wheel or 'w' and 's' keys.

This code controls the mouse wheel and is the same for the 'w' and 's' keys.

 private void UpdateMouseWheelThrottle()
{
    throttle += Input.GetAxis("Mouse ScrollWheel");
    throttle = Mathf.Clamp(throttle, 0.0f, 1.0f);
}

The object that is accelerated by the throttle stops moving when I decrease the throttle and does not drift or continue moving as it should in zero gravity.

This is the code that controls the physics.

public class PlayerPhysics: MonoBehaviour
{

[Tooltip("X: Lateral thrust\nY: Vertical thrust\nZ: Longitudinal Thrust")]
public Vector3 linearForce = new Vector3(100.0f, 100.0f, 100.0f);

[Tooltip("X: Pitch\nY: Yaw\nZ: Roll")]
public Vector3 angularForce = new Vector3(100.0f, 100.0f, 100.0f);

[Range(0.0f, 1.0f)]
[Tooltip("Multiplier for longitudinal thrust when reverse thrust is requested.")]
public float reverseMultiplier = 1.0f;

[Tooltip("Multiplier for all forces. Can be used to keep force numbers smaller and more readable.")]
public float forceMultiplier = 100.0f;

public Rigidbody Rigidbody { get { return rbody; } }

private Vector3 appliedLinearForce = Vector3.zero;
private Vector3 appliedAngularForce = Vector3.zero;

private Rigidbody rbody;

private Player player;

void Awake()
{
    rbody = GetComponent<Rigidbody>();
    if (rbody == null)
    {
        Debug.LogWarning(name + ": ShipPhysics has no rigidbody.");
    }

    player = GetComponent<Player>();
}
void FixedUpdate()
{
    if (rbody != null)
    {
        rbody.AddRelativeForce(appliedLinearForce * forceMultiplier, ForceMode.Force);
        rbody.AddRelativeTorque(appliedAngularForce * forceMultiplier, ForceMode.Force);
    }
}

public void SetPhysicsInput(Vector3 linearInput, Vector3 angularInput)
{
    appliedLinearForce = MultiplyByComponent(linearInput, linearForce);
    appliedAngularForce = MultiplyByComponent(angularInput, angularForce);
}

private Vector3 MultiplyByComponent(Vector3 a, Vector3 b)
{
    Vector3 ret;

    ret.x = a.x * b.x;
    ret.y = a.y * b.y;
    ret.z = a.z * b.z;

    return ret;
}
}

And here is the code that instantiates both.

    public class Player: MonoBehaviour
{
    public static Player Playerdrone { get { return player; } }
    private static Player player;

    private PlayerInput input;
    private PlayerPhysics physics;

    public Vector3 Velocity { get { return physics.Rigidbody.velocity; } }
    public float Throttle { get { return input.throttle; } }
    // Start is called before the first frame update
    void Awake()
    {
        input = GetComponent<PlayerInput>();
        physics = GetComponent<PlayerPhysics>();
    }

    // Update is called once per frame
    void Update()
    {
        physics.SetPhysicsInput(new Vector3(input.strafe, 0.0f, input.throttle), new Vector3(input.pitch, input.yaw, input.roll));
    }
    }

I cannot get the Rigidboy to keep drifting when I decrease the throttle, my option is to either abandon the throttle concept and use a simple "Addforce" but I would prefer to keep it.

I have edited the script to have a similar function to the 'Roll' that used 'w' and 's' but moves me forwards and backward. I still find myself decelerating when I let go of the input.

Lowering drag and angular causes the object to spin out of control due to the mouse following function. The mouse does not center the camera and instead causes the camera to keep rotating and tracking the mouse. Changing the mouse script will cause it's own issues since it controls the pitch and yaw of the object.

private void SetStickCommandsUsingMouse()
{
    Vector3 mousePos = Input.mousePosition;

    // Figure out most position relative to center of screen.
    // (0, 0) is center, (-1, -1) is bottom left, (1, 1) is top right.      
    pitch = (mousePos.y - (Screen.height * 0.5f)) / (Screen.height * 0.5f);
    yaw = (mousePos.x - (Screen.width * 0.5f)) / (Screen.width * 0.5f);

    // Make sure the values don't exceed limits.
    pitch = -Mathf.Clamp(pitch, -1.0f, 1.0f);
    yaw = Mathf.Clamp(yaw, -1.0f, 1.0f);
}

Upvotes: 0

Views: 105

Answers (1)

rel
rel

Reputation: 794

The object that is accelerated by the throttle stops moving when I decrease the throttle and does not drift or continue moving as it should in zero gravity.

The Rigidbody component has properties that can be changed in the Inspector (documented here) (and also via script (documented here)):

screenshot of the Rigidbody component in the Unity Inspector

  • Mass: The mass of the object (in kilograms by default).
  • Drag: How much air resistance affects the object when moving from forces. 0 means no air resistance, and infinity makes the object stop moving immediately.

It sounds like your Drag value might be too large (?).

Although this example project uses "space mechanics" (effectively with no air resistance), the Drag property can still be used to tune the movement and "drift behavior" of the rigidbody, and to control how long it will keep decelerating after the throttle value went down to 0.

Alternatively, you could try to experiment with other ForceMode parameters for the Add*Force() calls: ForceMode.Acceleration or ForceMode.VelocityChange (which is ignoring the mass of the rigidbody).

To make your game more "realistic", you could instead set the Drag property to 0 (no air resistance like in real space -> infinite drift), and try to actively decelerate the ship by experimenting with retrograde rockets/thrusters, by adding a force in backward direction. However, that's probably quite impractical for an arcade game, I guess.

There are also the global Physics settings of the project, which can be found under Edit -> Project settings -> Physics (documented here). There, you'll also find many important physics settings (like Gravity, for example).

(It can also be interesting to have a look at the official docs of the PhysX physics engine, which Unity uses internally for its 3D physics, to understand how things actually work under the hood...)

Upvotes: 1

Related Questions