c# - Unity汽车自行转向

标签 c# unity3d game-physics game-development

我有一个简单的汽车游戏,有一条直路。然而,道路的某些部分有一些拐角,我希望我的车能够通过这些拐角转向车轮。我已经为我的汽车创建了一些节点来驾驶。但是我的车继续直行。我不知道问题出在哪里。

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);
            }
        }
    }
}

最佳答案

无需查看 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;
    }
}

关于c# - Unity汽车自行转向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66736481/

相关文章:

c# - unity 更新运动向量。矢量值的物理意义

c++ - D3D11 : E_OUTOFMEMORY when mapping vertex buffer

unity3d - 如何在 Cardboard Unity SDK (Unity 5.6) 中检测 Cardboard 按钮按下

c# - 在 C#/XNA 中使用通用函数进行碰撞检测

c# - Unity 2D Top Down Shooter运动问题C#

actionscript-3 - AS3 角色仅在一个方向停在墙壁上

c# - C# 中相当于 Java 中的 List 和 Iterator 的是什么?

c# - 如何在 .NET 中以 SOLID 方式实现库级跟踪和诊断?

c# - 将 "nameof"关键字与仅设置属性一起使用

c# - 需要帮助调用 Web Api Controller 方法来检索数据