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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Unity 5, Standard asset, RigidBodyFPSController, do Mid air Jumps [Answered]

Discussion in 'Scripting' started by createasaurus, Aug 13, 2015.

  1. createasaurus

    createasaurus

    Joined:
    Sep 20, 2013
    Posts:
    9
    Hello,

    I would like to make the Unity 5, Standard asset, RigidBodyFPSController, do Mid air Jumps. Imagine you are flapping your wings, so you can just keep jumping without ever needing to touch the ground.

    I am brand new to coding. I have been trying to study the script: I've been looking for is_grounded statements, cuting and pasting things, changing falses to trues. Really, I'm randomly throwing darts... and the result is I just keep breaking the script.

    Thank you so much for any help with this.
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    this is psuedo code so it's not going to work if you copy it, it's just intended to show you where things need to go. I've assumed you don't have infinite mid air jumps.

    Code (csharp):
    1.  
    2. ///////// psuedo /////////
    3. private int midAirJumpRemaining;
    4. public int maxMidAirJump;
    5.  
    6. void FixedUpdate()
    7. {
    8.     // what to do if we are on the ground
    9.     if(grounded)
    10.     {
    11.         // reset mid air jump count
    12.         midAirJumpRemaining = maxMidAirJump;
    13.         if(jump input)
    14.         {
    15.             //do normal jump stuff
    16.         }
    17.     }
    18.     // what to do if we're not on the ground
    19.     else
    20.     {
    21.         if(jump input)
    22.         {
    23.             // if we have some mid air jumps left
    24.             if(midAirJumpRemaining > 0)
    25.             {
    26.                 // do mid air jump stuff
    27.                 midAirJumpRemaining -= 1;
    28.             }
    29.             // else => we aren't on the ground but have no jumps left.... do nothing
    30.         }
    31.     }
    32. }
    33.  
     
  3. createasaurus

    createasaurus

    Joined:
    Sep 20, 2013
    Posts:
    9
    Thank you LeftyRighty.

    My truest apologies, I actually do need infinite jumps. One problem is the script provided by Unity is very long, and uses terms I'm not familiar with. I've been trying to copy and paste the add force into the mid air check section... only I can't really read/write the code well enough to do this without breaking the script. Here is the whole code from Unity, note it is long.

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using UnityStandardAssets.CrossPlatformInput;
    5.  
    6. namespace UnityStandardAssets.Characters.FirstPerson
    7. {
    8.     [RequireComponent(typeof (Rigidbody))]
    9.     [RequireComponent(typeof (CapsuleCollider))]
    10.     public class RigidbodyFirstPersonController : MonoBehaviour
    11.     {
    12.         [Serializable]
    13.         public class MovementSettings
    14.         {
    15.             public float ForwardSpeed = 8.0f;   // Speed when walking forward
    16.             public float BackwardSpeed = 4.0f;  // Speed when walking backwards
    17.             public float StrafeSpeed = 4.0f;    // Speed when walking sideways
    18.             public float RunMultiplier = 2.0f;   // Speed when sprinting
    19.            public KeyCode RunKey = KeyCode.LeftShift;
    20.             public float JumpForce = 30f;
    21.             public AnimationCurve SlopeCurveModifier = new AnimationCurve(new Keyframe(-90.0f, 1.0f), new Keyframe(0.0f, 1.0f), new Keyframe(90.0f, 0.0f));
    22.             [HideInInspector] public float CurrentTargetSpeed = 8f;
    23.  
    24. #if !MOBILE_INPUT
    25.             private bool m_Running;
    26. #endif
    27.  
    28.             public void UpdateDesiredTargetSpeed(Vector2 input)
    29.             {
    30.                if (input == Vector2.zero) return;
    31.                 if (input.x > 0 || input.x < 0)
    32.                 {
    33.                     //strafe
    34.                     CurrentTargetSpeed = StrafeSpeed;
    35.                 }
    36.                 if (input.y < 0)
    37.                 {
    38.                     //backwards
    39.                     CurrentTargetSpeed = BackwardSpeed;
    40.                 }
    41.                 if (input.y > 0)
    42.                 {
    43.                     //forwards
    44.                     //handled last as if strafing and moving forward at the same time forwards speed should take precedence
    45.                     CurrentTargetSpeed = ForwardSpeed;
    46.                 }
    47. #if !MOBILE_INPUT
    48.                if (Input.GetKey(RunKey))
    49.                {
    50.                    CurrentTargetSpeed *= RunMultiplier;
    51.                    m_Running = true;
    52.                }
    53.                else
    54.                {
    55.                    m_Running = false;
    56.                }
    57. #endif
    58.             }
    59.  
    60. #if !MOBILE_INPUT
    61.             public bool Running
    62.             {
    63.                 get { return m_Running; }
    64.             }
    65. #endif
    66.         }
    67.  
    68.  
    69.         [Serializable]
    70.         public class AdvancedSettings
    71.         {
    72.             public float groundCheckDistance = 0.01f; // distance for checking if the controller is grounded ( 0.01f seems to work best for this )
    73.             public float stickToGroundHelperDistance = 0.5f; // stops the character
    74.             public float slowDownRate = 20f; // rate at which the controller comes to a stop when there is no input
    75.             public bool airControl; // can the user control the direction that is being moved in the air
    76.         }
    77.  
    78.  
    79.         public Camera cam;
    80.         public MovementSettings movementSettings = new MovementSettings();
    81.         public MouseLook mouseLook = new MouseLook();
    82.         public AdvancedSettings advancedSettings = new AdvancedSettings();
    83.  
    84.  
    85.         private Rigidbody m_RigidBody;
    86.         private CapsuleCollider m_Capsule;
    87.         private float m_YRotation;
    88.         private Vector3 m_GroundContactNormal;
    89.         private bool m_Jump, m_PreviouslyGrounded, m_Jumping, m_IsGrounded;
    90.  
    91.  
    92.         public Vector3 Velocity
    93.         {
    94.             get { return m_RigidBody.velocity; }
    95.         }
    96.  
    97.         public bool Grounded
    98.         {
    99.             get { return m_IsGrounded; }
    100.         }
    101.  
    102.         public bool Jumping
    103.         {
    104.             get { return m_Jumping; }
    105.         }
    106.  
    107.         public bool Running
    108.         {
    109.             get
    110.             {
    111. #if !MOBILE_INPUT
    112.                 return movementSettings.Running;
    113. #else
    114.                return false;
    115. #endif
    116.             }
    117.         }
    118.  
    119.  
    120.         private void Start()
    121.         {
    122.             m_RigidBody = GetComponent<Rigidbody>();
    123.             m_Capsule = GetComponent<CapsuleCollider>();
    124.             mouseLook.Init (transform, cam.transform);
    125.         }
    126.  
    127.  
    128.         private void Update()
    129.         {
    130.             RotateView();
    131.  
    132.             if (CrossPlatformInputManager.GetButtonDown("Jump") && !m_Jump)
    133.             {
    134.                 m_Jump = true;
    135.             }
    136.         }
    137.  
    138.  
    139.         private void FixedUpdate()
    140.         {
    141.             GroundCheck();
    142.             Vector2 input = GetInput();
    143.  
    144.             if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && (advancedSettings.airControl || m_IsGrounded))
    145.             {
    146.                 // always move along the camera forward as it is the direction that it being aimed at
    147.                 Vector3 desiredMove = cam.transform.forward*input.y + cam.transform.right*input.x;
    148.                 desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).normalized;
    149.  
    150.                 desiredMove.x = desiredMove.x*movementSettings.CurrentTargetSpeed;
    151.                 desiredMove.z = desiredMove.z*movementSettings.CurrentTargetSpeed;
    152.                 desiredMove.y = desiredMove.y*movementSettings.CurrentTargetSpeed;
    153.                 if (m_RigidBody.velocity.sqrMagnitude <
    154.                     (movementSettings.CurrentTargetSpeed*movementSettings.CurrentTargetSpeed))
    155.                 {
    156.                     m_RigidBody.AddForce(desiredMove*SlopeMultiplier(), ForceMode.Impulse);
    157.                 }
    158.             }
    159.  
    160.             if (m_IsGrounded)
    161.             {
    162.                 m_RigidBody.drag = 5f;
    163.  
    164.                 if (m_Jump)
    165.                 {
    166.                     m_RigidBody.drag = 0f;
    167.                     m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
    168.                     m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
    169.                     m_Jumping = true;
    170.                 }
    171.  
    172.                 if (!m_Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f)
    173.                 {
    174.                     m_RigidBody.Sleep();
    175.                 }
    176.             }
    177.             else
    178.             {
    179.                 m_RigidBody.drag = 0f;
    180.                 if (m_PreviouslyGrounded && !m_Jumping)
    181.                 {
    182.                     StickToGroundHelper();
    183.                 }
    184.             }
    185.             m_Jump = false;
    186.         }
    187.  
    188.  
    189.         private float SlopeMultiplier()
    190.         {
    191.             float angle = Vector3.Angle(m_GroundContactNormal, Vector3.up);
    192.             return movementSettings.SlopeCurveModifier.Evaluate(angle);
    193.         }
    194.  
    195.  
    196.         private void StickToGroundHelper()
    197.         {
    198.             RaycastHit hitInfo;
    199.             if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
    200.                                    ((m_Capsule.height/2f) - m_Capsule.radius) +
    201.                                    advancedSettings.stickToGroundHelperDistance))
    202.             {
    203.                 if (Mathf.Abs(Vector3.Angle(hitInfo.normal, Vector3.up)) < 85f)
    204.                 {
    205.                     m_RigidBody.velocity = Vector3.ProjectOnPlane(m_RigidBody.velocity, hitInfo.normal);
    206.                 }
    207.             }
    208.         }
    209.  
    210.  
    211.         private Vector2 GetInput()
    212.         {
    213.        
    214.             Vector2 input = new Vector2
    215.                 {
    216.                     x = CrossPlatformInputManager.GetAxis("Horizontal"),
    217.                     y = CrossPlatformInputManager.GetAxis("Vertical")
    218.                 };
    219.             movementSettings.UpdateDesiredTargetSpeed(input);
    220.             return input;
    221.         }
    222.  
    223.  
    224.         private void RotateView()
    225.         {
    226.             //avoids the mouse looking if the game is effectively paused
    227.             if (Mathf.Abs(Time.timeScale) < float.Epsilon) return;
    228.  
    229.             // get the rotation before it's changed
    230.             float oldYRotation = transform.eulerAngles.y;
    231.  
    232.             mouseLook.LookRotation (transform, cam.transform);
    233.  
    234.             if (m_IsGrounded || advancedSettings.airControl)
    235.             {
    236.                 // Rotate the rigidbody velocity to match the new direction that the character is looking
    237.                 Quaternion velRotation = Quaternion.AngleAxis(transform.eulerAngles.y - oldYRotation, Vector3.up);
    238.                 m_RigidBody.velocity = velRotation*m_RigidBody.velocity;
    239.             }
    240.         }
    241.  
    242.  
    243.         /// sphere cast down just beyond the bottom of the capsule to see if the capsule is colliding round the bottom
    244.         private void GroundCheck()
    245.         {
    246.             m_PreviouslyGrounded = m_IsGrounded;
    247.             RaycastHit hitInfo;
    248.             if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
    249.                                    ((m_Capsule.height/2f) - m_Capsule.radius) + advancedSettings.groundCheckDistance))
    250.             {
    251.                 m_IsGrounded = true;
    252.                 m_GroundContactNormal = hitInfo.normal;
    253.             }
    254.             else
    255.             {
    256.                 m_IsGrounded = false;
    257.                 m_GroundContactNormal = Vector3.up;
    258.             }
    259.             if (!m_PreviouslyGrounded && m_IsGrounded && m_Jumping)
    260.             {
    261.                 m_Jumping = false;
    262.             }
    263.         }
    264.     }
    265. }
    266.  
    267.  
     
    Last edited: Aug 13, 2015
  4. Acissathar

    Acissathar

    Joined:
    Jun 24, 2011
    Posts:
    669
    Move Lines 164-169 outside of the If(m_IsGrounded) statement, then you should be able to jump. Just make sure that those lines are placed above line 185 or pressing jump once will cause you to constantly jump upwards forever.

    You might also need to remove the "&& !m_Jump" at Line 132. I don't think you will just from looking at it though.
     
    Last edited: Aug 13, 2015
  5. createasaurus

    createasaurus

    Joined:
    Sep 20, 2013
    Posts:
    9
    Acissathar!! It worked!! I can infinite jump!!

    I moved the lines 164-169 just above the If(m-IsGrounded). I did not need to remove the "&& !m_Jump" at Line 132.

    Thank you!!
     
    Acissathar likes this.