Home > Software design >  unity rigidbody It's going up and bounces when is moving
unity rigidbody It's going up and bounces when is moving

Time:10-30

I have a problem with rigidbody, This is a simple character controller script. the problem is i created some square floor tiles and each floor has mesh collider. soo when the character moving fast on thes floor tiles the charachter will going up a little bit or bounces when moving !! this is a image and a code of script


[enter image description here] enter image description here


public class character_controller : MonoBehaviour {

[Header("Speeds")]
 public float move_speed;
 public float move_smooth;
 public float rotate_speed;


 [Header("Physics")]
 public float gravity_force = -10.0f;


 [Header("Distances")]
 public float ground_min_dis = 0.25f;
 public float ground_max_dis = 100;


 [Header("Layers")]
 public LayerMask ground_layer;


 [HideInInspector] public Rigidbody rb;
 [HideInInspector] public Vector3 dir;
 [HideInInspector] public Vector3 input;
 [HideInInspector] public Vector3 input_smooth;

 [HideInInspector] public bool move_to_direction;
 [HideInInspector] public bool rotate_to_direction;

 [HideInInspector] public bool can_move;
 [HideInInspector] public bool is_on_ground;

 private float ground_distance;
 private RaycastHit ground_hit;
 

 // method: start is called before the first frame update
 void Start() {
     rb = GetComponent<Rigidbody>();
     can_move = true;
     move_to_direction = true;
 }


 // method: update is called once per frame
 void Update() {
     move_input();
     check_ground_distance();
 }


 // method: fixed update is called every fixed framerate frame
 void FixedUpdate() {
     if(
         move_to_direction
     ) {
         move();
     }
 }


 // method: move input
 private void move_input() {
     input.x = Input.GetAxis("Vertical");
     input.z = Input.GetAxis("Horizontal");
 }


 // method: move character
 private void move() {

     // input smooth for moving character smoothly
     input_smooth = Vector3.Lerp(input_smooth, input, move_smooth * Time.deltaTime);

     // get the forward facing direction of the character
     var forward = Vector3.forward;

     // get the left facing direction of the character
     var right = Vector3.left;
     
     // determine the direction
     dir = (input_smooth.x * forward)   (input_smooth.z * right);

     // normalize direction
     if (
         dir.magnitude > 1f
     ) {
         dir.Normalize();
     }

     Vector3 target_position = rb.position   dir * move_speed * Time.deltaTime;
     Vector3 target_velocity = (target_position - transform.position) / Time.deltaTime;

     target_velocity.y = rb.velocity.y;

     if(
         can_move
     ) {
         rb.velocity = target_velocity;
     }

     if(
         input.magnitude > 0.01f
     ) {
         // start rotate to direction
         if(
             rotate_to_direction == true
         ) {
             start_rotate_to_direction(dir, rotate_speed);
         }
     }
 }


 // method: rotate character to direction
 public void start_rotate_to_direction(
     Vector3 dir,
     float speed
 ) {
     Vector3 forward;
     Quaternion new_rotation;

     forward = Vector3.RotateTowards(transform.forward, dir.normalized, speed * Time.deltaTime, 0.1f);
     forward.y = 0;

     new_rotation = Quaternion.LookRotation(forward);

     transform.rotation = new_rotation;
 }


 // method: check ground distance
 private void check_ground_distance() {

     float distance;

     Ray ray = new Ray(transform.position, Vector3.down);

     // if the ray hit to the ground layer
     if (
         Physics.Raycast(ray, out ground_hit, ground_max_dis, ground_layer)
     ) {
         if(
             !ground_hit.collider.isTrigger
         ) {
             distance = transform.position.y - ground_hit.point.y;
             ground_distance = (float)System.Math.Round(distance, 2);
         }
     }

     // check if character on the ground
     if(
         ground_distance <= ground_min_dis
     ) {
         is_on_ground = true;
     } else {
         is_on_ground = false;
     }

     // apply force gravity when falling
     if(
         is_on_ground == false
     ) {
         rb.AddForce(transform.up * gravity_force * Time.deltaTime, ForceMode.VelocityChange);
     }
 }}

CodePudding user response:

Can you please read this manual page carefully?

I think, the page explains this phenomena (it is called ghost collision). Probably, your rigidbody hits to the border of mesh colliders just like described in manual.

Also, did you try to freeze motion along related axis by using inspector? It can be a quick solution.

CodePudding user response:

I solved this problem by going into Edit > Project Settings > Physics from Physics tab you can set the Default Contact Offset value from 0.01 to 0.0001.

  • Related