2015-09-26 268 views
0

我正在关注如何在Unity中制作汽车的这段视频(https://www.youtube.com/watch?v=kAEpLX3rfms)。但是我的车不会根据视频的速度降低转向角度。这个想法是,你可以在最慢的时候将汽车转向最大50度,然后以最快的速度转向10度。但它对汽车没有影响。有人能告诉我如何解决这个问题吗?如何根据Unity中的速度调整转向角?

代码:

public WheelCollider wheelFL; 
public WheelCollider wheelFR; 
public WheelCollider wheelRL; 
public WheelCollider wheelRR; 

public Transform wheelFL_Trans; 
public Transform wheelFR_Trans; 
public Transform wheelRL_Trans; 
public Transform wheelRR_Trans; 

public float lowSpeedSteerAngle; 
public float highSpeedSteerAngle; 
public float Torque; 
public float centerOfMassHeight; 

public float speed; 
public GameObject speedometer; 
public GameObject accelerator; 
public GameObject brake; 
public float pedalRotationFactor; 
public float speedometerRotationFactor; 
public float decelerationRate; 

public float currentSpeed; 
public float topSpeed; 
public float maxReverseSpeed; 

public GameObject trunk; 
public Material[] brakeMaterials; 

public float currentSteerAngle; 
public float turnAmount; 

private Vector3 com; 
private Rigidbody rigidBody; 
private float acceleratorSpeed; 
private float brakeSpeed; 

void Start() { 
    rigidBody = GetComponent<Rigidbody>(); 
    com = rigidBody.centerOfMass; 
    com.y = centerOfMassHeight; 
    rigidBody.centerOfMass = com; 
} 

void FixedUpdate() { 
    currentSpeed = 2 * Mathf.PI * wheelFL.radius * wheelFL.rpm * 60/1000; 
    if(currentSpeed < topSpeed && currentSpeed > -maxReverseSpeed){ 
     wheelFL.motorTorque = Torque * Input.GetAxis("Vertical"); 
     wheelFR.motorTorque = Torque * Input.GetAxis("Vertical"); 
     wheelRL.motorTorque = Torque * Input.GetAxis("Vertical"); 
     wheelRR.motorTorque = Torque * Input.GetAxis("Vertical"); 
    }else{ 
     wheelFL.motorTorque = 0; 
     wheelFR.motorTorque = 0; 
     wheelRL.motorTorque = 0; 
     wheelRR.motorTorque = 0; 
    } 


    if(!Input.GetButton("Vertical")){ 
     wheelFL.brakeTorque = decelerationRate; 
     wheelFR.brakeTorque = decelerationRate; 
     wheelRL.brakeTorque = decelerationRate; 
     wheelRR.brakeTorque = decelerationRate; 
    }else{ 
     wheelFL.brakeTorque = 0; 
     wheelFR.brakeTorque = 0; 
     wheelRL.brakeTorque = 0; 
     wheelRR.brakeTorque = 0; 
    } 

    if(Input.GetAxis("Vertical") < 0){ 
     //Changing The Materials 
     Material[] mats = trunk.GetComponent<Renderer>().materials; 
     mats[0] = brakeMaterials[1]; 

     trunk.GetComponent<Renderer>().materials = mats; 
    }else{ 
     //Reseting The Materials 
     Material[] mats = trunk.GetComponent<Renderer>().materials; 
     mats[0] = brakeMaterials[0]; 

     trunk.GetComponent<Renderer>().materials = mats; 
    } 

    speed = GetComponent<Rigidbody>().velocity.magnitude * 15; 
    float speedFactor = 1 - (GetComponent<Rigidbody>().velocity.magnitude * 3.6f/topSpeed); 
    currentSteerAngle = highSpeedSteerAngle + ((lowSpeedSteerAngle - highSpeedSteerAngle) * speedFactor); 
    turnAmount = currentSteerAngle * Input.GetAxis("Horizontal"); 
    wheelFL.steerAngle = turnAmount; 
    wheelFR.steerAngle = turnAmount; 
} 

void Update() { 
    wheelFL_Trans.Rotate(0, 0, wheelFL.rpm/60 * 360 * Time.deltaTime); 
    wheelFR_Trans.Rotate(0, 0, wheelFR.rpm/60 * 360 * Time.deltaTime); 
    wheelRL_Trans.Rotate(0, 0, wheelRL.rpm/60 * 360 * Time.deltaTime); 
    wheelRR_Trans.Rotate(0, 0, wheelRR.rpm/60 * 360 * Time.deltaTime); 

    Vector3 wheelSteerAngle = wheelFL_Trans.localEulerAngles; 
    wheelSteerAngle.y = turnAmount + 90; 
    wheelFL_Trans.localEulerAngles = wheelSteerAngle; 
    wheelFR_Trans.localEulerAngles = wheelSteerAngle; 

    if(Input.GetKeyDown(KeyCode.P)){ 
     Vector3 resetPosition = new Vector3(transform.position.x, 1.5f, transform.position.z); 
     Quaternion resetRotation = Quaternion.Euler(0f, 0f, 0f); 

     //Reseting Velocity 
     GetComponent<Rigidbody>().velocity = new Vector3(0f, 0f, 0f); 

     //Reseting Rotation 
     transform.rotation = resetRotation; 

     //Reseting Position 
     transform.position = resetPosition; 

     //Reseting Motor Torque and Steering Angle 
     wheelFL.motorTorque = 0f; 
     wheelFR.motorTorque = 0f; 
     wheelRL.motorTorque = 0f; 
     wheelRR.motorTorque = 0f; 

     wheelFL.steerAngle = 0f; 
     wheelFR.steerAngle = 0f; 
     wheelRL.steerAngle = 0f; 
     wheelRR.steerAngle = 0f; 
    } 

    acceleratorSpeed = wheelFL.motorTorque; 
    brakeSpeed = wheelFL.motorTorque; 

    if(acceleratorSpeed < 0){ 
     acceleratorSpeed = 0; 
    } 

    if(brakeSpeed > 0){ 
     brakeSpeed = 0; 
    } 

    if(speed >= 350){ 
     speed = 350; 
    } 

    speedometer.transform.localRotation = Quaternion.Euler(speed * speedometerRotationFactor - 100, 90f, 0f); 
    accelerator.transform.localRotation = Quaternion.Euler(acceleratorSpeed * pedalRotationFactor, 0f, 0f); 
    brake.transform.localRotation = Quaternion.Euler(brakeSpeed * pedalRotationFactor * -1, 0f, 0f); 

} 

回答

1

我假设你设置了kmph或mph的maxSpeed,是吗?您应该注意velocity.magnitude以m/s为单位返回速度,需要将其转换为您在汽车脚本中用于加速的单位。如果是米/秒至公里/小时,则可以将速度大小乘以3.6。如果是米/秒到英里/小时,那么乘以2.2369362920544。所以,你现在speedFactor将

float speedFactor = GetComponent<Rigidbody>().velocity.magnitude * 3.6f/maxSpeed; //or magnitude * 2.236936f for miles/h 
+0

没有效果,汽车在低速时仍然以高速转动相同的数量。 –

+0

你的车的最高速度是多少?使currentSpeedAngle成为公共变量或将其序列化,以便它在检查器中显示,然后检查其值。如果速度降低到highSpeedSteerAngle的速度接近maxSpeed,则物理或控制器出现问题。 PS你没有使用输入来调节转向? – EvilTak

+0

最高速度是40.我刚刚制作了当前Speedpengle公开,价值徘徊在30左右。我也对turnAmount做了同样的处理(来自gamedev的答案)。那只是回到原点而已;值不受速度的影响。我已经将代码更新为现在的顺序。另外,通过使用输入来调节转向,你的意思是什么? –

0

我不是在单位的专家,但它看起来像

public float lowSpeedSteerAngle; 
public float highSpeedSteerAngle; 

可能是你的问题。除非我遗漏了一些东西,否则这些变量会被声明并被调用,而不会为其分配任何值。

+0

者的值在检查分配,高速一个是10,另一个是30 –

+0

之前所做的编辑,你有 'currentSteerAngle = Mathf.Lerp (highSpeedSteerAngle,lowSpeedSteerAngle,speedFactor)' 您的角度排序错误。他们应该是'Mathf.Lerp(lowSPeedSteerAngle,highSpeedSteerAngle,speedFactor)' 你从speedFactor得到什么样的结果? 以您目前的 式'currentSteerAngle = highSpeedSteerAngle +((lowSpeedSteerAngle - highSpeedSteerAngle)* speedFactor);' 如果速度因子是在0和1之间,则在全速你将返回30. @MatthewInglis的角度 – OddBall

+0

速度因数在低速时大约为1,在高速时大约为0。 –