【问题标题】:Unity collider shaking after hitting another colliderUnity 对撞机在撞到另一个对撞机后抖动
【发布时间】:2020-11-11 06:00:10
【问题描述】:

我有一个小问题。在 Unity 3D 2020 Beta 中,我放置了一个带有球体碰撞器的玩家,以及一些带有盒子碰撞器的立方体(墙壁)。我已将播放器控制器脚本添加到播放器对象。

我已经将相机放在玩家和墙壁所在的平面上方,并且我已经让玩家应该旋转以面对鼠标位置。我使用rigidbody.AddForceFixedUpdate 函数中移动。 播放器控制器脚本附在下面:

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 度之外的某个地方 - 这取决于用力程度我撞墙了)。

如果有帮助,我可以录制。如果您想了解任何信息,请随时询问!任何帮助将不胜感激! :)

【问题讨论】:

  • 出于好奇,你为什么使用lateUpdate而不是普通的旧update
  • 我正在阅读一篇文章(我看到不是那么有用),它说在其他更新之后可能会更好。我的意思是,现在听起来有点疯狂 :)) 我想我会把它改回经典 Update :)
  • 我明白了,如果你手边还有链接,我很想读一读。如果没有,请不要担心:)

标签: unity3d rotation collision shake collider


【解决方案1】:

这里的问题似乎是尽管有Rigidbody 组件,但您正在直接更改对象的转换。通常,当您附加了 Rigidbody 时,您应该避免直接更改变换,尤其是非运动的变换,因为通过附加一个,您表示对象将由物理模拟控制。

我会探索的解决方案:

  • 如果您不需要rigidbody,请不要使用
  • 如果您可以避免直接更改转换,请不要这样做。您可以通过应用torque 等来旋转对象
  • 如果您不需要碰撞来影响刚体的物理特性,请尝试将对象设置为运动学
  • 手动将对象的torquevelocity 设置为0 每个固定更新

【讨论】:

  • 我需要一个刚体来查看敌人子弹何时击中玩家;当我将刚体设置为运动学时,玩家对象根本无法移动。明天早上我会研究扭矩,我会回来发表另一条评论:)非常感谢@Jake,我真的很感激!
  • 真的有几个选项,你可以施加旋转力直到旋转对齐,或者你可以锁定旋转并通过变换手动设置它,或者你可以非常小心地确保物理模拟永远不会给你的身体一个角速度,然后你没有设置为0
  • 非常感谢,我明天再来评论!我会尝试你所说的一切:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多