Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Character Controller Jetpack

Discussion in 'Scripting' started by Keemo, Apr 22, 2014.

  1. Keemo

    Keemo

    Joined:
    Apr 22, 2014
    Posts:
    31
    Hello everyone,

    im currently trying to create a jetpack script for my character controller. I just want to press for example "e" and start to fly. But the thing is that i want it to be a bit realistic. So for example when im falling and press "e" it takes a bit time until i start to move in the y direction.
    Is it even possible? An advice would be great.
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,377
    Apply movement as an acceleration.

    Every update you record the velocity after a move, the next move you add to that old velocity for the new move instead of setting it to the velocity. This allows the change to take time to get applied.

    Code (csharp):
    1.  
    2. public float JetpackAcceleration = 1.0f; //accelerates 1 unit per second, per second
    3. public float MaxJetpackVelocity = 5.0f;
    4.  
    5. private Vector3 _lastVel;
    6. private CharacterController _controller;
    7.  
    8. void Awake()
    9. {
    10.     _controller = this.GetComponent<CharacterController>();
    11. }
    12.  
    13. void Update()
    14. {
    15.     Vector3 mv = _lastVel;
    16.     if(Input.GetKey(KeyCode.E))
    17.     {
    18.         mv.y += JetpackAcceleration * Time.deltaTime; //the acceleration happens over a duration
    19.     }
    20.     if (mv.y > MaxJetpackVelocity) mv.y = MaxJetpackVelocity; //clamp the velocity
    21.    
    22.     //... do other movement stuff, like gravity and the sort... note jetpack acceleration has to be GREATER than grav, OR you have to NOT apply gravity while pressing E
    23.    
    24.     _controller.Move(mv * Time.deltaTime); //move is done over a duration as well
    25.     _lastVel = _controller.velocity; //velocity property of CharacterController is the velocity after 'Move' is called
    26. }
    27.  
    Note, this is a very simple setup, you'll have to add more to it to get it fully working. But this gives you a starting point to work with.
     
    Last edited: Apr 22, 2014
  3. Keemo

    Keemo

    Joined:
    Apr 22, 2014
    Posts:
    31
    Okay i added now one line and now i looks like this(btw. i used FixedUpdate because it wasnt that jerky) :
    Code (csharp):
    1.  
    2.         Vector3 mv = _lastVel;
    3.         if (Input.GetKey(KeyCode.E))
    4.         {
    5.             mv.y += JetpackAcceleration * Time.deltaTime; //the acceleration happens over a duration
    6.  
    7.             if (mv.y > MaxJetpackVelocity) mv.y = MaxJetpackVelocity; //clamp the velocity
    8.             {
    9.                 mv.y -= Physics.gravity.y * Time.deltaTime;
    10.                 //... do other movement stuff, like gravity and the sort... note jetpack acceleration has to be GREATER than grav, OR you have to NOT apply gravity while pressing
    11.                 _controller.Move(mv * Time.deltaTime); //move is done over a duration as well
    12.                 _lastVel = _controller.velocity; //velocity property of CharacterController is the velocity after 'Move' is called
    13.             }
    14.         }
    15.  
    16.     }
    It works exactly one time. If i press the first time E is works but its very jerky, so how do i get it more smooth. And when i press E the second time ,i just fly in the air in warp speed.
    This velocity stuff is very new to me so sorry if i did it completely wrong, but if i did a explanation would be great.

    Edit: Its no longer Jerky i did a mistake with the "JetpackAcceleration". Only when im falling its now a lil bit jerky. So my only problem now is that it only works one time.
     
    Last edited: Apr 23, 2014
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,377
    Note that in your code, you only Move IF the E key is being pressed, and not always. This means that your controller won't fall back down from gravity otherwise.

    Also you put brackets around your code after the clamping of the velocity:

    Code (csharp):
    1.  
    2.             if (mv.y > MaxJetpackVelocity) mv.y = MaxJetpackVelocity; //clamp the velocity
    3.             {
    4.                 mv.y -= Physics.gravity.y * Time.deltaTime;
    5.                 //... do other movement stuff, like gravity and the sort... note jetpack acceleration has to be GREATER than grav, OR you have to NOT apply gravity while pressing
    6.                 _controller.Move(mv * Time.deltaTime); //move is done over a duration as well
    7.                 _lastVel = _controller.velocity; //velocity property of CharacterController is the velocity after 'Move' is called
    8.             }
    9.  
    I'm not sure why you did this, but that's some malformed code right there, and I bet a lot of problems are going to come out of that.

    Try something more like:

    Code (csharp):
    1.  
    2. Vector3 mv = _lastVel;
    3. if(Input.GetKey(KeyCode.E))
    4. {
    5.     mv.y += JetpackAcceleration * Time.deltaTime; //the acceleration happens over a duration
    6. }
    7. if (mv.y > MaxJetpackVelocity)
    8. {
    9.     //I added in the brackets around here, so you can see what this if statement was meant for.
    10.     //I left them out as a shorthanded one line if statement in my previous example
    11.     mv.y = MaxJetpackVelocity; //clamp the velocity
    12. }
    13.  
    14. mv.y -= Physics.gravity.y * Time.deltaTime;
    15. _controller.Move(mv * Time.deltaTime);
    16. _lastVel = _controller.velocity;
    17.  
    As an added example, here's how I would do it if I wanted to completely turn off gravity while jetpacking. Note how I don't apply gravity if E is pressed.

    Code (csharp):
    1.  
    2. Vector3 mv = _lastVel;
    3. if(Input.GetKey(KeyCode.E))
    4. {
    5.     mv.y += JetpackAcceleration * Time.deltaTime; //the acceleration happens over a duration
    6.     if (mv.y > MaxJetpackVelocity)
    7.     {
    8.         mv.y = MaxJetpackVelocity; //clamp the velocity
    9.     }
    10. }
    11. else
    12. {
    13.     mv.y -= Physics.gravity.y * Time.deltaTime;
    14. }
    15.  
    16. _controller.Move(mv * Time.deltaTime);
    17. _lastVel = _controller.velocity;
    18.  
     
    Last edited: Apr 23, 2014
  5. Aaryaman1211

    Aaryaman1211

    Joined:
    Oct 9, 2020
    Posts:
    1
    i want to keeep gravity low while he is falling what should I do
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,498
    Please don't reply to old threads. Start your own new thread, it's FREE!!

    To the question, take a look through the physics (or physics2D) setup area to see how gravity can be specified, IF you are using the in-built physics / physics2d gravity.

    If you're not using gravity, then you are either implementing gravity yourself, in which case use a smaller value, or you are using something such a
    ConstantForce
    component, in which case... use a smaller value for the force.

    Here's my jetpack game: