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.
– SarperSHi 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.
– Viking1972I 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() )
– Viking1972