How do I make a ship go forward and accelerating to a certain velocity ?

Hi

I’m trying to make a ship sail forward at different speeds, but I can’t figure out how to do that ?

My plan is to have four different velocities for my ship and a stop. The different velocities should be tied to five different keys on the keyboard:

  • (0) stop = 0
  • (1) 1/4 speed = 4
  • (2) 1/2 speed = 8
  • (3) 3/4 speed = 12
  • (4) maximum speed = 16

The ship should start to move forward as soon as I hit a certain key (it could be the “1” for 1/4 speed) and accelerate until it reaches the pre-dertermined velocity and then continue to go at this velocity until I choose another velocity or stop.

if I choose to another velocity or stop then the ship should decelerated until it reaches the pre-determined velocity.

I know how to make an object go forward as long as a key is pressed, but not how to make it continue to move once the key is not pressed anymore.

Would anyone please help me - a code example would be most welcome as long as it’s written in C#

1 Answer

1

Here is some quick code with some test values, play with them as you see fit. Hope it helps.

using UnityEngine;

internal sealed class SailControls : MonoBehaviour {
    private enum SailSpeedModes {
        Stop,
        QuarterSpeed,
        HalfSpeed,
        ThreeQuartersSpeed,
        FullSpeed
    }

    private SailSpeedModes currentSpeedMode;

    private const float maximumSpeed = 8f;

    private float currentSpeed;

    internal float CurrentSpeed {
        get { return currentSpeed; }
        set { currentSpeed = value; }
    }

    private float accelerationRate = 1.5f;

    internal float AccelerationRate {
        get { return accelerationRate; }
        set { accelerationRate = value; }
    }

    private void Update() {
        UpdateSpeedMode();
        UpdateCurrentSpeed(currentSpeedMode);
        Move();
    }

    private void UpdateSpeedMode() {
        if(Input.GetKey(KeyCode.Alpha0)) currentSpeedMode = SailSpeedModes.Stop;
        if(Input.GetKey(KeyCode.Alpha1)) currentSpeedMode = SailSpeedModes.QuarterSpeed;
        if(Input.GetKey(KeyCode.Alpha2)) currentSpeedMode = SailSpeedModes.HalfSpeed;
        if(Input.GetKey(KeyCode.Alpha3)) currentSpeedMode = SailSpeedModes.ThreeQuartersSpeed;
        if(Input.GetKey(KeyCode.Alpha3)) currentSpeedMode = SailSpeedModes.FullSpeed;
    }

    private void UpdateCurrentSpeed(SailSpeedModes speedMode) {
        switch(speedMode) {
            case SailSpeedModes.Stop:
                MoveSpeedTowards(0);
                break;
            case SailSpeedModes.QuarterSpeed:
                MoveSpeedTowards(maximumSpeed * 0.25f);
                break;
            case SailSpeedModes.HalfSpeed:
                MoveSpeedTowards(maximumSpeed * 0.5f);
                break;
            case SailSpeedModes.ThreeQuartersSpeed:
                MoveSpeedTowards(maximumSpeed * 0.75f);
                break;
            case SailSpeedModes.FullSpeed:
                MoveSpeedTowards(maximumSpeed);
                break;
        }
    }

    private void MoveSpeedTowards(float value) {
        while(Mathf.Abs(CurrentSpeed - value) > Mathf.Epsilon) {
            if(CurrentSpeed < value) CurrentSpeed += AccelerationRate * Time.deltaTime;
            else CurrentSpeed -= AccelerationRate * Time.deltaTime;
            break;
        }
    }

    private void Move() {
        if(CurrentSpeed < 0) {
            CurrentSpeed = 0;
            return;
        }

        transform.position += new Vector3(0f, 0f, CurrentSpeed * Time.deltaTime);
    }
}

You can also get rid of those properties and stick to the public variables if you don't want to spend time programming a custom inspector. But using properties instead of public variables is a golden C# rule due to many reasons like encapsulation, defensive programming, data binding to name just a few.

Hi Sarper Soher Thank you very much for taking your time to write the code - I look very much forward to give it a go. I hope many others will both benefit and save themselves headache and frustration when they have this code.

I have hit a small problem with this script ! The problem is not in the functionality as it does what it is supposed to - the problem is that I'm not really sure (due to lack of knowledge) where the initialization is taking place (the start function() )