Search Unity

Acceleration

Discussion in 'Scripting' started by PaxStyle, Jul 26, 2014.

  1. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    Hi! I've problem with set the acceleration in my script.
    I created a maxSpeed var, so that the speed should reach the max speed gradually. But ther's something wrong :D
    PS: i'm a beginner with scripting.
    PS I would like that If i press A or S everytime the acceleration is gradually, then it return to its value
    Thank you : )

    Code (CSharp):
    1. public float speed = 0;
    2.     public float maxSpeed = 10;
    3.     void Update () {
    4.         if(Input.GetKey(KeyCode.A) && transform.position.y < 1){
    5.             if (speed != maxSpeed) speed + 0.5;
    6.             transform.Translate(transform.up*speed*Time.deltaTime, Space.World);
    7.         }
    8.         if(Input.GetKey(KeyCode.S) && transform.position.y > -1){
    9.             if (speed != maxSpeed) speed + 0.5;
    10.             transform.Translate(-transform.up*speed*Time.deltaTime, Space.World);
    11.         }
    12.     }
     
    Last edited: Jul 27, 2014
  2. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
  3. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Okay, so what's acceleration?

    Acceleration is just the change in velocity over time.

    How fast do you want to be able to reach your max speed?

    Assuming your max speed for this example is 10, and you start at 0...

    I'm going to do an example that says you can go from 0-10 in 5 seconds...

    Your formula:

    A = final velocity - current velocity / time

    A = 10 - 0 / 5

    = 2 units/second to speed up.

    So for as long as you hold down the right key, you'll speed up by 2 units each second in the direction you're traveling.

    public float maxSpeed = 10;
    public float currentSpeed = 0;
    public float acceleration = 2;

    if (input.getkey(keycode.rigtharrow)
    {
    currentSpeed = currentSpeed + (acceleration * Time.deltaTime);

    if (currentSpeed >= maxSpeed)
    {
    currentSpeed = maxSpeed;
    }
    transform.Translate(new vector3(currentSpeed, 0, 0) * time.deltaTime);

    }

    It may be more accurate if you constantly calculate the acceleration too, but i think this will work fine.


    acceleration = maxSpeed - currenSpeed / 5;

    This should in hand return 2.0 every time. So just having 2 as the acceleration value is fine.
     
    Last edited: Jul 27, 2014
  4. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    This work, but on time that maxspeed has reach 10, it doesn't graduate the speed anymore.
    I would like that only when I press A or S the speed start gradually, but always with the same speed. Only the start should be graduated. Hope I have explained :)
     
  5. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Sorry, I don't quite understand. So you don't want the object to speed up over time?
     
  6. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    So, this script moves an object up and down, ok, but the movement when I press A or S is is jerky. The speed is correct so, but when the object start i don't like the jerky movement, but i would like a "soft" starting everytime I press the input keys. (A, S).. :D
     
  7. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Alright, you lost me. Paste your script. Let's take a look at what you currently have working with the new acceleration added.
     
  8. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    The script is this, I would like only a delicate start.. not jerky. I know that i've difficult with english, but it seems clear

    Code (CSharp):
    1. public float speed = 0;
    2.    
    3.     void Update () {
    4.         if(Input.GetKey(KeyCode.A) && transform.position.y < 1){
    5.            transform.Translate(transform.up*speed*Time.deltaTime, Space.World);
    6.         }
    7.         if(Input.GetKey(KeyCode.S) && transform.position.y > -1){
    8.            transform.Translate(-transform.up*speed*Time.deltaTime, Space.World);
    9.         }
    10.     }
     
  9. Macaberz

    Macaberz

    Joined:
    Jul 29, 2014
    Posts:
    3
    Hi @PaxStyle

    I am just going to show you my solution, then work you through the steps. It took me an embarrasing amount of time before I finally understood acceleration and velocity, so I know where you' re coming from!

    Anyway, this ought to do it:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class CubeController : MonoBehaviour {
    6.  
    7.     public float maxSpeed = 1f;
    8.     public float acceleration = 0.2f;
    9.     public float currentSpeed = 0f;
    10.  
    11.     void Start () {
    12.         acceleration *= Time.deltaTime;
    13.     }
    14.  
    15.     void Update() {
    16.  
    17.         if (Input.GetKey(KeyCode.A)) {
    18.             currentSpeed += acceleration;
    19.             transform.Translate(transform.up * currentSpeed, Space.World);
    20.         } else if (Input.GetKey(KeyCode.S)) {
    21.             currentSpeed += acceleration;
    22.             transform.Translate(-transform.up * currentSpeed, Space.World);
    23.         } else {
    24.             currentSpeed = 0;
    25.             //or, if you wish to de-accelerate:
    26.             //currentSpeed -= acceleration;
    27.         }
    28.         currentSpeed = Mathf.Clamp(currentSpeed,0f,maxSpeed);
    29.     }
    30. }
    31.  
    I just applied this CS script to a simple cube in the scene (GameObject -> Create Other -> Cube)

    Acceleration, as @SubZeroGaming pointed out, is the change in speed over time. Make sure you understand this before you go any further. If you sit in a car and hit the gas pedal, first the car moves slowly, then it accelerates (it moves faster, then faster still, then even faster).

    Alright, let's step through the code:

    Code (csharp):
    1.  
    2.     public float maxSpeed = 1f;
    3.     public float acceleration = 0.2f;
    4.     public float currentSpeed = 0f;
    5.  
    ^ We're just setting up our variables. We have a maximum speed of 1f (Unity world points, not pixels!), and with acceleration we say that we want to accelerate with 0.2f points every second. The important bit is every second. Keep this in mind. Lastly, we just have the current speed which is the speed the cube is currently travelling at (up initialization, it is 0).

    Code (csharp):
    1.  
    2. //calculates how many units we have to accelerate every Update() so that our acceleration over 1 second is 0.2
    3.   void Start () {
    4.         acceleration *= Time.deltaTime;
    5.     }
    6.  
    ^ This is a very important line of code. Remember how I said I wanted to move 0.2f every second?

    You' d say we could just add 0.2f to our speed in the Update() function, right?

    Wrong!

    The Update() function is called far more often than every second. Time.deltaTime tells you how much time has passed since the last call to Update(). By multiplying our desired acceleration per second (0.2) by the deltaTime we get how many units we have to move this update to have moved a total of 0.2 in a second. Remember, Update() gets called very often and so we just need to translate a tiny bit every update to get an overall smooth movement in a second.

    Code (csharp):
    1.  
    2.     void Update() {
    3.         if (Input.GetKey(KeyCode.A)) {
    4.             currentSpeed += acceleration;
    5.             transform.Translate(transform.up * currentSpeed, Space.World);
    6.  
    Alright, our currenSpeed grows (accelerates) by the acceleration. We were travelling at currentSpeed 0 at first, but now that has been increased to 0 + acceleration.

    Next, we translate our cube along the Y-axis. I noticed you used a vector here which is perfectly fine, but I get the feeling you may or may not really understand what you're doing here. In any case, it could also be written like this:

    Code (csharp):
    1.  
    2. transform.Translate(0,1 * currentSpeed, 0, Space.World);
    3.  
    That ^ does the exact same as when you're using transform.up

    Code (csharp):
    1.  
    2. currentSpeed = Mathf.Clamp(currentSpeed,0f,maxSpeed);
    3.  
    Lastly, that ^ simply makes sure that our currentSpeed never becomes less than 0 and never more than our maximum speed.

    Completely off topic, hi @SubZeroGaming! I am checking out your channel. I am new to Unity, but I've done my fair share of C# and Java. Your tutorials are quite helpful!
     
    Last edited: Jul 29, 2014
    PaxStyle and SubZeroGaming like this.
  10. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    Great reply, very helpful! thank you very much.
     
  11. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    I have applied the same method to another script, but here the speed seems 0.. the object doesn't move..

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Braccio : MonoBehaviour {
    5.  
    6.  
    7.     public GameObject[] arm;
    8.     public float maxSpeed = 10;
    9.     public float acceleration = 1;
    10.     public float currentSpeed = 0;
    11.     Vector3 StartPosition;
    12.  
    13.  
    14.     void Start()
    15.     {
    16.         acceleration *= Time.deltaTime;
    17.     }
    18.    
    19.     // Update is called once per frame
    20.     void Update () {
    21.  
    22.         //go up
    23.         if (Input.GetKey (KeyCode.Z)) {
    24.             currentSpeed += acceleration;
    25.             float currentAngle = transform.rotation.eulerAngles.x;
    26.             while (currentAngle < -180.0f)
    27.                 currentAngle += 360.0f;
    28.             while (currentAngle > 180.0f)
    29.                 currentAngle -= 360.0f;
    30.             Debug.Log ("currentAngle " + currentAngle);
    31.             float destinationAngle = currentAngle - Time.deltaTime * currentSpeed;
    32.             Debug.Log ("destinationAngle before clamp " + destinationAngle);
    33.             destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 0.0f);
    34.             Debug.Log ("destinationAngle after clamp " + destinationAngle);
    35.             float deltaAngle = destinationAngle - currentAngle;
    36.             transform.Rotate(Vector3.right, deltaAngle);
    37.            
    38.            
    39.            
    40.         }
    41.        
    42.         //go down
    43.         if (Input.GetKey (KeyCode.X)) {
    44.             currentSpeed += acceleration;
    45.             float currentAngle = transform.rotation.eulerAngles.x;
    46.             while (currentAngle < -180.0f)
    47.                 currentAngle += 360.0f;
    48.             while (currentAngle > 180.0f)
    49.                 currentAngle -= 360.0f;
    50.             Debug.Log ("currentAngle " + currentAngle);
    51.             float destinationAngle = currentAngle + Time.deltaTime * currentSpeed;
    52.             Debug.Log ("destinationAngle before clamp " + destinationAngle);
    53.             destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 0.0f);
    54.             Debug.Log ("destinationAngle after clamp " + destinationAngle);
    55.             float deltaAngle = destinationAngle - currentAngle;
    56.             transform.Rotate(Vector3.right, deltaAngle);
    57.         }
    58.  
    59.  
    60.         else {
    61.             currentSpeed = 0;
    62.             //or, if you wish to de-accelerate:
    63.             //currentSpeed -= acceleration;
    64.         }
    65.  
    66.         currentSpeed = Mathf.Clamp(currentSpeed,0f,maxSpeed);
    67.     }
    68. }
     
  12. Macaberz

    Macaberz

    Joined:
    Jul 29, 2014
    Posts:
    3
    Okay I haven' t tried this in Unity, but I am pretty sure the reason nothing is moving is because you don't try to move anything.

    In game design terms, movement = translation. Where is your call to transform.translate();? All I see is transform.rotate.

    In this case you forgot to code transform.Translate(); you need to add in into your existing script. It must go after the rotation code. There is a specific order of operations. It goes:

    1. Scale
    2. Rotate
    3. Translate

    source: http://gamedev.stackexchange.com/qu...ply-scale-rotation-and-translation-matrices-f

    Try this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Braccio : MonoBehaviour {
    5.  
    6.  
    7.     public GameObject[] arm;
    8.     public float maxSpeed = 10;
    9.     public float acceleration = 1;
    10.     public float currentSpeed = 0;
    11.     Vector3 StartPosition;
    12.  
    13.  
    14.     void Start()
    15.     {
    16.         acceleration *= Time.deltaTime;
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update () {
    21.  
    22.         //go up
    23.         if (Input.GetKey (KeyCode.Z)) {
    24.             currentSpeed += acceleration;
    25.             float currentAngle = transform.rotation.eulerAngles.x;
    26.             while (currentAngle < -180.0f)
    27.                 currentAngle += 360.0f;
    28.             while (currentAngle > 180.0f)
    29.                 currentAngle -= 360.0f;
    30.             Debug.Log ("currentAngle " + currentAngle);
    31.             float destinationAngle = currentAngle - Time.deltaTime * currentSpeed;
    32.             Debug.Log ("destinationAngle before clamp " + destinationAngle);
    33.             destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 0.0f);
    34.             Debug.Log ("destinationAngle after clamp " + destinationAngle);
    35.             float deltaAngle = destinationAngle - currentAngle;
    36.             transform.Rotate(Vector3.right, deltaAngle);
    37.            transform.Translate(transform.up * currentSpeed, Space.World);
    38.         }
    39.    
    40.         //go down
    41.         if (Input.GetKey (KeyCode.X)) {
    42.             currentSpeed += acceleration;
    43.             float currentAngle = transform.rotation.eulerAngles.x;
    44.             while (currentAngle < -180.0f)
    45.                 currentAngle += 360.0f;
    46.             while (currentAngle > 180.0f)
    47.                 currentAngle -= 360.0f;
    48.             Debug.Log ("currentAngle " + currentAngle);
    49.             float destinationAngle = currentAngle + Time.deltaTime * currentSpeed;
    50.             Debug.Log ("destinationAngle before clamp " + destinationAngle);
    51.             destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 0.0f);
    52.             Debug.Log ("destinationAngle after clamp " + destinationAngle);
    53.             float deltaAngle = destinationAngle - currentAngle;
    54.             transform.Rotate(Vector3.right, deltaAngle);
    55.             transform.Translate(-transform.up * currentSpeed, Space.World);
    56.         }
    57.  
    58.  
    59.         else {
    60.             currentSpeed = 0;
    61.             //or, if you wish to de-accelerate:
    62.             //currentSpeed -= acceleration;
    63.         }
    64.  
    65.         currentSpeed = Mathf.Clamp(currentSpeed,0f,maxSpeed);
    66.     }
    67. }
    All I did was add:

    Code (csharp):
    1.  
    2. ...
    3. transform.Translate(-transform.up * currentSpeed, Space.World);
    4. ...
    5.  
    and

    Code (csharp):
    1.  
    2. ...
    3. transform.Translate(transform.up * currentSpeed, Space.World);
    4. ...
    5.  
    EDIT: Again, I haven't tried your code yet, so I am not 100% sure how it works, but those while loops within the if statements look suspicious to me. Do you really need them?
     
    Last edited: Jul 29, 2014
  13. PaxStyle

    PaxStyle

    Joined:
    May 22, 2013
    Posts:
    63
    No it doesn't work. Now I show you the code without add the things that you said me before.
    So the code work, before, I tried to add your part of code and it doesn't work anymore.
    I can't edit this code because so is the only way to do what i would like. :)


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Braccio : MonoBehaviour {
    5.  
    6.  
    7.     public GameObject[] arm;
    8.    
    9.     public float speed;
    10.  
    11.     Vector3 StartPosition;
    12.  
    13.  
    14.  
    15.    
    16.     // Update is called once per frame
    17.     void Update () {
    18.  
    19.         //go up
    20.         if (Input.GetKey (KeyCode.Z)) {
    21.             float currentAngle = transform.rotation.eulerAngles.x;
    22.             while (currentAngle < -180.0f)
    23.                 currentAngle += 360.0f;
    24.             while (currentAngle > 180.0f)
    25.                 currentAngle -= 360.0f;
    26.             Debug.Log ("currentAngle " + currentAngle);
    27.             float destinationAngle = currentAngle - Time.deltaTime * speed;
    28.             Debug.Log ("destinationAngle before clamp " + destinationAngle);
    29.             destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 0.0f);
    30.             Debug.Log ("destinationAngle after clamp " + destinationAngle);
    31.             float deltaAngle = destinationAngle - currentAngle;
    32.             transform.Rotate(Vector3.right, deltaAngle);
    33.            
    34.            
    35.            
    36.         }
    37.        
    38.         //go down
    39.         if (Input.GetKey (KeyCode.X)) {
    40.             float currentAngle = transform.rotation.eulerAngles.x;
    41.             while (currentAngle < -180.0f)
    42.                 currentAngle += 360.0f;
    43.             while (currentAngle > 180.0f)
    44.                 currentAngle -= 360.0f;
    45.             Debug.Log ("currentAngle " + currentAngle);
    46.             float destinationAngle = currentAngle + Time.deltaTime * speed;
    47.             Debug.Log ("destinationAngle before clamp " + destinationAngle);
    48.             destinationAngle = Mathf.Clamp (destinationAngle, -50.0f, 0.0f);
    49.             Debug.Log ("destinationAngle after clamp " + destinationAngle);
    50.             float deltaAngle = destinationAngle - currentAngle;
    51.             transform.Rotate(Vector3.right, deltaAngle);
    52.         }
    53.     }
    54. }
     
  14. Mr_Kensho

    Mr_Kensho

    Joined:
    Feb 14, 2021
    Posts:
    1
    I am trying to accomplish something with acceleration, but over time without me pressing anything, lets say there is an enemy with a base speed of 2, but every time I (the player) reached certain amount of points in score, the enemy gain 0.50f of speed, then after another amount of points is reached then the another amount of speed is added to the enemy. Is there any way to make this possible?