问题描述
我有一个简单的汽车游戏,有一条直线。但是,道路的某些部分有一些拐角,我希望我的汽车通过这些点来引导车轮。我为我的汽车创建了一些节点来转向。但我的车继续直行。我不知道问题出在哪里。
这里是创建节点系统的代码:
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;
}
}