0
\$\begingroup\$

I am trying to create a simple movement script. Currently I don't have any jumping implemented; the movement script should just move rigidbody-based Capsule left, right, forward, backward based on Camera direction.

What is happening, however, is that the Capsule will go into the air after moving consistently for a few seconds. This especially happens if you hit two movement keys (W and A) at once.

Any ideas why this happens and how to prevent it? "Use Gravity" is checked. The constraints of the Rigidbody are "Freeze Rotation" on X, Y, and Z. All values for Rigidbody settings are default.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Scratcher : MonoBehaviour
{
    Rigidbody r;
    public CapsuleCollider capsule;
    public Transform cameraTransform;

    //Base Movement
    public float horizontalInput;
    public float verticalInput;
    public Vector3 moveDirection;
    public Vector3 moveDirectionRaw;
    public int rotDegPerSecond = 720;
    public float speed;


    //GroundChecking
    public LayerMask groundLayerMask;
    public Transform groundCheckTransform;
    public bool isGrounded;    
    public float groundCheckRadius = 0.25f;    
    public float distanceToGround;  


    void Awake()
    {
        r = GetComponent<Rigidbody>();
        capsule = GetComponent<CapsuleCollider>();      
    }

    void Update()
    {
        horizontalInput = Input.GetAxis("Horizontal");
        verticalInput = Input.GetAxis("Vertical");
    }

    private void FixedUpdate()
    {
        GroundCheck();

        moveDirection = new Vector3(horizontalInput, 0.0f, verticalInput).normalized;
        moveDirection = (Quaternion.AngleAxis(cameraTransform.rotation.eulerAngles.y, Vector3.up) * moveDirection).normalized;
        moveDirectionRaw = new Vector3(Input.GetAxisRaw("Horizontal"), 0.0f, Input.GetAxisRaw("Vertical")).normalized;
        moveDirectionRaw = (Quaternion.AngleAxis(cameraTransform.rotation.eulerAngles.y, Vector3.up) * moveDirectionRaw).normalized;


        if (moveDirectionRaw != Vector3.zero && moveDirection != Vector3.zero)
        {            
            Quaternion targetRotation = Quaternion.LookRotation(moveDirection); //or moveDirectionRaw
            targetRotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotDegPerSecond * Time.deltaTime);
            r.MoveRotation(targetRotation);
        }
        
        Vector3 force = moveDirection * speed;
        r.AddForce(force, ForceMode.VelocityChange);

        GroundStopSlide();        
    }

    
    void GroundStopSlide()
    {
        if (moveDirectionRaw == Vector3.zero)
        {
            Vector3 zeroMe = new Vector3(0, r.velocity.y, 0);
            r.velocity = zeroMe;
        }
    }
    
    public void GroundCheck()
    {
        isGrounded = Physics.CheckSphere(groundCheckTransform.position, groundCheckRadius, groundLayerMask);

        RaycastHit groundHit = new RaycastHit();
        if (Physics.Raycast(transform.position, -Vector3.up, out groundHit))
        {
            distanceToGround = groundHit.distance;
        }        
    }
}
\$\endgroup\$
1

1 Answer 1

0
\$\begingroup\$

maybe your move direction have a force that upwards, check the script in FixedUpdate and physicmaterial "bounce"

\$\endgroup\$
1
  • \$\begingroup\$ The code for FixedUpdate is shown in the question. What would you recommend changing in that code? How would the player check their physics material's bounce parameter, and what should they set it to? Details like this could help make this a more useful answer that will attract up-votes. \$\endgroup\$
    – DMGregory
    Dec 9, 2022 at 19:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .