Search Unity

Player/character movement jumps when moving down the slopes.

Discussion in 'Scripting' started by BluesyPompanno, Sep 28, 2017.

  1. BluesyPompanno

    BluesyPompanno

    Joined:
    Jan 1, 2017
    Posts:
    37
    Hello I have a small problem.

    My character starts to jump when moving down the slopes or ramps.

    This is my code.
    Code (CSharp):
    1. public float walkSpeed = 10f;
    2.     public float runSpeed = 20f;
    3.  
    4.     public Camera cameraPlayer;
    5.     private float mouseSensitivity = 2.0f;
    6.     public Vector2 LookRange = new Vector2(-60f, 60f);
    7.     float mouseX;
    8.     float mouseY;
    9.  
    10.     CharacterController charController;
    11.  
    12.     public float gravity = -12f;
    13.     public float jumpHeight = 1f;
    14.     float velocityY;
    15.  
    16.     float currentSpeed;
    17.  
    18.     public float turnSmoothTime = 0.2f;
    19.     float turnSmoothVelocity;
    20.     public float speedSmoothTime = 0.1f;
    21.     float speedSmoothVelocity;
    22.  
    23.     private void Start()
    24.     {
    25.         charController = GetComponent<CharacterController>();
    26.        
    27.     }
    28.     private void Update()
    29.     {
    30.         Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
    31.         Vector3 directionInput = input.normalized;
    32.         bool running = Input.GetKey(KeyCode.LeftShift);
    33.  
    34.         //transform.Translate(moveAmount);
    35.         transform.Rotate(0, mouseX, 0);
    36.  
    37.         mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
    38.         mouseY -= Input.GetAxis("Mouse Y") * mouseSensitivity;
    39.         mouseY = Mathf.Clamp(mouseY, LookRange.x, LookRange.y);
    40.         cameraPlayer.transform.localRotation = Quaternion.Euler(mouseY, 0, 0);
    41.  
    42.         if (Input.GetKeyDown(KeyCode.Space))
    43.         {
    44.             Jump();
    45.         }
    46.         MoveThePlayer(directionInput,running);
    47.     }
    48.     void MoveThePlayer(Vector3 directionInput,bool running)
    49.     {
    50.         Vector3 moveAmount = directionInput;      
    51.  
    52.         moveAmount = transform.TransformDirection(moveAmount);
    53.  
    54.         float targetSpeed = ((running) ? runSpeed : walkSpeed) * directionInput.magnitude;
    55.  
    56.         currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));
    57.  
    58.         Vector3 velocityMovement = moveAmount * currentSpeed + Vector3.up * velocityY;
    59.  
    60.         charController.Move(velocityMovement * Time.deltaTime);
    61.  
    62.         velocityY += Time.deltaTime * gravity;
    63.         currentSpeed = new Vector2(charController.velocity.x, charController.velocity.z).magnitude;
    64.         if (charController.isGrounded)
    65.         {
    66.             velocityY = 0;
    67.         }
    68.     }
    69.  
    70.     void Jump()
    71.     {
    72.         if (charController.isGrounded)
    73.         {
    74.             float jumpVelocity = Mathf.Sqrt(-2 * gravity * jumpHeight);
    75.             velocityY = jumpVelocity;
    76.         }
    77.     }
    78.     float GetModifiedSmoothTime(float smoothTime)
    79.     {
    80.         if (charController.isGrounded)
    81.         {
    82.             return smoothTime;
    83.         }
    84.         return smoothTime;
    85.     }
    86. }
    I have tried putting the velocityY into the Vector3 input like this -> Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), velocityY, Input.GetAxisRaw("Vertical")) ,but that makes the player to jump only like 2 units above ground and then snaps him back to the ground.

    I have also tried doing this with raycast but that makes the player to float above ground and not being able to move or jump.

    Anybody knows how to fix this ?
     
  2. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    There would mainly be two steps for accomplishing this:
    1. At every frame, do a spherecast downward to see at what distance you are from the ground. Then once you have that, move your character downward by that distance... so that you "snap" to the ground
    2. Make it so that your move "input" is always converted as tangent to the ground normal before it is applied as movement. That way you'll be moving along slopes instead of moving off of them
     
    BluesyPompanno likes this.
  3. BluesyPompanno

    BluesyPompanno

    Joined:
    Jan 1, 2017
    Posts:
    37
    Thank you I will try that
     
  4. BluesyPompanno

    BluesyPompanno

    Joined:
    Jan 1, 2017
    Posts:
    37
    Ok i've tried a slitly different aproach to it but I am still lost
    I've tried doing this

    adding into the MoveThePlayer function raycast that should point downwards and make the player stick to the ground but he just floats in the air and still bumps down the hill.

    Code (CSharp):
    1.  
    2. //added some variables//
    3. private Transform myTransform;
    4. public flaot rayDistance = 0.1f;
    5.  
    6. //In the MoveThePlayer function i have added this//
    7.  
    8.   RaycastHit hit;
    9.         if (Physics.Raycast(myTransform.position, -Vector3.up, out hit, rayDistance))
    10.         {
    11.             Vector3 hitNormal = hit.normal;
    12.             Vector3 slopeHitposition = hitNormal;
    13.             Vector3 slp = new Vector3(0, slopeHitposition.y);
    14.             transform.position = slp;
    15.             velocityY = slp.y;
    16.            
    17.             var charController = GetComponent<CharacterController>();
    18.             moveAmount = slp;
    19.  
    20.             charController.Move(moveAmount);
    21.  
    22.         }
    23.  
    i have tried to make it this way,but it doesn't work.

    I must be complete i**ot,I can make a gun shoot with raycast,create a detection system for the enemy but can't use it in movement scripts.
     
  5. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    You are constantly resetting the position at line 14, so I wouldn't expect your character to move at all. I would recommend you look into using cross product to merge your movement vector with the slope normal.
    Code (CSharp):
    1. Vector3.Cross(*movement vector*, *slope normal*)
    It's not as magical as that, but the moment you understand what the inputs should be like, you simply plug them into the function.
     
    BluesyPompanno likes this.
  6. BluesyPompanno

    BluesyPompanno

    Joined:
    Jan 1, 2017
    Posts:
    37
    Thank you I will try that
     
  7. BluesyPompanno

    BluesyPompanno

    Joined:
    Jan 1, 2017
    Posts:
    37
    Ok so i have managed to fix this not by using raycast but by using CollisionFlags.

    Here is the working code with jumping,moving and moving down the slopes.
    Feel free to use it

    Code (CSharp):
    1.  
    2.     //Movement variables//
    3.     public float walkSpeed = 6f;
    4.     public float runSpeed = 12f;
    5.  
    6.     //Camera variables//
    7.     public Camera cameraPlayer;
    8.     private float mouseSensitivity = 2.0f;
    9.     public Vector2 LookRange = new Vector2(-60f, 60f);
    10.     float mouseX;
    11.     float mouseY;
    12.  
    13.     //Gravity and gravity helper variables//
    14.     public float gravity = -12f;
    15.     public float jumpHeight = 1f;
    16.     float velocityY;
    17.  
    18.     //Helper variables//
    19.     public float turnSmoothTime = 0.2f;
    20.     float turnSmoothVelocity;
    21.     public float speedSmoothTime = 0.1f;
    22.     float speedSmoothVelocity;
    23.     float currentSpeed;
    24.     bool GROUNDED;
    25.  
    26.     //Componenents and script access//
    27.     CharacterController charController;
    28.  
    29.     private void Start()
    30.     {
    31.         charController = GetComponent<CharacterController>();
    32.  
    33.  
    34.         Cursor.lockState = CursorLockMode.Locked;
    35.         Cursor.visible = false;
    36.            
    37.     }
    38.     private void Update()
    39.     {
    40.         //Getting controlls//
    41.  
    42.         //MOVMENT//
    43.         Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
    44.         Vector3 directionInput = input.normalized;
    45.         bool running = Input.GetKey(KeyCode.LeftShift);
    46.  
    47.         //CAMERA//
    48.         mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
    49.         mouseY -= Input.GetAxis("Mouse Y") * mouseSensitivity;
    50.  
    51.         transform.Rotate(0, mouseX, 0);      
    52.         mouseY = Mathf.Clamp(mouseY, LookRange.x, LookRange.y);
    53.         cameraPlayer.transform.localRotation = Quaternion.Euler(mouseY, 0, 0);
    54.  
    55.         if (GROUNDED)
    56.         {
    57.             if (Input.GetKey(KeyCode.Space))
    58.             {
    59.                 Jump();
    60.             }
    61.         }
    62.         else
    63.         {
    64.             velocityY += Time.deltaTime * gravity;
    65.         }
    66.  
    67.         Vector3 moveAmount = directionInput;
    68.  
    69.         moveAmount = transform.TransformDirection(moveAmount);
    70.  
    71.         float targetSpeed = ((running) ? runSpeed : walkSpeed) * directionInput.magnitude;
    72.         currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, GetModifiedSmoothTime(speedSmoothTime));
    73.  
    74.         Vector3 velocityMovement = moveAmount * currentSpeed + Vector3.up * velocityY;  
    75.         currentSpeed = new Vector3(charController.velocity.x,0 ,charController.velocity.z).magnitude;
    76.  
    77.         CollisionFlags flags = charController.Move(velocityMovement * Time.deltaTime);
    78.         GROUNDED = ((flags & CollisionFlags.Below) != 0);
    79.     }
    80.  
    81.     float GetModifiedSmoothTime(float smoothTime)
    82.     {
    83.         if (charController.isGrounded)
    84.         {
    85.             return smoothTime;
    86.         }
    87.         return smoothTime;
    88.     }
    89.  
    90.     void Jump()
    91.     {
    92.         float jumpVelocity = Mathf.Sqrt(-2 * gravity * jumpHeight);
    93.         velocityY = jumpVelocity;
    94.     }
    95. }
    96.