# unity3d跑车游戏视频教程

www.MyException.Cn  网友分享于：2015-03-25  浏览：0次
unity3d赛车游戏视频教程

1. 摄像头跟随

```using UnityEngine;
using System.Collections;

public class CameraFollowScript : MonoBehaviour {

public GameObject car;
public float distance = 5;
public float heightDiff = 3;

public float angleDamping = 1.5f; // 缓冲系数
public float heightDamping = 1f;

public float defaultFOV = 60;
public float zoomRatio = 1.2f;

private float dstAngleWithDirection = 0;

// Use this for initialization
void Start () {

}
// Update is called once per frame
void Update () {
float myH = transform.position.y;
float dstH = car.transform.position.y + heightDiff;
float retH = Mathf.Lerp(myH, dstH, heightDamping * Time.deltaTime);

float myAngle =  transform.eulerAngles.y;
float dstAngle = dstAngleWithDirection;
float retAngle = Mathf.LerpAngle(myAngle, dstAngle, angleDamping * Time.deltaTime);
Quaternion retRotation = Quaternion.Euler(0, retAngle, 0);

transform.position = car.transform.position;
transform.position -= (retRotation * Vector3.forward * distance);
Vector3 temp = transform.position;
temp.y = retH;
transform.position = temp;

transform.LookAt(car.transform);
}

void FixedUpdate()
{
Vector3 v = car.rigidbody.velocity;
//Vector3 faceDirection = car.transform.forward;
//float dot = Vector3.Dot(v, faceDirection); // 点积
Vector3 carLocalV = car.transform.InverseTransformDirection(v);

float dstAnleY = car.transform.eulerAngles.y;
if ( carLocalV.z < -0.01f )
dstAngleWithDirection = dstAnleY + 180;
else
dstAngleWithDirection = dstAnleY;

float speed = v.magnitude;
camera.fieldOfView = defaultFOV + speed * zoomRatio;
}
}
```

2. 汽车的控制

```using UnityEngine;
using System.Collections;

public class CarMoveController : MonoBehaviour {

public WheelCollider wheelFL;
public WheelCollider wheelFR;
public WheelCollider wheelRL; // rear  left
public WheelCollider wheelRR;

public Transform wheelFLTransform;
public Transform wheelFRTransform;
public Transform wheelRLTransform;
public Transform wheelRRTransform;

public float MAXTORQUE = 50;
public float MaxAngleAtLowSpeed = 10f;
public float MaxAngleAtHighSpeed = 1f;
public float maxBrakeTorque = 100f;

public float slipForwardStiff = 0.04f;
public float slipSteerStiff = 0.025f;

public float initForwardStiff;
public float initSteerStiff;

// audio control
public int gearCount = 4;
public float minGearSoundPitch = 1.0f;
public float maxGearSoundPitch = 3.0f;

public AudioSource brakeAudioSource;

public float highSpeed = 50;
//private
public  float curSpeed;
public int curGearLevel;

private float initRotationFL = 0f;
private float initRotationFR = 0f;
private bool braked = false;
private float MAX_VILOCITY_FOR_STEER = 40f;
private float[] gearLevelSpeed;

// Use this for initialization
void Start () {
Vector3 temp = rigidbody.centerOfMass;
temp.y -= 0.8f;
rigidbody.centerOfMass = temp;

initForwardStiff = wheelRL.forwardFriction.stiffness;
initSteerStiff = wheelRL.sidewaysFriction.stiffness;

SeperateGearSpeedLevel();
}

private void SeperateGearSpeedLevel()
{
float gearRange = highSpeed / gearCount;

gearLevelSpeed = new float[gearCount + 1];

gearLevelSpeed[0] = 0f;

for (int i = 0; i < gearCount; i ++)
{
gearLevelSpeed[i + 1] = gearRange * (i + 1);
}
}

void FixedUpdate () {
float v = Input.GetAxis("Vertical");
float h = Input.GetAxis("Horizontal");

curSpeed = rigidbody.velocity.magnitude;
if( curSpeed < highSpeed )
{
wheelRL.motorTorque = MAXTORQUE * v;//力矩
wheelRR.motorTorque = MAXTORQUE * v;//力矩
}
else
{
wheelRL.motorTorque = 0;//力矩
wheelRR.motorTorque = 0;//力矩
}

float speedFactor = rigidbody.velocity.magnitude / MAX_VILOCITY_FOR_STEER;
float steerFacter = Mathf.Lerp(MaxAngleAtLowSpeed, MaxAngleAtHighSpeed, speedFactor);

wheelFL.steerAngle = steerFacter * h; // 方向的偏移角度
wheelFR.steerAngle = steerFacter * h;

HandBrake();
}

private void HandBrake()
{
braked = false;
if (Input.GetButton("Jump"))
{
braked = true;
}

if (braked)
{
wheelFL.brakeTorque = maxBrakeTorque;
wheelFR.brakeTorque = maxBrakeTorque;

wheelRL.motorTorque = 0;
wheelRR.motorTorque = 0;

SetWheelFrictionStiff(wheelRL, slipForwardStiff, slipSteerStiff);
SetWheelFrictionStiff(wheelRR, slipForwardStiff, slipSteerStiff);
}
else
{
wheelFL.brakeTorque = 0;
wheelFR.brakeTorque = 0;

SetWheelFrictionStiff(wheelRL, initForwardStiff, initSteerStiff);
SetWheelFrictionStiff(wheelRR, initForwardStiff, initSteerStiff);
}

}

private void SetWheelFrictionStiff(WheelCollider wheelRL, float slipForwardStiff, float slipSteerStiff)
{
WheelFrictionCurve temp = wheelRL.forwardFriction;
temp.stiffness = slipForwardStiff;
wheelRL.forwardFriction = temp;

temp = wheelRL.sidewaysFriction;
temp.stiffness = slipSteerStiff;
wheelRL.sidewaysFriction = temp;
}

void Update(){
initRotationFL += wheelFL.rpm * 360 * Time.deltaTime/ 60;
initRotationFL = Mathf.Repeat(initRotationFL, 360);
setFinalRotation(wheelFLTransform, initRotationFL, wheelFL.steerAngle);

initRotationFR += wheelFR.rpm * 360 * Time.deltaTime/ 60;
initRotationFR = Mathf.Repeat(initRotationFR, 360);
setFinalRotation(wheelFRTransform, initRotationFR, wheelFR.steerAngle);
//wheelFLTransform.Rotate(, 0, 0);  // round per minute
//wheelFRTransform.Rotate(wheelFR.rpm * 360 * Time.deltaTime/ 60, 0, 0);  // round per minute
wheelRLTransform.Rotate(wheelRL.rpm * 360 * Time.deltaTime/ 60, 0, 0);  // round per minute
wheelRRTransform.Rotate(wheelRR.rpm * 360 * Time.deltaTime/ 60, 0, 0);  // round per minute

// relative distance of wheel and car body
SetWheelPos(wheelFRTransform, wheelFR);
SetWheelPos(wheelFLTransform, wheelFL);
SetWheelPos(wheelRRTransform, wheelRR);
SetWheelPos(wheelRLTransform, wheelRL);

EngineSound(curSpeed);

}
private void EngineSound(float curSpeed)
{
//gearLevelSpeed
float gearMinSpeed = 0;
float gearMaxSpeed = 20;

for (int i = 0; i < gearLevelSpeed.Length; i ++)
{
if (curSpeed >= gearLevelSpeed[i] && curSpeed < gearLevelSpeed[i + 1] + 2)
{
gearMinSpeed = gearLevelSpeed[i];
gearMaxSpeed = gearLevelSpeed[i + 1];

curGearLevel = i;
break;
}
}

float ratio = (curSpeed - gearMinSpeed) / (gearMaxSpeed - gearMinSpeed);
ratio = ratio > 1 ? 1 : ratio;

audio.pitch = minGearSoundPitch + ratio * (maxGearSoundPitch - minGearSoundPitch);

if (braked && curSpeed > 0.2f)
{
if (!brakeAudioSource.isPlaying)
brakeAudioSource.Play();
}
else
{
brakeAudioSource.Stop();
}
}

private void SetWheelPos(Transform wheelFRTransform, WheelCollider wheelFR)
{
RaycastHit hitPoint;
bool isGrounded = Physics.Raycast(wheelFR.transform.position, -1 * wheelFR.transform.up, out hitPoint,

if (isGrounded)
{
if ((hitPoint.point - wheelFR.transform.position).sqrMagnitude < 0.16f)
{
wheelFRTransform.position = wheelFR.transform.position;
}
else
{
wheelFRTransform.position = hitPoint.point + wheelFR.transform.up * wheelFR.radius;
}

}
else
{
wheelFRTransform.position = wheelFR.transform.position - wheelFR.transform.up * wheelFR.suspensionDistance;
}
}
void setFinalRotation(Transform trans, float angle, float yAngle){
Vector3 ea = new Vector3(angle, yAngle, 0);
trans.localRotation = Quaternion.Euler(ea);
}
}
```