Коллайдер Unity трясется после столкновения с другим коллайдером

У меня МАЛЕНЬКАЯ проблема. В Unity 3D 2020 Beta я поместил игрока со сферическим коллайдером на нем и несколько кубов (стен) с коллайдерами ящиков. Я добавил скрипт контроллера игрока к объекту игрока.

Я поместил камеру над плоскостью, где находится игрок и стены, и сделал так, чтобы игрок поворачивался в сторону положения мыши. Я использовал rigidbody.AddForce для движения в FixedUpdate функции. Скрипт контроллера плеера прилагается ниже:

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

public class PlayerController : MonoBehaviour
{
     [Header("Keys")]
     public KeyCode forward;
     public KeyCode backward;
     public KeyCode left;
     public KeyCode right;
     public KeyCode fire;
     [Header("Health")]
     public int hitpoints = 3;
     [Header("Movement")]
     public float speed;
     public float turningSpeed;
     [Header("Shooting")]
     public GameObject bulletPrefab;
     public Transform bulletSpawner;
     public float bulletSpeed;
     public float reloadTime;

     private float currentReload;
     private Rigidbody rb;
     private Quaternion targetRotation;
     void Start()
     {
         rb = GetComponent<Rigidbody>();
         currentReload = reloadTime;
     }


void LateUpdate()
{
    if (hitpoints == 0)
        Die();
    // Rotation
    var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit))
    { 
        targetRotation = Quaternion.LookRotation(hit.point - transform.position);
        Debug.DrawLine(transform.position, hit.point, Color.white);
    }
    transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, turningSpeed * Time.deltaTime);
    transform.eulerAngles = new Vector3(0, transform.rotation.eulerAngles.y, 0);

    currentReload += Time.deltaTime;
    // Shooting
    if (Input.GetKeyDown(fire) && currentReload >= reloadTime)
    {
        currentReload = 0f;
        GameObject bulletGO = Instantiate(bulletPrefab, bulletSpawner.position, transform.rotation);
        bulletGO.transform.position = bulletSpawner.position;
        Bullet bulletScript = bulletGO.GetComponent<Bullet>();
        bulletScript.speed = bulletSpeed;
        Destroy(bulletGO, 5f);
    }
}
void FixedUpdate()
{
    // Movement
    if (Input.GetKey(forward))
    {
        rb.AddForce(Vector3.forward * speed, ForceMode.Force);
    }
    if (Input.GetKey(backward))
    {
        rb.AddForce(-Vector3.forward * speed, ForceMode.Force);
    }
    if (Input.GetKey(left))
    {
        rb.AddForce(Vector3.left * speed, ForceMode.Force);
    }
    if (Input.GetKey(right))
    {
        rb.AddForce(Vector3.right * speed, ForceMode.Force);
    }
    //transform.position = new Vector3(transform.position.x, 10, transform.position.z);
    // ON RIGIDBODY I HAVE CONSTRAINS:
    // POSITION: Y (thats why I commented the line above)
    // ROTATION: X, Z (topdown -> so I want only rotation on Y)
}

private void Die()
{
    Destroy(gameObject);
}

}

Но проблема в том, что когда игрок очень сильно ударяется о стену, коллайдер сфер начинает трястись, и игрок не смотрит точно на положение мыши (в большинстве случаев оно находится где-то в 10 градусах от стены - это зависит от того, насколько сильно я ударил по стены).

Я могу записать, если это поможет. Если вам нужна какая-либо информация, не стесняйтесь спрашивать! Любая помощь будет оценена по достоинству! :)


person Marc Vana    schedule 21.07.2020    source источник
comment
Еще из любопытства, почему вы используете lateUpdate, а не обычный старый update?   -  person Jay    schedule 21.07.2020
comment
Я читал статью (кажется, не очень полезную), и там говорилось, что может быть лучше после других обновлений. То есть, сейчас это звучит немного безумно :)) Думаю, поменяю обратно на классику Update :)   -  person Marc Vana    schedule 22.07.2020
comment
Понимаю, мне было бы интересно прочитать это, если у вас все еще есть ссылка. если нет, то не беспокойтесь об этом :)   -  person Jay    schedule 22.07.2020


Ответы (1)


Проблема здесь, кажется, в том, что вы напрямую изменяете преобразование своего объекта, несмотря на наличие компонента Rigidbody. Как правило, вам следует избегать непосредственного изменения преобразования, когда у вас есть присоединенный Rigidbody, особенно некинематический, поскольку, присоединяя его, вы сигнализируете, что объект должен управляться симуляцией физики.

Решения, которые я хотел бы изучить:

  • Если вам не нужен rigidbody, не используйте его
  • Если вы можете избежать прямого изменения преобразования, не делайте этого. Вы можете вращать объекты, применяя крутящий момент и т.п.
  • Попробуйте настроить объект на кинематику, если вам не нужны столкновения, чтобы повлиять на физику твердого тела.
  • Вручную установите torque и velocity вашего объекта на 0 каждое фиксированное обновление
person Jay    schedule 21.07.2020
comment
Мне нужно твердое тело, чтобы видеть, когда вражеская пуля попадает в игрока; когда я устанавливаю жесткое тело на кинематику, объект игрока вообще не может двигаться. Я посмотрю на крутящий момент завтра утром и вернусь с еще одним комментарием :) Большое спасибо, @Jake, я действительно ценю это! - person Marc Vana; 22.07.2020
comment
На самом деле есть несколько вариантов: вы можете применять силы вращения до тех пор, пока вращение не выровняется, или вы можете заблокировать вращение и установить его вручную с помощью преобразования, или вы можете быть очень осторожны, чтобы убедиться, что симуляция физики никогда не придает вашему телу угловатость. скорость, которую вы не устанавливаете на 0 - person Jay; 22.07.2020
comment
Большое спасибо, я вернусь завтра с комментарием! Я попробую все, что ты сказал :) - person Marc Vana; 22.07.2020