got a simple 3 intervals forward engine script
i want it to accelerate between each interval instead of instantly changing to the next speed level
how would i go about it with the existing code?
heres the script
using UnityEngine;
using System.Collections;
public class ForwardAccel : MonoBehaviour
{
private float baseSpeed = 5.0f;
int enginePower;
// Use this for initialization
void Start ()
{
enginePower = 0;
}
// Update is called once per frame
void Update ()
{
if (Input.GetButtonDown("Vertical") && Input.GetAxisRaw("Vertical") > 0)
{
if (enginePower < 3)
{
enginePower = enginePower + 1;
}
}
transform.position += transform.forward * enginePower * baseSpeed * Time.deltaTime;
}
}
You could build a delay into the update which would essentially log the time (Time.time) that the change in power occurs. Then, you’d put in a conditional that says the enginePower can only increase if(Time.Time >= lastChangeTime + 3f) or something. If you want to make it so that the power can be changed at any time, but that change can’t be FELT until a certain timer has passed, separate out the input from the change like this:
using UnityEngine;
using System.Collections;
public class ForwardAccel : MonoBehaviour
{
private float baseSpeed = 5.0f;
private float gearChangeDelay;
private float lastPowerChange;
private int curPower;
private int desiredPower;
void Start ()
{
gearChangeDelay = 3f;
lastPowerChange = Time.time - 5f;
desiredPower = 0;
curPower = 0;
}
void Update ()
{
if (Input.GetButtonDown("Vertical"))
{
int direction = 1;
if(Input.GetAxisRaw("Vertical") < 0)
direction = -1;
int newPower = desiredPower + direction;
if (newPower >= 0 && newPower <= 2)
{
desiredPower = newPower;
}
}
if(desiredPower != curPower && Time.time >= lastPowerChange + gearChangeDelay)
{
lastPowerChange = Time.time;
if(desiredPower > curPower)
curPower += 1;
else
curPower -= 1;
}
transform.position += transform.forward * curPower * baseSpeed * Time.deltaTime;
}
}
Something like that?
hi Lysander
thanks for the help but im either missing something or you misunderstood me
all this did as far as i can tell is add an input delay in the transitions between the first to second and second to third power levels
i was looking for a way to accelerate between power levels, so instead of going 1 to 2, it will go 1 to 1.1 to 1.2 etc…
also im a total beginner so i would like to understand my script for learning purposes and not just copy/paste, and your modified script is fairly different then mine
I see, I misunderstood the problem indeed, in spectacular fashion!
In order to set a smaller interval, just make enginePower into a float instead of an integer (floats can handle floating-point values, in other words decimal points). Once you’ve done that, you can change the “enginePower = enginePower +1;” to increase by .1, or less, instead.
You’ll have to change the integers you’re assigning to the enginePower variable to be floats instead as well, in C# at least. You can do this by just adding an “f” to the end of the numbers. For instance, 0f instead of 0, .1f instead of .1, etc…

i tried floats before, but its not exactly what im after.
i DO want the power to increase by 1 every time the button is pressed, just not at once
lets say im at 0 power and i press the forward button, now im at 1 power but i want the object to have a period of time it is accelerating to the current level, and the same if i press the button three times in a row, now im at 3 power, but my object should slowly accelerate from 0 to 3
I know you said you didn’t want to copy/paste, but this is some fairly complicated logic, so forgive me but I’m going to post (commented, this time) one method for doing what you want. I really couldn’t come up with a way to explain this that wasn’t going to be horribly confusing, so:
using UnityEngine;
using System.Collections;
public class ForwardAccel : MonoBehaviour
{
private float baseSpeed = 5.0f; //mutliplier for total speed
private float curPower = 0f; //the power we have
private int desiredPower = 0; //the power we want
private float changeIncrement = 1f; //multiplier for how fast to adjust speed changes
void Update()
{
//if we're pressing up or down
if (Input.GetButtonDown("Vertical"))
{
//default direction is positive (up)
int direction = 1;
//if we're pressing down instead, flip it to negative
if (Input.GetAxisRaw("Vertical") < 0)
direction = -1;
//add the change (based on direction) to the old power value, temporarily
int newPower = desiredPower + direction;
//if we're within a set bounds (0 to 2), make the change "real"
if (newPower >= 0 && newPower <= 2)
{
desiredPower = newPower;
}
}
//we modify the increment by the time the last frame took to process
//this makes the change smoother using real-time
float adjustedIncrement = changeIncrement * Time.deltaTime;
//if the power we want is more than the power we have
if (curPower <= desiredPower - adjustedIncrement)
{
curPower += adjustedIncrement;
}
//if the power we want is less than the power we have
else if (curPower >= desiredPower + adjustedIncrement)
{
curPower -= adjustedIncrement;
}
else
{
//match the desired speed exactly
curPower = desiredPower;
}
transform.position += transform.forward * curPower * baseSpeed * Time.deltaTime;
}
}
thanks a bunch, this is very helpful, the comments are awsome
i admit i expected a much simpler addition to my code, and hopefully something i could easily implement in other parts of my script, but ill get there first
it sorta accomplishes what im after
but ill have to take some time breaking it down and understanding it, will post if i need any more advice on this matter
The relevant process (slowly adjusting to match a goal number) only relies on 3 parts: a starting point (the current value), an ending point (the goal value), and an increment. Keeping that in mind, and using those 3 things as parameters, you can make a new function and just copy the entire part of the script in update that deals with slowly adjusting time over into that function, then just change the names to match some parameter names, like so:
public float IncrementValue(float current, float goal, float increment)
{
float adjustedIncrement = increment * Time.deltaTime;
if (current <= goal- adjustedIncrement)
{
current += adjustedIncrement;
}
else if (current >= goal + adjustedIncrement)
{
current -= adjustedIncrement;
}
else
{
current = goal;
}
return current;
}
This would then be re-usable in your code elsewhere if needed. You can also look at Lerp and MoveTowards and SmoothStep and SmoothDamp, now that you see more or less how they work.
@DonLoquacious
hi again 
so, i was messing around with this script a little further, added rotation based on my speed and such
now i have a problem and im not sure where it originates
basically, all is working as intended for now, the faster i go the slower i rotate, while the fastest rotation speed is at power level 1 and dropping as it goes from 1 to 3, so besides while being stationarey, at power 3 it turns the slowest .
the problem is that once i get to power level 3 and then decelerate, my rotation speed no longer acts as it should, its subtle but noticeable, if i go from 3 to 1 and back to 3 then my turn speed would be faster than it should.
any ideas what i am missing? tried debuging some of the values and i cant find the culprit
if anyone beside Lysander has a clue it would be welcome as well
here is the complete script (forgive the unoptimized mess, still learning :))
EDIT found the little bugger
it was caused by my reverse state, once i pressed down it was set to true and stayed true even after pressing up
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
public float baseSpeed = 1.0f; //mutliplier for total speed
private float currentPower = 0f; //the power we have
private int desiredPower = 0; //the power we want
private float changeIncrement = 0.5f; //multiplier for how fast to adjust speed changes
public float rotationSpeed = 50.0F;
private float stationaryRotationSpeed = 10.0f;
private bool reverseState = false;
// Use this for initialization
void Start ()
{
currentPower = 0f;
}
void Update()
{
// Vertical Input
if (Input.GetButtonDown("Vertical"))
{
// Vertical UP
int direction = 1;
// Vertical DOWN
if (Input.GetAxisRaw("Vertical") < 0)
direction = -1;
if (direction == -1){
reverseState = true;
}
// Add input value to newPower
int newPower = desiredPower + direction;
// check if newPower is no bigger than 3 and no smaller than -1
if (newPower >= 0 && newPower <= 3)
{
desiredPower = newPower;
}
if (newPower < 0 && newPower >= -1)
{
desiredPower = newPower;
}
}
//Turning boat ""BUG : Rot Speed is wrong after deccelerating and accelreating back""
// use stationaryRotationSpeed if power is 0
if (currentPower == 0f) {
float rotation = Input.GetAxis ("Horizontal") * stationaryRotationSpeed;
rotation *= Time.deltaTime;
transform.Rotate (0, rotation, 0);
}
// when power is between 0 and 1, the rotation speed goes from lowest (stationary) to highest (power = 1)
else if (currentPower > 0f)
if (currentPower < 1f) {
float stationaryToRotSpeed = rotationSpeed * currentPower;
// limit the minimum rotation speed to stationaryRotationSpeed
if (stationaryToRotSpeed <= stationaryRotationSpeed) {
stationaryToRotSpeed = stationaryRotationSpeed;
}
float rotation = Input.GetAxis ("Horizontal") * stationaryToRotSpeed;
rotation *= Time.deltaTime;
transform.Rotate (0, rotation, 0);
}
// rotation speed at its highest at power lvl-1
else if (currentPower == 1f) {
float rotation = Input.GetAxis ("Horizontal") * rotationSpeed;
rotation *= Time.deltaTime;
transform.Rotate (0, rotation, 0);
}
// rotation speed drops relative to how fast the boat is going (only beyond PwrLvl-1)
else if (currentPower > 1f) {
float rotation = Input.GetAxis ("Horizontal") * rotationSpeed / currentPower;
rotation *= Time.deltaTime;
transform.Rotate (0, rotation, 0);
}
// reverse rotation
if (reverseState == true)
{
float rotation = Input.GetAxis ("Horizontal") * stationaryRotationSpeed;
rotation *= Time.deltaTime;
transform.Rotate (0, rotation, 0);
}
//we modify the increment by the time the last frame took to process
//this makes the change smoother using real-time
float adjustedIncrement = changeIncrement * Time.deltaTime;
//if the power we want is more than the power we have
if (currentPower <= desiredPower - adjustedIncrement)
{
currentPower += adjustedIncrement;
}
//if the power we want is less than the power we have
else if (currentPower >= desiredPower + adjustedIncrement)
{
currentPower -= adjustedIncrement;
}
else
{
//match the desired speed exactly
currentPower = desiredPower;
}
transform.position += transform.forward * currentPower * baseSpeed * Time.deltaTime;
}
}
Glad you found it! Debugging is fun, eh?
it could be if i knew how to do it correctly 
i actually couldnt find any problems with any of the values using Debug.Log, then, out of frustration i started manually debugging, systematically commenting out each section of the script until i found the culprit.
and since you asked, for the future, is this a reasonable process to go through when such problems arise? i really just did what seems logical to me
Yes, that’s fine. For better/easier control you can look into breakpoints and tracepoints though, which will allow you to see all of the values of all variables when a certain point in the code is reached. Here’s an excellent article on it, and proof that the Unity staff should go back to writing real tutorials instead of those silly semi-promotional videos they’ve been doing (you can’t “search” through a video, after all). That’s for Mono, but there’s breakpoints (and more importantly tracepoints, which allow an action to be performed just before the break) in Visual Studio as well- or at least the pro version. You should definitely look into it, as it’ll make more difficult-to-find bugs far far easier to locate.
Very happy to know such a thing exists, that’s awesome.
cant wait for some high level bug hunting 