Unity汽车自动转向

4
我有一个简单的汽车游戏,它在一条直路上。然而,路的某些部分有些拐角,我希望我的汽车可以通过这些点转动轮子。我已经为我的汽车创建了一些节点来控制方向,但我的汽车仍然保持直行。我无法确定问题出在哪里。

My car and the road

这里是创建节点系统的代码:

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

public class PathFollower : MonoBehaviour
{

public Color lineColor;

private List<Transform> nodes = new List<Transform>();

private void OnDrawGizmos()
{
    Gizmos.color = lineColor;

    Transform[] pathTransform = GetComponentsInChildren<Transform>();
    nodes = new List<Transform>();

    for(int i = 0; i < pathTransform.Length; i++)
    {
        if (pathTransform[i] != transform)
        {
            nodes.Add(pathTransform[i]);
        }
    }

    for (int i = 0; i < nodes.Count; i++)
    {
        Vector3 previousNode;
        Vector3 currentNode = nodes[i].position;

        if (!(i - 1 < 0))
        {
            previousNode = nodes[i - 1].position;
        }
        else
        {
            previousNode = nodes[0].position;
        }

        Gizmos.DrawLine(previousNode, currentNode);
        Gizmos.DrawWireSphere(currentNode, 0.3f);

    }
}

这个脚本是用来让我的汽车自动驾驶的:

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

public class AutoSteering : MonoBehaviour
{

public Transform path;
public float maxSteeringAngle = 30f;
public CarPhysic getAxleInfos;

private List<Transform> nodes;
private int currentNode = 0;

void Start()
{
    Transform[] pathTransform = path.GetComponentsInChildren<Transform>();
    nodes = new List<Transform>();

    for (int i = 0; i < pathTransform.Length; i++)
    {
        if (pathTransform[i] != path.transform)
        {
            nodes.Add(pathTransform[i]);
        }
    }
}

private void FixedUpdate()
{
    ApplySteer();
    CheckWaypointDistance();

}

private void ApplySteer()
{
    Vector3 relativeVector = transform.InverseTransformPoint(nodes[currentNode].position);
    float newSteer = (relativeVector.x / relativeVector.magnitude) * maxSteeringAngle;

    foreach (AxleInfo axleInfo in getAxleInfos.axleInfos)
    {
        newSteer = axleInfo.leftWheel.steerAngle;
        newSteer = axleInfo.rightWheel.steerAngle;
    }
}

private void CheckWaypointDistance()
{
    if(Vector3.Distance(transform.position, nodes[currentNode].position) < 0.5f)
    {
        if (currentNode == nodes.Count - 1)
        {
            currentNode = 0;
        }
        else
        {
            currentNode++;
        }
    }
}

这是有关汽车物理的内容,我从Unity教程本身复制了一些部分:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;


[System.Serializable]
public class AxleInfo
{
    public WheelCollider leftWheel;
    public WheelCollider rightWheel;
    public bool motor;
    public bool newSteer;
}

public class CarPhysic : MonoBehaviour
{
    public List<AxleInfo> axleInfos;
    public float maxMotorTorque;
    public float brake;
    public bool isBraking;
    public Transform carPosition;
    public float mudForce = 300f;
    public Canvas myCanvas;


private Rigidbody rigidbody;


public void ApplyLocalPositionToVisuals(WheelCollider collider)
{
    if (collider.transform.childCount == 0)
    {
        return;
    }

    Transform visualWheel = collider.transform.GetChild(0);

    Vector3 position;
    Quaternion rotation;
    collider.GetWorldPose(out position, out rotation);

    visualWheel.transform.position = position;
    visualWheel.transform.rotation = rotation;
}

private void Braking(AxleInfo axleInfo)
{
    if (isBraking)
    {
        axleInfo.leftWheel.brakeTorque = brake;
        axleInfo.rightWheel.brakeTorque = brake;
    }
    else
    {
        axleInfo.leftWheel.brakeTorque = 0;
        axleInfo.rightWheel.brakeTorque = 0;  
    } 
}

void Start()
{
    rigidbody = GetComponent<Rigidbody>();
}

public void FixedUpdate()
{
    float motor = maxMotorTorque * Input.GetAxis("Vertical");

    foreach (AxleInfo axleInfo in axleInfos)
    {
        if (axleInfo.motor)
        {
            isBraking = false;
            axleInfo.leftWheel.motorTorque = motor;
            axleInfo.rightWheel.motorTorque = motor;
        }
        if (Input.GetKey(KeyCode.Space))
        {
            isBraking = true;
            Braking(axleInfo);
        }
        else if (Input.GetKeyUp(KeyCode.Space))
        {
            isBraking = false;
            axleInfo.leftWheel.brakeTorque = 0;
            axleInfo.rightWheel.brakeTorque = 0;
        }
        ApplyLocalPositionToVisuals(axleInfo.leftWheel);
        ApplyLocalPositionToVisuals(axleInfo.rightWheel);
    }
}
private void Update()
{
    RaycastHit hit;

    if (Physics.Raycast(carPosition.position, transform.TransformDirection(Vector3.down * 100), out hit))
    {
        Debug.DrawRay(carPosition.position, Vector3.down * 100, Color.red);

        if (hit.collider.gameObject.tag == "mud")
        {
            Debug.Log("done");
            rigidbody.AddForce(Vector3.right * mudForce, ForceMode.Impulse);
        }

        if (hit.collider.gameObject.tag == "FinishPoint")
        {
            myCanvas.gameObject.SetActive(true);
            foreach(AxleInfo axleInfo in axleInfos)
            {
                isBraking = true;
                maxMotorTorque = 0;
                Braking(axleInfo);
            }
        }
    }
}

1
为了缩小问题范围,除了遵循航点之外,如果您使用 ApplySteer() 进行随机转向,车辆会做出响应并转向吗? - rustyBucketBay
尝试使用贝塞尔曲线方法,此链接将提供您所需的所有代码和解释。https://www.habrador.com/tutorials/interpolation/3-move-along-curve/ - Syed Mohib Uddin
1个回答

1

不看你在ApplySteer中的其余代码,你就可以

private void ApplySteer()
{
    Vector3 relativeVector = transform.InverseTransformPoint(nodes[currentNode].position);
    float newSteer = (relativeVector.x / relativeVector.magnitude) * maxSteeringAngle;

    foreach (AxleInfo axleInfo in getAxleInfos.axleInfos)
    {
        newSteer = axleInfo.leftWheel.steerAngle;
        newSteer = axleInfo.rightWheel.steerAngle;
    }
}

在循环中,您将一些值存储到newSteer中。无论如何,您只会存储最后一个值。然后您从未使用该值。
我猜 - 我非常确定 - 您实际想要做的是:
private void ApplySteer()
{
    Vector3 relativeVector = transform.InverseTransformPoint(nodes[currentNode].position);
    float newSteer = (relativeVector.x / relativeVector.magnitude) * maxSteeringAngle;

    foreach (AxleInfo axleInfo in getAxleInfos.axleInfos)
    {
        axleInfo.leftWheel.steerAngle = newSteer;
        axleInfo.rightWheel.steerAngle = newSteer;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接