Results 1 to 3 of 3
  1. #1
    Join Date
    Feb 2002
    Location
    Belgium, Limburg
    Posts
    7,196

    Jumping question

    I have a sphere which is my player and which I can move around freely throughout the world. But now I want to make the little guy jump... which kind of works, but not really the way I want it to work.

    If I jump now, the ball just snaps to the jump height and then starts falling because of gravity working on it. Can anyone help me figure out how to make the ball actually "jump" up to the jump height instead of just snapping to it?

    The build:
    http://www.nielsvaes.be/Unity/WebPlayer.html


    The code:
    Code:
    public class Player : MonoBehaviour
    {
        #region Fields
    
        enum State
        {
            isRolling,
            isJumping
        }
    
        public float PlayerSpeed;
        public float JumpPower;
        public float Weight = 2;
        public GameObject RotationFrom;
    
        private State state = State.isRolling;
        #endregion
    
    
        #region Methods
        void Update()
        {
            // amount to move
            float amountToMove = Input.GetAxis("Horizontal") * PlayerSpeed * Time.deltaTime;
            float amountToMoveVertical = Input.GetAxis("Vertical") * PlayerSpeed * Time.deltaTime;
            float amountToJump = JumpPower * Time.deltaTime;
    
            // move the player
            transform.Translate(new Vector3(amountToMove, 0, amountToMoveVertical));
    
            // stops player from going through the floot
            if (state != State.isJumping)
            {
                if (transform.position.y < 0 + (transform.localScale.y / 2))
                    transform.position = new Vector3(transform.position.x, 0 + (transform.localScale.y / 2), transform.position.z);
    
                if (transform.position.y > 0 + (transform.localScale.y / 2))
                    transform.position = new Vector3(transform.position.x, 0 + (transform.localScale.y / 2), transform.position.z);
            }
    
            // rotate the player using another gameObject. Set it to the main camera which has the LookAt script and this works pretty good
            transform.rotation = RotationFrom.transform.rotation;
    
    
            // Jump... but the ball just snaps to the jumpheight instead of "jumping" to it...
            if (Input.GetKeyDown(KeyCode.Space))
            {
                state = State.isJumping;
                transform.Translate(Vector3.up * amountToJump);
            }
    
    
            // check to see if we're back on the ground, if we are, we're in state isRolling and now longer isJumping
            if (transform.position.y < 0 + (transform.localScale.y / 2))
                state = State.isRolling;
        }
    
        void OnGUI()
        {
            GUI.Label(new Rect(10, 10, 20, 300), Input.GetAxis("Horizontal").ToString());
            GUI.Label(new Rect(10, 30, 20, 300), Input.GetAxis("Vertical").ToString());
        }
        #endregion
    }
    Technical Artist at LuGus Studios
    www.lugus-studios.be


    nielsVaes.be


  2. #2
    Join Date
    Dec 2007
    Location
    Austin, Texas
    Posts
    499
    I generally add an up force to him, and make it so that the jump key does nothing until he lands. I then have a function that raycasts downwards and returns a bool, if the raycast touches something tagged "World", it returns true. This is to prevent you from jumping on things like bullets. You can do it however you want though (like what it detects). Key things is, an extra boolean that turns OFF jumping and ON ground detection.

    another way to detect ground is: OnCollisionEnter() {}

    Only problem with that, is that if you run into a wall mid jump, you can jump again. You would have to do a little work with it.

    Hope that helps!

  3. #3
    Join Date
    Mar 2002
    Location
    Long Island
    Posts
    1,673
    I kinda cheated on mine and found something online. It works good but it also combines other things like going up a slope and the like.

    Code:
    using UnityEngine;
    
    using System.Collections;
    
    [RequireComponent(typeof(CharacterController))]
    public class Player : MonoBehaviour
    {
    
        public float walkSpeed = 6.0f;
    
        public float runSpeed = 11.0f;
    
        // If true, diagonal speed (when strafing + moving forward or back) can't exceed normal move speed; otherwise it's about 1.4 times faster
        public bool limitDiagonalSpeed = true;
    
        // If checked, the run key toggles between running and walking. Otherwise player runs if the key is held down and walks otherwise
        // There must be a button set up in the Input Manager called "Run"
        public bool toggleRun = false;
    
        public float jumpSpeed = 8.0f;
        public float gravity = 20.0f;
    
        // Units that player can fall before a falling damage function is run. To disable, type "infinity" in the inspector
        public float fallingDamageThreshold = 10.0f;
    
        // If the player ends up on a slope which is at least the Slope Limit as set on the character controller, then he will slide down
        public bool slideWhenOverSlopeLimit = false;
    
        // If checked and the player is on an object tagged "Slide", he will slide down it regardless of the slope limit
        public bool slideOnTaggedObjects = false;
    
        public float slideSpeed = 12.0f;
    
        // If checked, then the player can change direction while in the air
        public bool airControl = false;
    
        // Small amounts of this results in bumping when walking down slopes, but large amounts results in falling too fast
        public float antiBumpFactor = .75f;
    
        // Player must be grounded for at least this many physics frames before being able to jump again; set to 0 to allow bunny hopping
        public int antiBunnyHopFactor = 1;
    
        private Vector3 moveDirection = Vector3.zero;
        private bool grounded = false;
        private CharacterController controller;
        private Transform myTransform;
        private float speed;
        private RaycastHit hit;
        private float fallStartLevel;
        private bool falling;
        private float slideLimit;
        private float rayDistance;
        private Vector3 contactPoint;
        private bool playerControl = false;
        private int jumpTimer;
    
        void Start()
        {
            controller = GetComponent<CharacterController>();
            myTransform = transform;
            speed = walkSpeed;
            rayDistance = controller.height * .5f + controller.radius;
            slideLimit = controller.slopeLimit - .1f;
            jumpTimer = antiBunnyHopFactor;
        }
    
        void FixedUpdate()
        {
            float inputX = Input.GetAxis("Horizontal");
            float inputY = Input.GetAxis("Vertical");
            // If both horizontal and vertical are used simultaneously, limit speed (if allowed), so the total doesn't exceed normal move speed
            float inputModifyFactor = (inputX != 0.0f && inputY != 0.0f && limitDiagonalSpeed) ? .7071f : 1.0f;
    
            if (grounded)
            {
                bool sliding = false;
                // See if surface immediately below should be slid down. We use this normally rather than a ControllerColliderHit point,
                // because that interferes with step climbing amongst other annoyances
                if (Physics.Raycast(myTransform.position, -Vector3.up, out hit, rayDistance))
                {
                    if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
                        sliding = true;
                }
                // However, just raycasting straight down from the center can fail when on steep slopes
                // So if the above raycast didn't catch anything, raycast down from the stored ControllerColliderHit point instead
                else
                {
                    Physics.Raycast(contactPoint + Vector3.up, -Vector3.up, out hit);
                    if (Vector3.Angle(hit.normal, Vector3.up) > slideLimit)
                        sliding = true;
                }
    
                // If we were falling, and we fell a vertical distance greater than the threshold, run a falling damage routine
                if (falling)
                {
                    falling = false;
                    if (myTransform.position.y < fallStartLevel - fallingDamageThreshold)
                        FallingDamageAlert(fallStartLevel - myTransform.position.y);
                }
    
                // If running isn't on a toggle, then use the appropriate speed depending on whether the run button is down
                if (!toggleRun)
                    speed = Input.GetButton("Run") ? runSpeed : walkSpeed;
    
                // If sliding (and it's allowed), or if we're on an object tagged "Slide", get a vector pointing down the slope we're on
                if ((sliding && slideWhenOverSlopeLimit) || (slideOnTaggedObjects && hit.collider.tag == "Slide"))
                {
                    Vector3 hitNormal = hit.normal;
                    moveDirection = new Vector3(hitNormal.x, -hitNormal.y, hitNormal.z);
                    Vector3.OrthoNormalize(ref hitNormal, ref moveDirection);
                    moveDirection *= slideSpeed;
                    playerControl = false;
                }
                // Otherwise recalculate moveDirection directly from axes, adding a bit of -y to avoid bumping down inclines
                else
                {
                    moveDirection = new Vector3(inputX * inputModifyFactor, -antiBumpFactor, inputY * inputModifyFactor);
                    moveDirection = myTransform.TransformDirection(moveDirection) * speed;
                    playerControl = true;
                }
    
                // Jump! But only if the jump button has been released and player has been grounded for a given number of frames
                if (!Input.GetButton("Jump"))
                    jumpTimer++;
                else if (jumpTimer >= antiBunnyHopFactor)
                {
                    moveDirection.y = jumpSpeed;
                    jumpTimer = 0;
                }
            }
            else
            {
                // If we stepped over a cliff or something, set the height at which we started falling
                if (!falling)
                {
                    falling = true;
                    fallStartLevel = myTransform.position.y;
                }
    
                // If air control is allowed, check movement but don't touch the y component
                if (airControl && playerControl)
                {
                    moveDirection.x = inputX * speed * inputModifyFactor;
                    moveDirection.z = inputY * speed * inputModifyFactor;
                    moveDirection = myTransform.TransformDirection(moveDirection);
                }
            }
    
            // Apply gravity
            moveDirection.y -= gravity * Time.deltaTime;
    
            // Move the controller, and set grounded true or false depending on whether we're standing on something
            grounded = (controller.Move(moveDirection * Time.deltaTime) & CollisionFlags.Below) != 0;
        }
    
        void Update()
        {
            // If the run button is set to toggle, then switch between walk/run speed. (We use Update for this...
            // FixedUpdate is a poor place to use GetButtonDown, since it doesn't necessarily run every frame and can miss the event)
            if (toggleRun && grounded && Input.GetButtonDown("Run"))
                speed = (speed == walkSpeed ? runSpeed : walkSpeed);
        }
    
        // Store point that we're in contact with for use in FixedUpdate if needed
        void OnControllerColliderHit(ControllerColliderHit hit)
        {
            contactPoint = hit.point;
        }
    
        // If falling damage occured, this is the place to do something about it. You can make the player
        // have hitpoints and remove some of them based on the distance fallen, add sound effects, etc.
        void FallingDamageAlert(float fallDistance)
        {
            print("Ouch! Fell " + fallDistance + " units!");
        }
    }
    Please let me know when we are going to have some fun so I can pay attention.


Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •