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

Infinite Double Jump Error

Discussion in 'Scripting' started by Kazantler, May 13, 2020.

  1. Kazantler

    Kazantler

    Joined:
    May 12, 2020
    Posts:
    7
    if (m_IsGrounded || m_DoubleJumpPossible)
    {
    if (m_IsGrounded)
    {
    m_RigidBody.drag = 5f;
    }


    if (m_Jump)
    {
    m_RigidBody.drag = 0f;
    m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
    m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
    m_Jumping = true;
    m_DoubleJumpPossible = !m_DoubleJumpPossible;
    }

    if (!m_Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f)
    {
    m_RigidBody.Sleep();
    }
    }
    else
    {
    //double Jump
    if (m_Jump)
    {
    m_Jump = false;
    m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
    m_RigidBody.AddForce(new Vector3(0f, movementSettings.DoubleJumpForce, 0f), ForceMode.Impulse);
    }
    m_RigidBody.drag = 0f;
    if (m_PreviouslyGrounded && !m_Jumping)
    {
    StickToGroundHelper();
    }
    }
    m_Jump = false;
    }
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    If you can't be bothered to actually describe the problem, don't be surprised when no one else can be bothered to help with the problem. Also post code using CODE tags, or it is painful to read.
     
    eses likes this.
  3. Kazantler

    Kazantler

    Joined:
    May 12, 2020
    Posts:
    7
    Sorry about that
    Sorry about that. My player controller can double jump infinitely and I don't know how to fix it.
     
  4. Kazantler

    Kazantler

    Joined:
    May 12, 2020
    Posts:
    7
    Code (CSharp):
    1.  
    2.  
    3. if (m_IsGrounded || m_DoubleJumpPossible)
    4. {
    5. if (m_IsGrounded)
    6. {
    7. m_RigidBody.drag = 5f;
    8. }
    9.  
    10.  
    11. if (m_Jump)
    12. {
    13. m_RigidBody.drag = 0f;
    14. m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
    15. m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
    16. m_Jumping = true;
    17. m_DoubleJumpPossible = !m_DoubleJumpPossible;
    18. }
    19.  
    20. if (!m_Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f)
    21. {
    22. m_RigidBody.Sleep();
    23. }
    24. }
    25. else
    26. {
    27. //double Jump
    28. if (m_Jump)
    29. {
    30. m_Jump = false;
    31. m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
    32. m_RigidBody.AddForce(new Vector3(0f, movementSettings.DoubleJumpForce, 0f), ForceMode.Impulse);
    33. }
    34. m_RigidBody.drag = 0f;
    35. if (m_PreviouslyGrounded && !m_Jumping)
    36. {
    37. StickToGroundHelper();
    38. }
    39. }
    40. m_Jump = false;
    41. }
    42.  
    43.  
     
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    The point of code tags is to preserve the formatting. Having it all left justified defeats the purpose.

    If that is true, then m_Jump must have a value of "true". No where in this code is m_Jump set to anything but "false", so the problem would be in some other code somewhere else. But verify it is actually a double jump and not a regular jump. Put Debug.Log statements everywhere relevant and track what is happening. If you confirm it is double jump only, then look at where you are setting m_Jump to true.
     
  6. Kazantler

    Kazantler

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

    Kazantler

    Joined:
    May 12, 2020
    Posts:
    7
    Sorry, I don't really understand the Unity forums. A little confusing to me. Here is the whole script. I don't know if this solves the issue or not.
     
  8. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    So every frame you're checking for the jump input button on line 140, and setting m_Jump to true. So whenever you get down to line 194 m_Jump can be true even if you have already double jumped, which will allow another double jump.

    But here is probably the real issue. On line 169 you are checking to see if you are grounded OR if m_DoubleJumpPossible is true, in order to do a regular jump, not a double jump. This doesn't make sense. This will allow for an extra regular jump after the first regular jump (that would be a double jump, but you have the double jump code itself defined separately later). Only if both grounded and m_DoubleJumpPossible are false does it go to the "else" on line 191 to then check if it should do a double jump.

    So I suspect you are getting 2 regular jumps in a row followed by infinite double jumps afterwards. I'd try changing line 169 to only check if you are grounded. Change the "else" on 191 to an "elseif" and check for m_DoubleJumpPossible on that line. After you do the double jump set m_DoubleJumpPossible to false after line 198 but within the same "if" statement brackets as the rest of the double jump.
     
  9. Kazantler

    Kazantler

    Joined:
    May 12, 2020
    Posts:
    7
    This sadly didn't work. Do you think there is a simpler way to incorporate a double jump?