统一物理球体运动(轮子运动)



我正在使球体在平面对象上移动。我试图使运动类似于轮子的运动,但我不想使用轮子碰撞器组件。我使用扭矩来回移动球体,我使用刚体旋转(因为我读到直接在几何体上执行这些变换不是一个好的做法(,但旋转(转向(部分不起作用,球体继续沿着相同的方向旋转。下面的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SphereMovement : MonoBehaviour
{
float maxTorque = 30.0f;
float maxSteerAngle = 30.0f;
void Start()
{

}
void FixedUpdate()
{
var deltaRotation = GetComponent<Rigidbody>().rotation * Quaternion.Euler(new Vector3(maxSteerAngle * Input.GetAxis("Horizontal") * Time.deltaTime, 0, 0));
GetComponent<Rigidbody>().rotation = deltaRotation;
GetComponent<Rigidbody>().AddTorque(new Vector3(maxTorque * Input.GetAxis("Vertical") * Time.deltaTime, 0, 0)); 
}
}

有人能帮我吗?

  1. 缓存GetComponent调用以提高性能(见下文(

  2. 你正在向全局x方向施加扭矩,你可能想移动";向前";(取决于车轮的旋转(。transform.forward是你的朋友

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class SphereMovement : MonoBehaviour
    {
    float maxTorque = 30.0f;
    float maxSteerAngle = 30.0f;
    private Rigidbody rb;
    void Start()
    {
    rb = GetComponent<Rigidbody>();
    }
    void FixedUpdate()
    {
    var deltaRotation = rb .rotation * Quaternion.Euler(new Vector3(maxSteerAngle * Input.GetAxis("Horizontal") * Time.deltaTime, 0, 0));
    GetComponent<Rigidbody>().rotation = deltaRotation;
    GetComponent<Rigidbody>().AddTorque(transform.forward * (maxTorque * Input.GetAxis("Vertical") * Time.deltaTime); 
    }
    }
    

如果您的设置以其他方式旋转,您可以尝试transform.righttransform.up


编辑

当你转动你的轮子时;向前";也会旋转,因此需要忽略y。(假设现在是一个几乎平坦的表面,你提到了一架飞机(

所以你认为这是有效的:

Vector3 direction = transform.forward;
direction.y = 0;
direction = direction.normalized;
GetComponent<Rigidbody>().AddTorque(direction * (maxTorque * 
Input.GetAxis("Vertical") * Time.deltaTime); 

但随后它会来回移动,这取决于当前的旋转。所以这是行不通的。

另一个想法:您可以添加一个空的父对象,并将其在y轴上旋转为";"转向";而孩子被旋转以进行实际的"旋转";向前运动";就像车轮在混凝土上滑行。

没有父项的选项

您只需使用刚体在局部空间中应用扭矩。AddRelativeTorque

像这样(我们使用Vector3.forward,不要把它和transform.forward混淆!Vector3.forward就是Vector3(0,0,1(。但在局部空间中,这很好,因为仍然考虑旋转(

void FixedUpdate()
{
var deltaRotation = rb .rotation * Quaternion.Euler(new Vector3(maxSteerAngle * Input.GetAxis("Horizontal") * Time.deltaTime, 0, 0));
GetComponent<Rigidbody>().rotation = deltaRotation;
GetComponent<Rigidbody>().AddRelativeTorque(Vector3.forward * (maxTorque * Input.GetAxis("Vertical") * Time.deltaTime);
}

问题就在这里:

GetComponent<Rigidbody>().AddTorque(new Vector3(maxTorque * Input.GetAxis("Vertical") * Time.deltaTime, 0, 0));

扭矩始终沿全局X轴应用,因此球体对象的旋转方向无关紧要。这样想吧——无论你用哪种方式旋转足球,如果你把它向北旋转,它就会向北滚动。对于你的工作方法,你需要获得扭力,并沿着你想要移动的向量施加,而不是总是沿着全局X轴。

最新更新