Search Unity

Good O'l Sphere jump c# question

Discussion in 'Scripting' started by Kalliber95, Mar 27, 2015.

  1. Kalliber95

    Kalliber95

    Joined:
    Mar 27, 2015
    Posts:
    19
    Hey guys, I've been struggling to get my Jump section of my script to work and this is the closest I've gotten to it working. The original problem was that I had the player constantly jumping when he wasn't touching the ground but I got around that with using a boolean. Now my biggest issue is having the boolean to actually work. Sometimes it works sometimes it doesnt. On line 35, I've tried changing the == parameter to <= however it falls back to the player being able to infinitely jump. All advice is greatly accepted. Also feel free to point out any flaws in the code you can see yourself!

    Thanks!

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerController : MonoBehaviour
    5. {
    6.     public float speed;
    7.     public float JumpSpeed= 100.0f;
    8.     public float gravity = 20.0f;
    9.     public GUIText countText;
    10.     public GUIText winText;
    11.     private int count;
    12.     public bool grounded = true;
    13.     public float jumpPower = 190;
    14.     private bool hasJumped = false;
    15.     public float jumpHeight= 3;
    16.  
    17.  
    18.  
    19.  
    20.     void start (){
    21.         count = 0;
    22.         SetCountText();
    23.         winText.text = "";
    24.  
    25.     }
    26.  
    27.     void Update(){
    28.         //if (Input.GetButtonUp ("Jump")) {
    29.         //    jump ();
    30.         //    canJump = false;
    31.         //}
    32.         //if (rigidbody.velocity.y == 0.48) {
    33.            
    34.         //}
    35.         if(!grounded && rigidbody.velocity.y == 0) {
    36.             grounded = true;
    37.         }
    38.         if (Input.GetButtonUp("Jump") && grounded == true) {
    39.             hasJumped = true;
    40.         }
    41.    
    42.  
    43.     }
    44.  
    45.     void FixedUpdate()
    46.     {
    47.         if (hasJumped) {
    48.             //rigidbody.AddForce(transform.up*jumpPower);
    49.             rigidbody.velocity = new Vector3(0, jumpHeight, 0);
    50.             grounded = false;
    51.             hasJumped = false;
    52.         }
    53.  
    54.         float moveHorizontal = Input.GetAxis ("Horizontal");
    55.         float moveVertical = Input.GetAxis ("Vertical");
    56.  
    57.         Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
    58.  
    59.         rigidbody.AddForce (movement * speed * Time.deltaTime);
    60.  
    61.  
    62.  
    63.     }
    64.  
    65.     // Destroy everything that enters the trigger  
    66.     void OnTriggerEnter (Collider other) {
    67.         if (other.gameObject.tag == "PickUp")
    68.         {
    69.             other.gameObject.SetActive (false);
    70.             count = count + 1;
    71.             SetCountText();
    72.         }
    73.     }
    74.  
    75.     void SetCountText()
    76.     {
    77.         countText.text = "Count: " + count.ToString ();
    78.         if (count >= 12) {
    79.             winText.text = "You win!";
    80.         }
    81.     }
    82. //    void jump()
    83.     //    {
    84.     //    if (canJump=true){      
    85.     //    rigidbody.AddForce (Vector3.up * JumpSpeed);
    86.     //    }
    87.         //else{
    88.     //    }
    89.        
    90.  
    91.  
    92.         //rigidbody.AddForce(Vector3(0,jumping,0));
    93.         //rigidbody.AddForce (Vector3.up * JumpSpeed);
    94.     //}
    95. }
    96.  
    97.  
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    First off, rigidbody.velocity.y is a floating-point value, and you should (almost) never test whether a float is equal to something, you should test whether it is approximately equal. Otherwise you invite precision problems where you think two numbers are both "three and a half" but actually one of them is 3.500012534 and the other is 3.500012533 and so they're technically not equal. My guess is that's the reason it seems like this sometimes works and sometimes doesn't.

    But conceptually, testing whether velocity.y is (approximately) zero means "if I'm not currently moving up or down". That will happen if you're falling and the floor stops you, but it will also happen if you're rising and the ceiling stops you, or at the exact apex of your jump where the gradual acceleration of gravity causes your momentum to switch from positive to negative. So that's probably not the best approach to use here.

    This lengthy tutorial includes a section that describes a different method for detecting when a character is grounded (the "grounded" discussion starts around 51 minutes).
     
    Kalliber95 likes this.
  3. Kalliber95

    Kalliber95

    Joined:
    Mar 27, 2015
    Posts:
    19
    Thanks for the swift reply Antistone,

    In regards to the approximately equal, I have no real idea how to apply it with the boolean to check if its grounded,. My brain is fried trying to get my head around it.
     
  4. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Have a play with these options
    Code (CSharp):
    1.         if (!grounded &&
    2.             rb.velocity.y <= 0) {
    3.             grounded = true;
    4.         }
    Code (CSharp):
    1.         if (!grounded &&
    2.             Mathf.Approximately(rb.velocity.y, 0.0F)) {
    3.             grounded = true;
    4.         }
     
    Kalliber95 likes this.
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    If changing "equal" to "approximately equal" were the only thing you wanted to change, you'd just replace this expression:
    Code (CSharp):
    1. rigidbody.velocity.y == 0
    with this:
    Code (CSharp):
    1. Mathf.Approximately(rigidbody.velocity.y, 0)
    However, if you use the ground-detection method in the video I linked, I don't think you'll need Approximately. I just thought you should be aware of it for future reference.
     
    Kalliber95 likes this.
  6. Kalliber95

    Kalliber95

    Joined:
    Mar 27, 2015
    Posts:
    19
    Thank you guys for explaining it ^_^. I took a look at the ground detection video however, I couldnt really adapt it to a 3D environment but I did understand how it made it easier by drawing a detection underneath the model.

    Edit:
    I just realized that the issue I'm running into is to do with the point on the sphere. eg. I can only jump when the Very top point of the sphere has touched the ground(Approximately 0)

    Its a 3D sphere using force to roll around and can only jump when the one point is hitting ground .
     
    Last edited: Mar 28, 2015
  7. Kalliber95

    Kalliber95

    Joined:
    Mar 27, 2015
    Posts:
    19
    Just going to bump this, still facing problems.
     
  8. lordconstant

    lordconstant

    Joined:
    Jul 4, 2013
    Posts:
    389
    So you have a jumping sphere not a player jumping around a sphere?

    If so a raycast down from the center of the sphere to slightly beyond its extents could be used to check if grounded.

    In bed atm but will add some working code tomorrow for you.
     
  9. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Is it possible for you to upload a minimised ( remove all extraneous objects ) project file and provide a link ??
    This may make it easier for others to help without relying on guessing.

    From your use of the rigidbody variable I assume you are using Unity 4.x not 5.x ??
     
  10. kdubnz

    kdubnz

    Joined:
    Apr 19, 2014
    Posts:
    177
    Showing my ignorance ...
    I don't understand how/why the TOP of the sphere can touch the ground ...
     
  11. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Instead of checking for ground in a small sphere centered at one point on the surface of your character, check in a sphere that is centered on the center of your character and slightly larger than your character.