I am coding a script for a ship, and i’m not at all sure how to handle this part.

I want it so when the player tries to move forward (W key, or vertical input), the ship will gradually increase its speed to maxspeed without the need for the player to hold the button.

Pressing the S key will slowly stop the ship (again, without really needing to hold down the key) and move it in reverse if the button is held down.

Currently the script im writting is in JS.

Any advice or help would be wonderful

Hi,

Have you seen the Car Tutorial ?
In that sample, car moves when holding down the key.

Modify the logic by checking whether ‘W’/‘S’ key is pressed and apply Force accordingly instead of applying force on key press only.
Check the js script for car in the sample.

regards,anu

I’ll write you in C#, you can apply the logic, it’s just the same.

``````float vx = 0f;
float accelerationValue = 1f;
float deccelerationValue = 1f;

void Update()
{

if(W Pressed)
{
vx = vx + (accelerationValue * Time.DeltaTime);
}

if(S Pressed)
{
vx = vx - (deccelerationValue  * Time.DeltaTime);
}

shipObject.transform.position = new Vector3(shipObject.transform.position.x+vx, shipObject.transform.position.y, shipObject.transform.position.z);

}
``````

So what you need is a basic “State Machine” - see here for more details on what those are.

Basically the Update function of your script needs to be in one of several modes:

• Idle - speed is tending towards 0

• Moving - speed is tending towards maxspeed

• Reverse - speed is tending toward max reverse speed

``````enum ShipModes { Idle, Moving, Reverse };

var currentMode = ShipModes.Idle;
var currentSpeed = 0.0;
var maxSpeed = 5.0;
var maxReverseSpeed = -2.0;
``````

Then in your Update function you do different things depending on the mode:

``````     function Update() {

//Input phase split out - I like to do this but it's optional
switch(currentMode) {
case ShipModes.Idle:
if(Input.GetKeyDown(KeyCode.W)) {
currentMode = ShipModes.Moving;
}
if(Input.GetKeyDown(KeyCode.S)) {
currentMode = ShipModes.Reverse;
}
break;
case ShipModes.Moving:
if(Input.GetKeyDown(KeyCode.S)) {
currentMode = ShipModes.Idle;
}
break;
case ShipModes.Reverse:
if(!Input.GetKey(KeyCode.S)) {
currentMode = ShipModes.Idle;
}
break;
}

//Movement phase
switch(currentMode) {
case ShipModes.Idle:
currentSpeed = Mathf.Lerp(currentSpeed, 0, Time.deltaTime); //Or MoveTowards
break;
case ShipModes.Moving:
currentSpeed = Mathf.Lerp(currentSpeed, maxSpeed, Time.deltaTime); //Or MoveTowards
break;
case ShipModes.Reverse:
currentSpeed = Mathf.Lerp(currentSpeed, maxReverseSpeed, Time.deltaTime); //Or MoveTowards
break;
}

//Actually move
transform.position += transform.forward * currentSpeed * Time.deltaTime;

}
``````