Search Unity

influence course of a ship moved with AddForce by its rotation

Discussion in 'Scripting' started by Hubardo, Jul 27, 2015.

  1. Hubardo

    Hubardo

    Joined:
    Apr 2, 2015
    Posts:
    22
    beginner here, im sure there is a lot wrong with my code, but im trying to learn the hard way.

    i made a simple script to add speed to a player ship when 'forward' is pressed (up to 3 levels of speed)
    problem is my ship will always move "forward" relative to where its facing the moment force is added
    what i want is the rotation of the ship to affect its 'course' whenever it is rotated.

    here is my script

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerController : MonoBehaviour
    5. {
    6.     public float thrust;
    7.     public float reverseThrust;
    8.     public Rigidbody rb;
    9.     private int maxThrustLvl;
    10.     public float rotationSpeed = 100.0F;
    11.  
    12.     // Use this for initialization
    13.     void Start ()
    14.     {
    15.         maxThrustLvl = 0;
    16.         rb = GetComponent<Rigidbody>();
    17.     }
    18.    
    19.     // Update is called once per frame
    20.     void Update ()
    21.     {
    22.  
    23.         if (Input.GetButtonDown("Vertical") && Input.GetAxisRaw("Vertical") > 0)
    24.         {
    25.             if (maxThrustLvl < 3)
    26.                 {
    27.                 rb.AddForce(transform.forward * thrust);
    28.                 maxThrustLvl = maxThrustLvl + 1;
    29.                 }
    30.         }
    31.  
    32.         if (Input.GetButtonDown("Vertical") && Input.GetAxisRaw("Vertical") < 0)
    33.         {
    34.             if (maxThrustLvl > -3)
    35.             {
    36.                 rb.AddForce(transform.forward * reverseThrust);
    37.                 maxThrustLvl = maxThrustLvl - 1;
    38.             }
    39.         }
    40.  
    41.         float rotation = Input.GetAxis("Horizontal") * rotationSpeed;
    42.         rotation *= Time.deltaTime;
    43.         transform.Rotate(0, rotation, 0);
    44.  
    45.     }
    46. }
    47.  
     
  2. Hubardo

    Hubardo

    Joined:
    Apr 2, 2015
    Posts:
    22
    sorry to bump but i have been trying to figure this out all day with no luck
    would really appreciate any tips
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    Your script is working fine: absent other forces, a rigidbody will continue moving in the direction it was moved in, regardless of which way it is pointed. It isn't really an "arrow" per se.

    I modified it (it is now called PC2) to make the spaceship move in the direction you point it, more like a car.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. // more like a car behavior really...
    5. public class PC2 : MonoBehaviour
    6. {
    7.     public float baseSpeed;
    8.     Rigidbody rb;
    9.     int CurrentSpeed; //  was: maxThrustLvl;
    10.     public float rotationSpeed = 100.0F;
    11.  
    12.     // Use this for initialization
    13.     void Start ()
    14.     {
    15.         CurrentSpeed = 0;
    16.         rb = GetComponent<Rigidbody>();
    17.     }
    18.  
    19.     // Update is called once per frame
    20.     void Update ()
    21.     {
    22.      
    23.         if (Input.GetButtonDown("Vertical") && Input.GetAxisRaw("Vertical") > 0)
    24.         {
    25.             if (CurrentSpeed < 3)
    26.             {
    27.                 CurrentSpeed = CurrentSpeed + 1;
    28.             }
    29.         }
    30.      
    31.         if (Input.GetButtonDown("Vertical") && Input.GetAxisRaw("Vertical") < 0)
    32.         {
    33.             if (CurrentSpeed > -3)
    34.             {
    35.                 CurrentSpeed = CurrentSpeed - 1;
    36.             }
    37.         }
    38.      
    39.         float rotation = Input.GetAxis("Horizontal") * rotationSpeed;
    40.         rotation *= Time.deltaTime;
    41.         transform.Rotate(0, rotation, 0);
    42.  
    43.         transform.position += transform.forward * CurrentSpeed * baseSpeed * Time.deltaTime;
    44.     }
    45. }
    46.  
    47.  
    HOWEVER, if you want it to move more like a spaceship, try this script (PC3), but you must use MUCH SMALLER thrust values, because it will continue applying the current thrust kind of like an engine that has been turned on between -3 and 3 power, if that makes sense.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. // engine remains on (between -3 and 3 value) pushing you all the time,
    6. // so you must use much smaller values of thrust
    7.  
    8. public class PC3 : MonoBehaviour
    9. {
    10.     public float thrust;
    11.     Rigidbody rb;
    12.     private int maxThrustLvl; //  was: maxThrustLvl;
    13.     public float rotationSpeed = 100.0F;
    14.  
    15.     // Use this for initialization
    16.     void Start ()
    17.     {
    18.         maxThrustLvl = 0;
    19.         rb = GetComponent<Rigidbody>();
    20.     }
    21.  
    22.     // Update is called once per frame
    23.     void Update ()
    24.     {
    25.      
    26.         if (Input.GetButtonDown("Vertical") && Input.GetAxisRaw("Vertical") > 0)
    27.         {
    28.             if (maxThrustLvl < 3)
    29.             {
    30.                 maxThrustLvl = maxThrustLvl + 1;
    31.             }
    32.         }
    33.      
    34.         if (Input.GetButtonDown("Vertical") && Input.GetAxisRaw("Vertical") < 0)
    35.         {
    36.             if (maxThrustLvl > -3)
    37.             {
    38.                 maxThrustLvl = maxThrustLvl - 1;
    39.             }
    40.         }
    41.      
    42.         float rotation = Input.GetAxis("Horizontal") * rotationSpeed;
    43.         rotation *= Time.deltaTime;
    44.         transform.Rotate(0, rotation, 0);
    45.  
    46.         rb.AddForce( transform.forward * maxThrustLvl);
    47.     }
    48. }
    49.  
    50.  
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    As an addendum to all of this, your Update() function should really be a FixedUpdate() function since it acts upon physics objects. My bad. If you tried to parent a camera to your spaceship, it would probably jitter horribly because we're not using FixedUpdate(). But the basic physics lesson remains.

    BTW, PC2 does not really even NEED the rigidbody. The code is actually moving the transform based on speed every frame, based on which way it is pointed.
     
  5. Hubardo

    Hubardo

    Joined:
    Apr 2, 2015
    Posts:
    22
    thanks for the help Kurt

    your first script is more like what i had in mind, should have mentioned the kind of ship im talking about is less of the space kind and more the water kind :) a boat if you will.

    as far as i can tell, its that last line that takes care of the moving direction, care to give me a little more detail on what you did there?

    and in any case, would you say that going the rigidbody/addForce route wouldnt be needed/smart?
    and just out of curiosity, this same outcome or close to it cant be achieved using rigidbody and addforce?

    thanks again
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,697
    Yeah, that last line was manually updating the position. It does this by moving the current position of the object explicitly by the amount of the speed, turned in the direction of our current .forward vector, multiplied of course by .deltaTime.

    There are a few different reasons to use a RigidBody: one is if you want the object to maintain an internal notion of its momentum (linear and rotational) over time and to update its position in the world, respond to gravity, etc. That's the usual type of RB and I call this loosely the "ballistic" function.

    The other reason is if you want a kinematic RigidBody which is for doing things like platforms, where other actors need to interact with it and stand on it, etc.

    You also might want a RigidBody if you are interested in that particular object receiving collision and trigger events when it enters other colliders, and of course if you are using the RB for its ballistic properties, to bounce and/or react to collisions.
     
  7. Hubardo

    Hubardo

    Joined:
    Apr 2, 2015
    Posts:
    22
    gotcha, well, thanks for the explanation there, im still not 100% sure if i want this to be a rigidbody or not, for now ill continue with a non RB boat, cross the bridge when we get to it.