我有一个简单的汽车游戏,有一条直路。然而,道路的某些部分有一些拐角,我希望我的车能够通过这些拐角转向车轮。我已经为我的汽车创建了一些节点来驾驶。但是我的车继续直行。我不知道问题出在哪里。
下面是创建节点系统的代码:
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/