using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using RGSK;
public class TestCar_Controller : MonoBehaviour
{
public Rigidbody rigidBody;
public Camera cam_Car;
public Collider car_Collider;
public Transform dx;
public Vector3 centerOfMass = Vector3.zero;
public AnimationCurve ac;
//定义变量
public float reverseSpeed = 5.0f; //反向速度
public float turnSpeed = 0.6f; //转弯速度
public float turnNorAngle = 60;
public float turnNitroAngle = 90;
float turnNitorAngleTemp = 0;
public bool driftState = false;
/// <summary>
/// 转弯轮胎角度
/// </summary>
public float turnTireAngleChange = 0;
//Engine values
public float engineTorque = 800.0f; //avoid setting this value too high inorder to not overpower the wheels!
private float moveDirection = 0.0f; //移动方向
private float turnDirection = 0.0f; //转弯方向
public float currentSpeed = 0.0f; //当前速度
public float currentSpeed1 = 0.0f; //当前速度
public float downforce = 100.0f;
public float antiRollAmount = 8000.0f;
/// <summary>
/// 沉睡状态 不能启动
/// </summary>
public bool isSleeping = false;
public int direction = 1; // Reverse Gear Currently.
/// <summary>
/// 氮气加的力
/// </summary>
private float fNitroAddFroce = 10000;
/// <summary>
/// 氮气加速
/// </summary>
[SerializeField]
AnimationCurve animNitroAcceleration;
/// <summary>
/// 氮气
/// </summary>
public bool usingNitro;
public bool usingPiaoyi;
public bool startPiaoyi = false;
/// <summary>
/// 开始漂移状态
/// </summary>
public float startPiaoyiStateSteer = 0;
public bool bCarTengKong = false;
public float motorInput;
public float brakeInput;
public float steerInput;
public float handbrakeInput;
public bool pulseon;
public bool iszhuanwan = false;
public bool autoAcceleration;
//Wheel Colliders
public Transform FL_Transform;
public Transform FR_Transform;
public Transform RL_Transform;
public Transform RR_Transform;
public WheelCollider FL_WheelCollider;
public WheelCollider FR_WheelCollider;
public WheelCollider RL_WheelCollider;
public WheelCollider RR_WheelCollider;
public float rawEngineRPM = 0f; // Actual engine RPM.
public float engineRPM = 0f; // Smoothed engine RPM.
public float minEngineRPM = 1000f; // Minimum Engine RPM.
public float maxEngineRPM = 7000f; // Maximum Engine RPM.
[Range(.75f, 2f)]
public float engineInertia = 1f; // Inertia of the engine.
public AudioSource engineAudio;
public AudioSource nitroAudio;
// Gears.
[System.Serializable]
public class Gear
{
public float maxRatio;
public int maxSpeed;
public int targetSpeedForNextGear;
public AnimationCurve torqueCurve;
public void SetGear(float ratio, int speed, int targetSpeed)
{
maxRatio = ratio;
maxSpeed = speed;
targetSpeedForNextGear = targetSpeed;
}
}
public Gear[] gears;
public int totalGears = 6; // Total count of gears.
public int currentGear = 0; // Current Gear Of The Vehicle.
[Range(0f, .5f)]
public float gearShiftingDelay = .35f;
[Range(.25f, .8f)]
public float gearShiftingThreshold = .75f;
[Range(.1f, .9f)]
public float clutchInertia = .25f;
private float orgGearShiftingThreshold; // Original Gear Shifting Threshold.
public bool changingGear = false; // Changing Gear Currently.
public bool NGear = false; // N Gear.
public bool automaticGear = true;
// Inputs.
public float gasInput = 0f;
internal float _gasInput
{
get
{
if (_fuelInput <= 0f)
return 0f;
if (!automaticGear)
{
if (!changingGear && !cutGas)
return Mathf.Clamp01(gasInput);
else
return 0f;
}
else
{
if (!changingGear && !cutGas)
return Mathf.Clamp01(gasInput);
else
return 0f;
}
}
set { gasInput = value; }
}
internal float _fuelInput
{
get
{
return Input.GetAxis("Vertical");
}
set { fuelInput = value; }
}
/// <summary>
/// 离合器输入
/// </summary>
public float clutchInput = 1f;
public float idleInput = 0f;
public float fuelInput = 0f;
public bool cutGas = false;
/// <summary>
/// 加速度
/// </summary>
float acceleration = 0;
private void Start()
{
car_Collider = transform.GetChildComponent<Collider>("Collider");
rigidBody.centerOfMass = centerOfMass;
if (!cam_Car && GameObject.FindGameObjectWithTag("PlayCamera"))
{
Transform target = GameObject.FindGameObjectWithTag("PlayCamera").transform;
cam_Car = target.GetComponent<Camera>();
}
CreateGearCurves();
}
bool input = false;
bool bOneStart = true;
private void Update()
{
if (RaceManager.instance.raceCompleted)
{
isSleeping = false;
}
if (RaceManager.instance.raceStarted && bOneStart)
{
isSleeping = true;
clutchInput = 0;
gasInput = 0;
bOneStart = false;
int tempGear = 1;
tempGear = (int)(engineRPM * 1.1f / (maxEngineRPM / 6.0f));
acceleration = acceleration * 0.7f;
//完美起步,有部分氮气//
if (tempGear == 4 || tempGear == 5)
{
nitroTime = 2;
}
TestUI.Instance.showTip(tempGear);
}
if ((iszhuanwan) || Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.D))
{
input = true;
}
if ((!iszhuanwan) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.D))
{
input = false;
vel = rigidBody.transform.localEulerAngles;
vel.y -= an;
//rigidBody.transform.localEulerAngles = vel;
//Quaternion velRotation = Quaternion.AngleAxis(-an, Vector3.up);
//rigidBody.velocity = velRotation * rigidBody.velocity;
//rigidBody.MoveRotation(Quaternion.Euler(vel));
}
if (dx) dx.eulerAngles = new Vector3(0, cam_Car.transform.eulerAngles.y, 0);
WheelAllignment();
}
private void OnGUI()
{
//GUIStyle fontStyle = new GUIStyle();
//fontStyle.normal.background = null; //设置背景填充
//fontStyle.normal.textColor = new Color(1, 0, 0); //设置字体颜色
//fontStyle.fontSize = 40; //字体大小
//GUI.Label(new Rect(100, 200, 600, 300), transform.InverseTransformDirection(rigidBody.velocity).ToString(), fontStyle);
}
public float wheelRPM = 0;
void FixedUpdate()
{
//当前速度赋值
currentSpeed = Mathf.Abs(transform.InverseTransformDirection(rigidBody.velocity).z) * 3.6f;
currentSpeed1 = rigidBody.velocity.magnitude * 5f;
engineAudio.pitch = 1 + currentSpeed1 / 260;
TestUI.Instance.SetSpeed(currentSpeed1);
float wheelLRPMToSpeed = (((FL_WheelCollider.rpm * FL_WheelCollider.radius) / 2.9f)) * rigidBody.transform.lossyScale.y;
float wheelRRPMToSpeed = (((FR_WheelCollider.rpm * FR_WheelCollider.radius) / 2.9f)) * rigidBody.transform.lossyScale.y;
wheelRPM = (wheelLRPMToSpeed + wheelRRPMToSpeed);
// Debug.Log("motorTorque:" + FL_WheelCollider.motorTorque + "wheelLRPMToSpeed:" + wheelLRPMToSpeed + ",wheelRRPMToSpeed:" + wheelRRPMToSpeed + ",clutchInput" + clutchInput + ",gasInput" + gasInput + ",idleInput" + idleInput);
if (gasInput > 0.01f)
//clutchInput 离合器输入
{
float clamp01V = Mathf.Clamp01(Mathf.Lerp(0f, 1f, (1f - clutchInput) * (((wheelRPM * direction) / 2f) / gears[currentGear].maxSpeed)) + (((gasInput) * clutchInput) + idleInput));
//float clamp01V = Mathf.Clamp01(Mathf.Lerp(0f, 1f, (1f - 1) * (((wheelRPM * 1) / 2f) / gears[currentGear].maxSpeed)) + (((1) * 1) + 1));
float targetV = (maxEngineRPM * 1.1f) * clamp01V;
float clampV = Mathf.MoveTowards(rawEngineRPM, targetV, engineInertia * 100f);
rawEngineRPM = Mathf.Clamp(clampV, 0f, maxEngineRPM * 1.1f);
rawEngineRPM *= 1;
// Debug.Log("离合器输入 rawEngineRPM:" + rawEngineRPM);
}
else
{
maxEngineRPM = 7000;
float clamp01V = Mathf.Clamp01(Mathf.Lerp(0f, 1f, (1f - clutchInput) * (((wheelRPM * direction) / 2f) / gears[currentGear].maxSpeed)));
float targetV = (maxEngineRPM * 1.1f) * clamp01V;
float clampV = Mathf.MoveTowards(rawEngineRPM, targetV, engineInertia * 100f);
float minRPM = 0;
float MaxRPM = 0;
if (currentGear <= 0)
{
rawEngineRPM = Mathf.Clamp(clampV, 1000f, maxEngineRPM * 1.1f);
minRPM = 1000;
MaxRPM = 4000;
// rawEngineRPM = Mathf.Lerp(1000, 4000,(currentSpeed1- gears[currentGear].targetSpeedForNextGear) / (float)(gears[currentGear].maxSpeed - gears[currentGear].targetSpeedForNextGear) * Random.Range(0.5f, 1));
}
else if (currentGear == 1)
{
rawEngineRPM = Mathf.Clamp(clampV, 4000f, maxEngineRPM * 1.1f);
minRPM = 3500;
MaxRPM = 6000;
// rawEngineRPM = Mathf.Lerp(3500, 6000, (currentSpeed1 - gears[currentGear].targetSpeedForNextGear) / (float)(gears[currentGear].maxSpeed - gears[currentGear].targetSpeedForNextGear) * Random.Range(0.5f, 1));
}
else if (currentGear == 2)
{
rawEngineRPM = Mathf.Clamp(clampV, 5000f, maxEngineRPM * 1.1f);
minRPM = 5000;
MaxRPM = 7700;
// rawEngineRPM = Mathf.Lerp(5000, 7700, (currentSpeed1 - gears[currentGear].targetSpeedForNextGear) / (float)(gears[currentGear].maxSpeed - gears[currentGear].targetSpeedForNextGear) * Random.Range(0.5f, 1));
}
else if (currentGear == 3)
{
rawEngineRPM = Mathf.Clamp(clampV, 5000f, maxEngineRPM * 1.1f);
minRPM = 5000;
MaxRPM = 7700;
// rawEngineRPM = Mathf.Lerp(5000, 7700, (currentSpeed1 - gears[currentGear].targetSpeedForNextGear) / (float)(gears[currentGear].maxSpeed - gears[currentGear].targetSpeedForNextGear) * Random.Range(0.5f, 1));
}
else if (currentGear == 4)
{
rawEngineRPM = Mathf.Clamp(clampV, 5000f, maxEngineRPM * 1.1f);
minRPM = 5000;
MaxRPM = 7700;
// rawEngineRPM = Mathf.Lerp(5000, 7700, (currentSpeed1 - gears[currentGear].targetSpeedForNextGear) / (float)(gears[currentGear].maxSpeed - gears[currentGear].targetSpeedForNextGear) * Random.Range(0.5f, 1));
}
else if (currentGear == 5)
{
rawEngineRPM = Mathf.Clamp(clampV, 5000f, maxEngineRPM * 1.1f);
minRPM = 5000;
MaxRPM = 7700;
//rawEngineRPM = Mathf.Lerp(5000, 7700, (currentSpeed1 - gears[currentGear].targetSpeedForNextGear) / (float)(gears[currentGear].maxSpeed - gears[currentGear].targetSpeedForNextGear)*Random.Range(0.5f,1));
}
if (nitroEnable)
{
minRPM = 8000;
MaxRPM = 9500;
maxEngineRPM = 9500;
}
float lerpT = (currentSpeed1 - gears[currentGear].targetSpeedForNextGear) / (float)(gears[currentGear].maxSpeed - gears[currentGear].targetSpeedForNextGear);
if (lerpT >= 0.9f)
lerpT = lerpT * Random.Range(0.9f, 1);
rawEngineRPM = Mathf.Lerp(minRPM, MaxRPM, lerpT);
}
engineRPM = Mathf.Lerp(engineRPM, rawEngineRPM, Mathf.Lerp(Time.fixedDeltaTime * 5f, Time.fixedDeltaTime * 50f, rawEngineRPM / maxEngineRPM));
TestUI.Instance.SetRpm(engineRPM);
if (!isSleeping)
{
int tempGear = 1;
tempGear = (int)(engineRPM * 1.1f / (maxEngineRPM / 6.0f));
TestUI.Instance.SetGear(tempGear);
}
//if (currentSpeed1 > 100)
// Debug.Log(time);
Drive();
Turn();
GearBox();
//Clutch ();
Nitro();
ApplyDownforce();
StabilizerBars();
}
public Vector3 vel;
public Vector3 vvv;
public float an;
float time = 0;
void Drive()
{
if (!isSleeping)
{
if (pulseon)
{
clutchInput = 1;
if (acceleration < 1)
acceleration += Time.fixedDeltaTime * 1.2f;
if (acceleration >= 1)
acceleration = 1;
}
else
{
if (acceleration > 0)
acceleration -= Time.fixedDeltaTime * 0.8f;
}
gasInput = acceleration;
}
//移动
if ((autoAcceleration || Input.GetAxis("Vertical") > 0.0f) && isSleeping)//上键
{
time += Time.deltaTime;
float en = ac.Evaluate(Input.GetAxis("Vertical"));
if (currentGear <= 0)
{
if (acceleration < 12000 / engineTorque)
acceleration += Time.fixedDeltaTime * 1.2f;
}
else if (currentGear == 1)
{
if (acceleration < 18000 / engineTorque)
acceleration += Time.fixedDeltaTime * 1.0f;
}
else if (currentGear == 2)
{
if (acceleration < 26000 / engineTorque)
acceleration += Time.fixedDeltaTime * 0.3f;
}
else if (currentGear == 3)
{
if (acceleration < 36000 / engineTorque)
acceleration += Time.fixedDeltaTime * 0.3f;
}
else if (currentGear == 4)
{
if (acceleration < 49000 / engineTorque)
acceleration += Time.fixedDeltaTime * 0.2f;
}
else if (currentGear == 5)
{
if (acceleration < 60000 / engineTorque)
acceleration += Time.fixedDeltaTime * 0.1f;
}
moveDirection = acceleration * engineTorque;
//moveDirection = 0;
WheelHit FrontWheelHit;
bool groundedFL = FL_WheelCollider.GetGroundHit(out FrontWheelHit);
if (groundedFL)
{
rigidBody.AddRelativeForce(0, 0, moveDirection);
//rigidBody.AddForce(dx.transform.forward * engineTorque);
}
// ApplyWheel(engineTorque);
ApplyWheel(10);
//if (currentSpeed1 > 100f&& currentSpeed1<110)//速度达到一定值转弯
//{
// Debug.Log("速度100 时间:"+time);
//}
//if (currentSpeed1 > 250f)//速度达到一定值转弯
//{
// Debug.Log("速度250 时间:" + time);
//}
}
//if (Input.GetAxis("Horizontal") != 0)
//{
// if (!input) return;
// turnDirection = Input.GetAxis("Horizontal") * turnSpeed;
// //rigidBody.AddRelativeTorque(0, turnDirection, 0);
// //FL_WheelCollider.steerAngle = 30 * Input.GetAxis("Horizontal");
// //FR_WheelCollider.steerAngle = 30 * Input.GetAxis("Horizontal");
// //rigidBody.AddForceAtPosition(FL_WheelCollider.transform.right * turnDirection, FL_WheelCollider.transform.position );
// //rigidBody.AddForceAtPosition(FR_WheelCollider.transform.right * turnDirection, FR_WheelCollider.transform.position );
// //rigidBody.AddForceAtPosition(RL_WheelCollider.transform.right * -turnDirection, RL_WheelCollider.transform.position);
// //rigidBody.AddForceAtPosition(RR_WheelCollider.transform.right * -turnDirection, RR_WheelCollider.transform.position);
//}
//if (Input.GetAxis("Vertical") < 0.0f)//下键
//{
// moveDirection = Input.GetAxis("Vertical") * reverseSpeed;
// rigidBody.AddRelativeForce(0, 0, moveDirection);
// ApplyWheel(-engineTorque);
// //if (currentSpeed > 0.05f)//速度达到一定值转弯
// {
// turnDirection = Input.GetAxis("Horizontal") * turnSpeed;
// rigidBody.AddRelativeTorque(0, -turnDirection, 0);
// }
//}
//阻力
float maxAngularDrag = 1.5f; //最大阻力(转弯)
float currentAngularDrag = 1.0f; //当前阻力(转弯)
float aDragLerpTime = currentSpeed * 0.1f; //间隔时间(转弯)
float maxDrag = 1.0f; //最大阻力
float currentDrag = 0.35f; //当前阻力
float dragLerpTime = currentSpeed * 0.1f; //间隔时间
//float myAngularDrag = Mathf.Lerp(currentAngularDrag, maxAngularDrag, aDragLerpTime); //得出阻力(转弯)
//float myDrag = Mathf.Lerp(currentDrag, maxDrag, dragLerpTime); //得出阻力
阻力赋值到车上
//rigidBody.angularDrag = myAngularDrag;
//rigidBody.drag = myDrag;
if (currentGear <= 0)
{
maxDrag = 0.4f;
maxAngularDrag = 1.0f;
}
else if (currentGear == 1)
{
maxDrag = 0.45f;
maxAngularDrag = 1.0f;
}
else if (currentGear == 2)
{
maxDrag = 0.5f;
maxAngularDrag = 1.2f;
}
else if (currentGear == 3)
{
maxDrag = 0.55f;
maxAngularDrag = 1.4f;
}
else if (currentGear == 4)
{
maxDrag = 0.6f;
maxAngularDrag = 2.0f;
}
else if (currentGear == 5)
{
maxDrag = 0.7f;
maxAngularDrag = 2.5f;
}
float myDrag = Mathf.Lerp(currentDrag, maxDrag, dragLerpTime); //得出阻力
rigidBody.drag = myDrag;
float myAngularDrag = Mathf.Lerp(currentAngularDrag, maxAngularDrag, aDragLerpTime); //得出阻力(转弯)
rigidBody.angularDrag = myAngularDrag;
}
float piaoyiTempforwardSpeed = 0;
private void Turn()
{
if (isSleeping)
{
if (usingPiaoyi)
{
RL_WheelCollider.GetComponent<RGSK.Wheels>().shouldEmit = true;
RR_WheelCollider.GetComponent<RGSK.Wheels>().shouldEmit = true;
}
else
{
RL_WheelCollider.GetComponent<RGSK.Wheels>().shouldEmit = false;
RR_WheelCollider.GetComponent<RGSK.Wheels>().shouldEmit = false;
}
}
if ((iszhuanwan || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)) && isSleeping)
{
if (bIsCollision)
{
Vector3 dir = transform.InverseTransformDirection(rigidBody.velocity);
piaoyiTempforwardSpeed = dir.z;
if (steerInput > 0)
dir.x += 5 * Time.deltaTime;
else
dir.x -= 5 * Time.deltaTime;
rigidBody.velocity = transform.TransformDirection(dir);
}
float h = steerInput;// Input.GetAxis("Horizontal");
//driftState = Input.GetKey(KeyCode.L);
if (usingPiaoyi)
{
//漂移时切换方向,高速时 取消漂移,低速时随机//
if (startPiaoyi == true)
{
startPiaoyiStateSteer = steerInput;
startPiaoyi = false;
//Vector3 dir = transform.InverseTransformDirection(rigidBody.velocity);
//piaoyiTempforwardSpeed = dir.z;
//dir.z = 0;
//rigidBody.velocity = transform.TransformDirection(dir);
}
else
{
float value = startPiaoyiStateSteer * steerInput;
if (value < 0)
{
//Vector3 dir = transform.InverseTransformDirection(rigidBody.velocity);
//dir.z = piaoyiTempforwardSpeed;
//rigidBody.velocity = transform.TransformDirection(rigidBody.velocity);
startPiaoyiStateSteer = steerInput;
StartCoroutine("WaitPiaoYiEnd");
}
}
//漂移时加氮气//
if (!usingNitro && nitroTime < 5)
nitroTime += Time.fixedDeltaTime * 0.5f;
float turn = h * turnNitroAngle * Time.fixedDeltaTime * 1;
turnNitorAngleTemp = turn;
Quaternion turnRotation = Quaternion.Euler(0f, turn, 0f);
rigidBody.MoveRotation(rigidBody.rotation * turnRotation);
FL_Transform.localEulerAngles = new Vector3(0, -h * 30, 0);
FR_Transform.localEulerAngles = new Vector3(0, -h * 30, 0);
//rigidBody.AddForceAtPosition(FR_WheelCollider.transform.TransformDirection(Vector3.right * turn) * 1.8f * rigidBody.mass, FR_WheelCollider.transform.position);
//rigidBody.AddForceAtPosition(FL_WheelCollider.transform.TransformDirection(Vector3.right * turn) * 1.8f * rigidBody.mass, FL_WheelCollider.transform.position);
}
else
{
float turn = h * turnNorAngle * Time.fixedDeltaTime;
Quaternion turnRotation = Quaternion.Euler(0f, turn, 0f);
rigidBody.MoveRotation(rigidBody.rotation * turnRotation);
rigidBody.AddRelativeForce(h * turnSpeed, 0, 0);
if (currentGear >= 4)
{
if (!nitroEnable)
rigidBody.AddRelativeForce(0, 0, -acceleration / 8.0f * engineTorque);
//rigidBody.AddForce(dx.transform.forward * engineTorque);
}
FL_Transform.localEulerAngles = new Vector3(0, h * 30, 0);
FR_Transform.localEulerAngles = new Vector3(0, h * 30, 0);
//rigidBody.AddForceAtPosition(FR_WheelCollider.transform.TransformDirection(Vector3.right * turn) * rigidBody.mass * 1.8f, FR_WheelCollider.transform.position);
//rigidBody.AddForceAtPosition(FL_WheelCollider.transform.TransformDirection(Vector3.right * turn) * rigidBody.mass * 1.8f, FL_WheelCollider.transform.position);
//if (h > 0)
//{
// rigidBody.AddForceAtPosition(RL_WheelCollider.transform.right * -h * turnNorAngle * 100, RL_WheelCollider.transform.position);
// rigidBody.AddForceAtPosition(RR_WheelCollider.transform.right * -h * turnNorAngle * 100, RR_WheelCollider.transform.position);
//}
//else
//{
// rigidBody.AddForceAtPosition(RL_WheelCollider.transform.right * -h * turnNorAngle * 100, RL_WheelCollider.transform.position);
// rigidBody.AddForceAtPosition(RR_WheelCollider.transform.right * -h * turnNorAngle * 100, RR_WheelCollider.transform.position);
//}
}
}
else
{
Quaternion rotation = Quaternion.Euler(0.0f, 0.0f, 0.0f);
FL_Transform.localRotation = Quaternion.Lerp(FL_Transform.localRotation, rotation, Time.deltaTime * 0.5f); //得出阻力 new Vector3(0, 0, 0);
FR_Transform.localRotation = Quaternion.Lerp(FR_Transform.localRotation, rotation, Time.deltaTime * 0.5f); //得出阻力 new Vector3(0, 0, 0);
}
//Vector3 vN = Vector3.Normalize(rigidBody.velocity);
//Vector3 dN = Vector3.Normalize(dx.forward);
//float turnadjust = Vector3.Angle(vN, dN);
//Quaternion velRotation = Quaternion.AngleAxis(turnadjust, Vector3.up);
//rigidBody.velocity = velRotation * rigidBody.velocity;
}
bool bIsCancelPiaoyi = false;
IEnumerator WaitPiaoYiEnd()
{
bIsCancelPiaoyi = false;
if (currentSpeed > 150)
bIsCancelPiaoyi = true;
else
{
int value = Random.Range(0, 100);
if (value < 50)
bIsCancelPiaoyi = true;
}
yield return new WaitForSeconds(0.5f);
if (bIsCancelPiaoyi)
usingPiaoyi = false;
}
//IEnumerator DriftAnysc()
//{
//
//}
//private void OnDrawGizmos()
//{
// Vector3 vN = Vector3.Normalize(rigidBody.velocity) * 10;
// Vector3 dN = Vector3.Normalize(dx.forward);
// Gizmos.DrawLine(rigidBody.position + Vector3.up * 5, rigidBody.position + Vector3.up * 5 + vN);
//}
/// <summary>
/// Gearbox.
/// </summary>
private void GearBox()
{
if (automaticGear)
{
if (currentGear < gears.Length - 1 && !changingGear)
{
if (currentSpeed1 >= (gears[currentGear].maxSpeed) && FL_WheelCollider.rpm > 0)
{
// Debug.Log("变速:" + (currentGear + 1) + ",currentSpeed1:" + currentSpeed1 + ",engineRPM:" + engineRPM);
StartCoroutine(ChangeGear(currentGear + 1));
}
}
if (currentGear > 0)
{
if (!changingGear)
{
if (currentSpeed1 < (gears[currentGear - 1].targetSpeedForNextGear * .7f) && direction != -1)
{
StartCoroutine(ChangeGear(currentGear - 1));
}
}
}
}
}
/// <summary>
/// Changes the gear.
/// </summary>
/// <returns>The gear.</returns>
/// <param name="gear">Gear.</param>
public IEnumerator ChangeGear(int gear)
{
changingGear = true;
yield return new WaitForSeconds(gearShiftingDelay);
if (gear == -1)
{
currentGear = 0;
if (!NGear)
direction = -1;
else
direction = 0;
}
else
{
currentGear = gear;
if (!NGear)
direction = 1;
else
direction = 0;
}
changingGear = false;
}
void ApplyWheel(float torque)
{
FL_WheelCollider.motorTorque = torque;// torque;
FR_WheelCollider.motorTorque = torque;// torque;
RL_WheelCollider.motorTorque = torque;// torque;
RR_WheelCollider.motorTorque = torque;// torque;
}
void WheelAllignment()
{
Transform cL = FL_Transform.GetChild(1);
Transform cR = FR_Transform.GetChild(1);
WheelAllignmentOne(cL, FL_WheelCollider, 1);
WheelAllignmentOne(cR, FR_WheelCollider, 1);
WheelAllignmentOne(FL_Transform, FL_WheelCollider, 0);
WheelAllignmentOne(FR_Transform, FR_WheelCollider, 0);
WheelAllignmentOne(RL_Transform, RL_WheelCollider);
WheelAllignmentOne(RR_Transform, RR_WheelCollider);
}
void WheelAllignmentOne(Transform wt, WheelCollider wc, int t = 2)
{
Quaternion rot;
Vector3 pos;
wc.GetWorldPose(out pos, out rot);
//Set rotation & position of the wheels
if (t == 2)
{
wt.position = pos;
wt.rotation = rot;
}
if (t == 1)
{
wt.localEulerAngles = new Vector3(rot.eulerAngles.x, 0, 0);
}
if (t == 0)
{
wt.position = pos;
}
}
/// <summary>
/// 稳定杆
/// </summary>
public void StabilizerBars()
{
WheelHit FrontWheelHit;
float travelFL = 1.0f;
float travelFR = 1.0f;
bool groundedFL = FL_WheelCollider.GetGroundHit(out FrontWheelHit);
if (groundedFL)
travelFL = (-FL_WheelCollider.transform.InverseTransformPoint(FrontWheelHit.point).y - FL_WheelCollider.radius) / FL_WheelCollider.suspensionDistance;
bool groundedFR = FR_WheelCollider.GetGroundHit(out FrontWheelHit);
if (groundedFR)
travelFR = (-FR_WheelCollider.transform.InverseTransformPoint(FrontWheelHit.point).y - FR_WheelCollider.radius) / FR_WheelCollider.suspensionDistance;
float antiRollForceFront = (travelFL - travelFR) * antiRollAmount;
if (groundedFL)
rigidBody.AddForceAtPosition(FL_WheelCollider.transform.up * -antiRollForceFront, FL_WheelCollider.transform.position);
if (groundedFR)
rigidBody.AddForceAtPosition(FR_WheelCollider.transform.up * antiRollForceFront, FR_WheelCollider.transform.position);
WheelHit RearWheelHit;
float travelRL = 1.0f;
float travelRR = 1.0f;
bool groundedRL = RL_WheelCollider.GetGroundHit(out RearWheelHit);
if (groundedRL)
travelRL = (-RL_WheelCollider.transform.InverseTransformPoint(RearWheelHit.point).y - RL_WheelCollider.radius) / RL_WheelCollider.suspensionDistance;
bool groundedRR = RR_WheelCollider.GetGroundHit(out RearWheelHit);
if (groundedRR)
travelRR = (-RR_WheelCollider.transform.InverseTransformPoint(RearWheelHit.point).y - RR_WheelCollider.radius) / RR_WheelCollider.suspensionDistance;
float antiRollForceRear = (travelRL - travelRR) * antiRollAmount;
if (groundedRL)
rigidBody.AddForceAtPosition(RL_WheelCollider.transform.up * -antiRollForceRear, RL_WheelCollider.transform.position);
if (groundedRR)
rigidBody.AddForceAtPosition(RR_WheelCollider.transform.up * antiRollForceRear, RR_WheelCollider.transform.position);
//if (groundedRR && groundedRL && currentSpeed > 5.0f)
// rigidBody.AddRelativeTorque((Vector3.up * (moveDirection * 1)) * 500f);
//腾空时加氮气//
if (!groundedRL && !groundedRR && !groundedFL && !groundedFR)
{
bCarTengKong = true;
Debug.Log("腾空时加氮气");
if (!usingNitro && nitroTime < 5)
nitroTime += Time.fixedDeltaTime * 0.5f;
downforce = 500;
}
else
{
bCarTengKong = false;
downforce = 1595;
}
}
/// <summary>
/// 施加向下的压力
/// </summary>
void ApplyDownforce()
{
rigidBody.AddForce(-transform.up * downforce * rigidBody.velocity.magnitude);
}
public bool nitroEnable = false;
public bool nitroEndTeffect = false;
public float nitroEndTeffectTime = 0;
public GameObject nitroGroup;
public float nitroTime = 0;
public float nitroReduceTime = 0;
RGSK.PlayerCamera playerCam;
void Nitro()
{
if ((usingNitro || Input.GetKeyDown(KeyCode.LeftShift)) && !nitroEnable && nitroTime > 1)
{
nitroEnable = true;
// StartCoroutine(NitroAnysc());
playerCam = GameObject.FindObjectOfType(typeof(RGSK.PlayerCamera)) as RGSK.PlayerCamera;
nitroReduceTime = 0;
nitroGroup.SetActive(true);
nitroAudio.Play();
}
else
{
//if (usingNitro)
//{
// Debug.Log("触发氮气,但其他条件不满足 nitroTime:" + nitroTime);
//}
}
if (nitroEndTeffect)
{
nitroEndTeffectTime += Time.deltaTime * 4;
playerCam.GetComponent<Camera>().fieldOfView = Mathf.Lerp(70, 60, nitroEndTeffectTime);
playerCam.distanceZoomSpeed = Mathf.Lerp(3, 2, nitroEndTeffectTime);
playerCam.distance = Mathf.Lerp(7.4f, 5f, nitroEndTeffectTime);
playerCam.height = Mathf.Lerp(1.95f, 1.75f, nitroEndTeffectTime);
playerCam.lookAtHeight = Mathf.Lerp(1.28f, 1.22f, nitroEndTeffectTime);
}
if (nitroEnable)
{
nitroTime -= Time.fixedDeltaTime;
nitroReduceTime += Time.fixedDeltaTime;
TestUI.Instance.SetNitro(nitroTime / 5);
acceleration += Time.fixedDeltaTime * 0.5f;
if (acceleration > 1)
acceleration = 1;
float value = animNitroAcceleration.Evaluate(nitroReduceTime);
rigidBody.AddRelativeForce(dx.forward * fNitroAddFroce * value);
if (nitroTime <= 0)
{
nitroEnable = false;
nitroGroup.SetActive(false);
nitroAudio.Stop();
StartCoroutine(NitroEndAnysc());
}
if (nitroReduceTime <= 0.2f)
{
playerCam.GetComponent<Camera>().fieldOfView = Mathf.Lerp(60, 70, nitroReduceTime * 5);
playerCam.distanceZoomSpeed = Mathf.Lerp(5f, 2, nitroReduceTime * 5);
playerCam.distance = Mathf.Lerp(5f, 7.4f, nitroReduceTime * 5);
playerCam.height = Mathf.Lerp(1.75f, 1.9f, nitroReduceTime * 5);
playerCam.lookAtHeight = Mathf.Lerp(1.22f, 1.3f, nitroReduceTime * 5);
}
//if (nitroTime <= 0.5f && nitroTime > 0)
//{
// //Debug.Log("1- nitroTime * 2:"+ (1 - nitroTime * 1));
// playerCam.GetComponent<Camera>().fieldOfView = Mathf.Lerp(70, 60, 1 - nitroTime * 1);
// playerCam.distanceZoomSpeed = Mathf.Lerp(2, 5, 1 - nitroTime * 1);
// playerCam.distance = Mathf.Lerp(7.4f, 5f, 1 - nitroTime * 1);
// playerCam.height = Mathf.Lerp(1.9f, 1.75f, 1 - nitroTime * 1);
// playerCam.lookAtHeight = Mathf.Lerp(1.3f, 1.22f, 1 - nitroTime * 1);
//}
}
else
{
//if (isSleeping)
// if (nitroTime < 5)
// nitroTime += Time.fixedDeltaTime * 0.5f;
TestUI.Instance.SetNitro(nitroTime / 5);
}
}
/// <summary>
/// 氮气结束
/// </summary>
/// <returns></returns>
IEnumerator NitroEndAnysc()
{
RGSK.PlayerCamera playerCam = GameObject.FindObjectOfType(typeof(RGSK.PlayerCamera)) as RGSK.PlayerCamera;
yield return new WaitForSeconds(1f);
//playerCam.distanceZoomSpeed = 3;
//playerCam.distance = 5.5f;
//playerCam.height = 1.88f;
//playerCam.lookAtHeight = 1.28f;
//playerCam.GetComponent<Camera>().fieldOfView = 70;
nitroEndTeffect = true;
nitroEndTeffectTime = 0;
//yield return new WaitForSeconds(.25f);
yield return new WaitForSeconds(0.3f);
nitroEndTeffect = false;
//playerCam.GetComponent<Camera>().fieldOfView = 60;
//playerCam.distanceZoomSpeed = 5;
//playerCam.distance = 5f;
//playerCam.height = 1.8f;
//playerCam.lookAtHeight = 1.2f;
}
IEnumerator NitroAnysc()
{
float t = nitroTime - 0.25f;
RGSK.PlayerCamera playerCam = GameObject.FindObjectOfType(typeof(RGSK.PlayerCamera)) as RGSK.PlayerCamera;
playerCam.GetComponent<Camera>().fieldOfView = 60;
playerCam.distanceZoomSpeed = 5;
playerCam.distance = 5f;
playerCam.height = 1.8f;
playerCam.lookAtHeight = 1.2f;
yield return new WaitForSeconds(0.1f);
playerCam.distanceZoomSpeed = 2;
playerCam.distance = 5.5f;
playerCam.height = 1.75f;
playerCam.lookAtHeight = 1.22f;
playerCam.GetComponent<Camera>().fieldOfView = 65;
yield return new WaitForSeconds(0.15f);
playerCam.distance = 7.4f;
playerCam.height = 1.9f;
playerCam.lookAtHeight = 1.3f;
playerCam.GetComponent<Camera>().fieldOfView = 70;
yield return new WaitForSeconds(nitroTime);
playerCam.distanceZoomSpeed = 2;
playerCam.distance = 5.5f;
playerCam.height = 1.85f;
playerCam.lookAtHeight = 1.22f;
playerCam.GetComponent<Camera>().fieldOfView = 65;
yield return new WaitForSeconds(0.25f);
playerCam.GetComponent<Camera>().fieldOfView = 60;
playerCam.distanceZoomSpeed = 5;
playerCam.distance = 5f;
playerCam.height = 1.8f;
playerCam.lookAtHeight = 1.2f;
}
/// <summary>
/// Creates the gear curves.
/// </summary>
public void CreateGearCurves()
{
gears = new Gear[totalGears];
float[] gearRatio = new float[gears.Length];
int[] maxSpeedForGear = new int[gears.Length];
if (gears.Length == 3)
{
gearRatio = new float[] { 2.0f, 1.5f, 1.0f };
}
if (gears.Length == 4)
{
gearRatio = new float[] { 2.86f, 1.62f, 1.0f, .72f };
}
if (gears.Length == 5)
{
gearRatio = new float[] { 4.23f, 2.52f, 1.66f, 1.22f, 1.0f, };
}
if (gears.Length == 6)
{
gearRatio = new float[] { 4.35f, 2.5f, 1.66f, 1.23f, 1.0f, .85f };
}
if (gears.Length == 7)
{
gearRatio = new float[] { 4.5f, 2.5f, 1.66f, 1.23f, 1.0f, .9f, .8f };
}
if (gears.Length == 8)
{
gearRatio = new float[] { 4.6f, 2.5f, 1.86f, 1.43f, 1.23f, 1.05f, .9f, .72f };
}
for (int i = 0; i < maxSpeedForGear.Length; i++)
{
maxSpeedForGear[i] = new int();
maxSpeedForGear[i] = (int)((260 / gears.Length) * (i + 1));
}
maxSpeedForGear = new int[] { 61, 91, 129, 179, 221, 262 };
for (int i = 0; i < gears.Length; i++)
{
gears[i] = new Gear();
if (i == 0)
gears[i].SetGear(gearRatio[i], maxSpeedForGear[i], 0);
else
gears[i].SetGear(gearRatio[i], maxSpeedForGear[i], maxSpeedForGear[i - 1]);
}
/*if (autoGenerateGearCurves) {
engineTorqueCurve = new AnimationCurve[gears.Length];
currentGear = 0;
for (int i = 0; i < engineTorqueCurve.Length; i++)
engineTorqueCurve [i] = new AnimationCurve (new Keyframe (0, 1));
for (int i = 0; i < gears.Length; i++) {
if (i != 0) {
engineTorqueCurve [i].MoveKey (0, new Keyframe (0, Mathf.Lerp (1f, .05f, (float)(i + 1) / (float)gears.Length)));
engineTorqueCurve [i].AddKey (gears[i].targetSpeedForNextGear / 3f, gears[i].maxRatio / 1.1f);
// engineTorqueCurve [i].AddKey (gears[i-1].targetSpeedForNextGear, gears[i].maxRatio);
// engineTorqueCurve [i].AddKey (gears[i-1].targetSpeedForNextGear + ((gears[i].targetSpeedForNextGear - gears[i-1].targetSpeedForNextGear) / 2f), gears[i].maxRatio);
engineTorqueCurve [i].AddKey (gears[i].targetSpeedForNextGear, gears[i].maxRatio);
engineTorqueCurve [i].AddKey (gears[i].maxSpeed, Mathf.Lerp (1f, .05f, (float)(i + 1) / (float)gears.Length));
engineTorqueCurve [i].postWrapMode = WrapMode.Clamp;
engineTorqueCurve [i].preWrapMode = WrapMode.Clamp;
engineTorqueCurve [i].SmoothTangents (1, -.5f);
engineTorqueCurve [i].SmoothTangents (2, .75f);
} else {
engineTorqueCurve [i].MoveKey (0, new Keyframe (0, gears[0].maxRatio));
engineTorqueCurve [i].AddKey (gears[0].targetSpeedForNextGear, gears[0].maxRatio / 1.25f);
engineTorqueCurve [i].AddKey (gears[0].maxSpeed, Mathf.Lerp (1f, .05f, (float)(1) / (float)gears.Length));
engineTorqueCurve [i].postWrapMode = WrapMode.Clamp;
engineTorqueCurve [i].preWrapMode = WrapMode.Clamp;
// engineTorqueCurve [i].SmoothTangents (1, -.5f);
engineTorqueCurve [i].SmoothTangents (1, .5f);
// engineTorqueCurve [i].SmoothTangents (2, .75f);
}
orgMaxSpeed = maxspeed;
orgGearShiftingThreshold = gearShiftingThreshold;
}
}
for (int i = 0; i < engineTorqueCurve.Length; i++)
gears [i].torqueCurve = engineTorqueCurve [i];
*/
}
public bool hh = false;
float stayTime = 0;
Vector3 hitpos = Vector3.zero;
public LayerMask hittestMalk;
/// <summary>
/// 车尾碰撞
/// 描述:尾部处于碰撞状态,在转弯时加大转弯力度
/// </summary>
public bool bIsCollision = false;
private void OnCollisionEnter(Collision collision)
{
//rigidBody.velocity = Vector3.zero;
// acceleration = 0;
ApplyWheel(0);
if (collision.contacts.Length < 1)
return;
ContactPoint contact = collision.contacts[0];
//ContactPoint contact1 = collision.contacts[1];
//Vector3 nor = Vector3.Normalize(contact1.point - contact.point);
Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal);
Vector3 pos1 = contact.point;
if (collision.transform.tag == "RoadSide")
{
//初始化开始碰撞参数
stayTime = 0;
hitpos = contact.point;
//碰撞取消漂移
usingPiaoyi = false;
//播放碰撞效果
GameObject effectPrefab = Resources.Load<GameObject>("Effect/ExplosionFX");
GameObject effectIns = GameObject.Instantiate(effectPrefab);
effectIns.transform.position = hitpos;
//effectPrefab.DoScale()
//如果碰撞的是马路围挡
//则根据不同的车速与当前车的碰撞角度
//减弱车辆的速度,控制一定的反弹性
float speed = rigidBody.velocity.magnitude * 5.0f;
//发射射线,碰撞辅助点
Ray rayForward;
bool hitForward = transform.InverseTransformPoint(hitpos).z > 0;
if (hitForward)
rayForward = new Ray(car_Collider.transform.position, transform.forward * 20);
else
rayForward = new Ray(car_Collider.transform.position, -transform.forward * 20);
Ray rayRight;
bool hitRight = transform.InverseTransformPoint(hitpos).x > 0;
if (hitRight)
rayRight = new Ray(car_Collider.transform.position, transform.right * 20);
else
rayRight = new Ray(car_Collider.transform.position, -transform.right * 20);
RaycastHit rhForward = new RaycastHit();
bool hashitForward = Physics.Raycast(rayForward, out rhForward, 100, hittestMalk);
RaycastHit rhRight = new RaycastHit();
bool hashitRight = Physics.Raycast(rayRight, out rhRight, 100, hittestMalk);
float distanceForward = Vector3.Distance(rhForward.point, hitpos);
if (hashitForward)
{
if (hitForward)
{
if (hashitRight)
{
float distanceRight = Vector3.Distance(rhRight.point, hitpos);
float rateF = distanceForward / 5f;
float rateR = 1 / distanceRight;
float rateAvg = Mathf.Clamp((rateF + rateR) / 2, 0, 1);
if (!bIsCollision)
rigidBody.velocity = rigidBody.velocity * rateAvg;
Debug.Log("车头碰撞 距离:" + distanceForward + " Rate : " + rateF + " | " +
(hitRight ? "右" : "左") + "侧碰撞 距离:" + distanceRight + " Rate : " + rateR +
" \nAverageRate : " + (rateF + rateR) / 2 + " | 碰撞后速度:" + speed + "/" + rigidBody.velocity.magnitude * 5f + " |速度方向:" + rigidBody.velocity);
//yanjiang add//
//rigidBody.AddExplosionForce(5.0f, rigidBody.transform.position + rigidBody.transform.forward, 2.0f, 3.0f, ForceMode.VelocityChange);
//根据碰撞力度设置镜头抖动
cam_Car.GetComponent<RGSK.PlayerCamera>().SharkCamera(0.25f * (1 - rateAvg), 0.5f * (1 - rateAvg));
}
else
{
//Debug.Log("车头碰撞 距离: " + distanceForward);
if (!bIsCollision)
rigidBody.velocity = rigidBody.velocity * 0;
}
}
else
{
bIsCollision = true;
Debug.Log("车尾碰撞 距离: " + distanceForward);
}
}
else
{
if (hashitRight)
{
float distanceRight = Vector3.Distance(rhRight.point, hitpos);
float rateF = distanceForward / 5f;
float rateR = 1 / distanceRight;
float rateAvg = Mathf.Clamp((rateF + rateR) / 2, 0, 1);
if (!bIsCollision)
rigidBody.velocity = rigidBody.velocity * rateAvg;
Debug.Log("车后 右侧碰撞 距离:" + distanceForward + " Rate : " + rateF + " | " +
(hitRight ? "右" : "左") + "侧碰撞 距离:" + distanceRight + " Rate : " + rateR +
" \nAverageRate : " + (rateF + rateR) / 2 + " | 碰撞前后速度:" + speed + "/" + rigidBody.velocity.magnitude * 5f + " |速度方向:" + rigidBody.velocity);
//yanjiang add//
//rigidBody.AddExplosionForce(5.0f, rigidBody.transform.position + rigidBody.transform.forward, 2.0f, 3.0f, ForceMode.VelocityChange);
//根据碰撞力度设置镜头抖动
cam_Car.GetComponent<RGSK.PlayerCamera>().SharkCamera(0.25f * (1 - rateAvg), 0.5f * (1 - rateAvg));
}
else
{
Debug.Log("未检测到碰撞");
if (!bIsCollision)
rigidBody.velocity = rigidBody.velocity * 0.8f;
}
}
}
else if (collision.transform.tag == "")
{
}
currentSpeed1 = rigidBody.velocity.magnitude * 5f;
if (currentGear > 0)
for (int i = 0; i < gears.Length; i++)
{
if (gears[i].targetSpeedForNextGear <= currentSpeed1 && currentSpeed1 < gears[i].maxSpeed)
{
currentGear = i;
// Debug.Log("碰撞减档:" + (currentGear) + ",currentSpeed1:" + currentSpeed1);
}
}
if (currentGear <= 0)
{
acceleration = 0;
}
else if (currentGear == 1)
{
acceleration = 12000 / engineTorque;
}
else if (currentGear == 2)
{
acceleration = 18000 / engineTorque;
}
else if (currentGear == 3)
{
acceleration = 26000 / engineTorque;
}
else if (currentGear == 4)
{
acceleration = 36000 / engineTorque;
}
else if (currentGear == 5)
{
acceleration = 49000 / engineTorque;
}
//GameObject gb = GameObject.CreatePrimitive(PrimitiveType.Sphere);
//gb.transform.SetParent(this.transform);
//gb.transform.position = pos1;
//gb.transform.localScale = Vector3.one * 0.1f;
}
private void OnDrawGizmos()
{
Color color = Color.white;
if (car_Collider)
{
Ray ray = new Ray(car_Collider.transform.position, transform.forward * 20);
RaycastHit rh = new RaycastHit();
bool hashit = Physics.Raycast(ray, out rh, 100, hittestMalk);
if (hashit)
color = Color.red;
Debug.DrawRay(car_Collider.transform.position, transform.forward * 20, color);
}
}
private void OnCollisionStay(Collision collision)
{
if (collision.transform.tag == "RoadSide")
{
//如果碰撞的是马路围挡
//则判断是不是长时间不动,或不能前进
//如果是,就重置车子方向,一定条件下赋予一定的初速度
//Debug.Log("碰撞速度方向:" + rigidBody.velocity);
stayTime += Time.fixedDeltaTime;
if (stayTime > 1)
{
if (Vector3.Distance(hitpos, collision.contacts[0].point) < 0.2f)
{
// Debug.Log("重置车子状态");
}
else
stayTime = 0;
}
}
else if (collision.transform.tag == "")
{
}
}
private void OnCollisionExit(Collision collision)
{
if (collision.transform.tag == "RoadSide")
{
//判断是否离开碰撞
bIsCollision = false;
// Debug.Log("碰撞速度方向:" + rigidBody.velocity);
}
else if (collision.transform.tag == "")
{
}
}
}
/// <summary>
/// 赛车计算模型
/// 物理引擎模拟模式
/// 赛车wheel仿真轨迹
/// </summary>
public enum SaiCarLogicModel
{
}
//Race_Manager.cs handles the race logic - countdown, spawning cars, asigning racer names, checking race status, formatting time strings and more important race functions.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine.SceneManagement;
namespace RGSK
{
public class RaceManager : MonoBehaviour
{
public static RaceManager instance;
#region enum
public enum RaceType { Circuit, LapKnockout, TimeTrial, SpeedTrap, Checkpoints, Elimination, Drift }
public enum RaceState { StartingGrid, Racing, Paused, Complete, KnockedOut, Replay }
public enum PlayerSpawnPosition { Randomized, Selected }
public enum TimerType { CountUp, CountDown }
public enum AISpawnType { Randomized, Order }
public OpponentControl.AiDifficulty aiDifficulty = OpponentControl.AiDifficulty.Custom;
public RaceType _raceType;
public RaceState _raceState = RaceState.StartingGrid;
public PlayerSpawnPosition _playerSpawnPosition;
public AISpawnType _aiSpawnType;
public TimerType timerType = TimerType.CountUp;
#endregion
#region int
public int totalLaps = 3;
public int totalRacers = 4; //The total number of racers (player included)
public int playerStartRank = 4; //The rank you will start the race as
public int countdownFrom = 3;
private int currentCountdownTime;
#endregion
#region float
public float raceDistance; //Your race track's distance.
public float countdownDelay = 3.0f;
private float countdownTimer = 1.0f;
public float initialCheckpointTime = 10.0f; //start time (Checkpoint race);
public float driftTimeLimit = 60; //time limit (Drift race)
public float eliminationTime = 30f; //start time (Elimination race);
public float eliminationCounter; //timer for elimination
public float ghostAlpha = 0.3f;
public float goldDriftPoints = 10000;
public float silverDriftPoints = 5000;
public float bronzeDriftPoints = 1000;
#endregion
#region Transform
public Transform pathContainer;
public Transform spawnpointContainer;
public Transform checkpointContainer;
public Transform timeTrialStartPoint;
#endregion
#region GameObject
public GameObject playerCar;
public GameObject playerPointer, opponentPointer, racerName;
public GameObject activeGhostCar;
#endregion
#region List
public List<GameObject> opponentCars = new List<GameObject>();
public List<Transform> spawnpoints = new List<Transform>();
public List<RaceRewards> raceRewards = new List<RaceRewards>();
public List<string> opponentNamesList = new List<string>();
public List<Statistics> eliminationList = new List<Statistics>();
#endregion
public TextAsset opponentNames;
public StringReader nameReader;
public string playerName = "You";
public Shader ghostShader;
public Material ghostMaterial;
#region bool
private bool startCountdown;
public bool continueAfterFinish = true; //Should the racers keep driving after finish.
public bool showRacerNames = true; //Should names appear above player cars
public bool showRacerPointers = true; //Should minimap pointers appear above all racers
public bool showRaceInfoMessages = true;//Show final lap indication , new best lap, speed trap & racer knockout information texts
public bool forceWrongwayRespawn; //should the player get respawned if going the wrong way
public bool raceStarted; //has the race began
public bool raceCompleted; //has the race began
public bool loadRacePreferences; //Load menu prefrences?
public bool allowDuplicateRacers;//allow duplicate AI
public bool assignAiRacerNames = true;
public bool assignPlayerName = true;
public bool enableGhostVehicle = true;
public bool useGhostMaterial = false;
public bool enableReplay = true;
public bool autoStartReplay; //automatically start the replay after finishing the race
public bool showStartingGrid;
public bool timeTrialAutoDrive = true;
public bool penalties = true;
public bool timeLimit;
#endregion
void Awake()
{
//create an instance
instance = this;
//load race prefernces from an active data loader
if (loadRacePreferences)
{
if (GameObject.FindObjectOfType(typeof(DataLoader)))
{
DataLoader dl = GameObject.FindObjectOfType(typeof(DataLoader)) as DataLoader;
dl.LoadRacePreferences();
}
else
{
Debug.LogWarning("Add a DataLoader component to your scene to load race preferences!");
}
}
}
void Start()
{
//Set appropriate racer & lap values according to race type.
switch (_raceType)
{
case RaceType.Circuit:
timerType = TimerType.CountUp;
break;
/*case RaceType.Sprint:
totalLaps = 1;
continueAfterFinish = false;
timerType = TimerType.CountUp;
break;
*/
case RaceType.LapKnockout:
if (totalRacers < 2)
{
totalRacers = 2;
}
totalLaps = totalRacers - 1;
timerType = TimerType.CountUp;
break;
case RaceType.TimeTrial:
totalRacers = 1;
enableReplay = false;
showStartingGrid = false;
timerType = TimerType.CountUp;
if(SoundManager.instance.musicStart == SoundManager.MusicStart.BeforeCountdown)
SoundManager.instance.musicStart = SoundManager.MusicStart.AfterCountdown;
break;
case RaceType.Checkpoints:
timerType = TimerType.CountDown;
break;
case RaceType.Elimination:
if (totalRacers < 2)
{
totalRacers = 2;
}
eliminationCounter = eliminationTime;
timerType = TimerType.CountDown;
break;
case RaceType.Drift:
totalRacers = 1;
showStartingGrid = false;
timerType = (timeLimit) ? TimerType.CountDown : TimerType.CountUp;
break;
}
ConfigureNodes();
SpawnRacers();
}
void SpawnRacers()
{
if (!playerCar)
{
Debug.LogError("Please add a player vehicle!");
return;
}
//Find the children of the spawnpoint container and add them to the spawnpoints List.
spawnpoints.Clear();
Transform[] _sp = spawnpointContainer.GetComponentsInChildren<Transform>();
foreach (Transform point in _sp)
{
if (point != spawnpointContainer)
{
spawnpoints.Add(point);
}
}
//Set appropriate values incase they are icnorrectly configured.
totalRacers = SetValue(totalRacers, spawnpoints.Count);
playerStartRank = SetValue(playerStartRank, totalRacers);
totalLaps = SetValue(totalLaps, 1000);
//Check for player spawn type
if (_playerSpawnPosition == PlayerSpawnPosition.Randomized)
{
playerStartRank = Random.Range(1, totalRacers);
}
//Randomize spawn if total racers is greater than AI
if (totalRacers - 1 > opponentCars.Count)
{
_aiSpawnType = AISpawnType.Randomized;
allowDuplicateRacers = true;
}
//Spawn the racers
for (int i = 0; i < totalRacers; i++)
{
if (spawnpoints[i] != spawnpoints[playerStartRank - 1] && opponentCars.Count > 0)
{
//Spawn the AI
if (_aiSpawnType == AISpawnType.Randomized)
{
if (allowDuplicateRacers)
{
Instantiate(opponentCars[Random.Range(0, opponentCars.Count)], spawnpoints[i].position, spawnpoints[i].rotation);
}
else {
int spawnIndex = Random.Range(0, opponentCars.Count);
if (spawnIndex > opponentCars.Count) spawnIndex = opponentCars.Count - 1;
Instantiate(opponentCars[spawnIndex], spawnpoints[i].position, spawnpoints[i].rotation);
opponentCars.RemoveAt(spawnIndex);
}
}
else if (_aiSpawnType == AISpawnType.Order)
{
int spawnIndex = 0;
if (spawnIndex > opponentCars.Count) spawnIndex = opponentCars.Count - 1;
Instantiate(opponentCars[spawnIndex], spawnpoints[i].position, spawnpoints[i].rotation);
opponentCars.RemoveAt(spawnIndex);
}
}
else if (spawnpoints[i] == spawnpoints[playerStartRank - 1] && playerCar)
{
//Spawn the player
Transform spawnPos = (_raceType != RaceType.TimeTrial) ? spawnpoints[i] : timeTrialStartPoint;
GameObject player = (GameObject)Instantiate(playerCar, spawnPos.position, spawnPos.rotation);
switch (_raceType)
{
case RaceType.Drift:
if(!player.GetComponent<DriftPointController>())
player.AddComponent<DriftPointController>();
break;
case RaceType.TimeTrial:
player.AddComponent<TimeTrialConfig>();
if (enableGhostVehicle)
player.AddComponent<GhostVehicle>();
break;
}
}
}
//Set racer names, pointers and handle countdown after spawning the racers
RankManager.instance.RefreshRacerCount();
RaceUI.instance.RefreshInRaceStandings();
SetRacerPreferences();
//Start the countdown immediately if starting grid isn't shown
if (!showStartingGrid)
{
StartCoroutine(Countdown(countdownDelay));
}
else
{
//Update cameras
CameraManager.instance.ActivateStartingGridCamera();
}
}
void SetRacerPreferences()
{
Statistics[] racers = GameObject.FindObjectsOfType(typeof(Statistics)) as Statistics[];
//Load opponent names if they havent already been loaded
if (opponentNamesList.Count <= 0)
{
LoadRacerNames();
}
for (int i = 0; i < racers.Length; i++)
{
racers[i].name = ReplaceString(racers[i].name, "(Clone)");
if (racers[i].gameObject.tag == "Player")
{
//Player Name & Player Minimap Pointer
if (assignPlayerName)
{
racers[i].racerDetails.racerName = playerName;
}
if (showRacerPointers && playerPointer)
{
GameObject m_pointer = (GameObject)Instantiate(playerPointer);
m_pointer.GetComponent<RacerPointer>().target = racers[i].transform;
}
}
else {
//AI Racer Names
if (assignAiRacerNames)
{
int nameIndex = Random.Range(0, opponentNamesList.Count);
if (nameIndex > opponentNamesList.Count) nameIndex = opponentNamesList.Count - 1;
racers[i].racerDetails.racerName = opponentNamesList[nameIndex].ToString();
opponentNamesList.RemoveAt(nameIndex);
}
//Ai Racer Name Component
if (showRacerNames && racerName)
{
GameObject _name = (GameObject)Instantiate(racerName);
_name.GetComponent<RacerName>().target = racers[i].transform;
_name.GetComponent<RacerName>().Initialize();
}
//Ai Minimap Pointers
if (showRacerPointers && opponentPointer)
{
GameObject o_pointer = (GameObject)Instantiate(opponentPointer);
o_pointer.GetComponent<RacerPointer>().target = racers[i].transform;
}
//Ai Difficulty
racers[i].gameObject.GetComponent<OpponentControl>().SetDifficulty(aiDifficulty);
}
}
}
public IEnumerator Countdown(float delay)
{
if (_raceType == RaceType.TimeTrial)
yield break;
//Set the race state to racing
SwitchRaceState(RaceState.Racing);
//Update cameras
CameraManager.instance.ActivatePlayerCamera();
//Check whether music should be played now
if (SoundManager.instance.musicStart == SoundManager.MusicStart.BeforeCountdown)
SoundManager.instance.StartMusic();
//wait for (countdown delay) seconds
yield return new WaitForSeconds(delay);
//set total countdown time
currentCountdownTime = countdownFrom + 1;
startCountdown = true;
while (startCountdown == true)
{
countdownTimer -= Time.deltaTime;
if (currentCountdownTime >= 1)
{
if (countdownTimer < 0.01f)
{
currentCountdownTime -= 1;
countdownTimer = 1;
if (currentCountdownTime > 0)
{
RaceUI.instance.SetCountDownText(currentCountdownTime.ToString());
SoundManager.instance.PlayDefaultSound(SoundManager.instance.defaultSounds.countdownSound);
}
}
}
else {
//Display GO! and call StartRace();
startCountdown = false;
RaceUI.instance.SetCountDownText("GO!");
SoundManager.instance.PlayDefaultSound(SoundManager.instance.defaultSounds.startRaceSound);
StartRace();
//Wait for 1 second and hide the text.
yield return new WaitForSeconds(1);
RaceUI.instance.SetCountDownText(string.Empty);
}
yield return null;
}
}
void Update()
{
//Handle Elimination race times
if (_raceType == RaceType.Elimination)
CalculateEliminationTime();
}
public void StartRace()
{
//enable cars to start racing
Statistics[] racers = GameObject.FindObjectsOfType(typeof(Statistics)) as Statistics[];
foreach (Statistics go in racers)
{
if (go.GetComponent<Car_Controller>())
go.GetComponent<Car_Controller>().controllable = true;
if (go.GetComponent<Motorbike_Controller>())
go.GetComponent<Motorbike_Controller>().controllable = true;
if (_raceType == RaceType.Elimination)
eliminationList.Add(go);
}
//Start replay recording
if (enableReplay && GetComponent<ReplayManager>())
GetComponent<ReplayManager>().GetRacersAndStartRecording(racers);
//Check whether music should be played now
if (SoundManager.instance && SoundManager.instance.musicStart == SoundManager.MusicStart.AfterCountdown)
SoundManager.instance.StartMusic();
//注释 yanjiang 控制是否移动
raceStarted = true;
}
public void EndRace(int rank)
{
StartCoroutine(EndRaceRoutine());
raceCompleted = true;
CalculateRaceRewards(rank);
if (ReplayManager.instance)
ReplayManager.instance.StopRecording();
}
IEnumerator EndRaceRoutine()
{
RaceUI.instance.DisableRacePanelChildren();
RaceUI.instance.SetFinishedText("RACE COMPLETED");
yield return new WaitForSeconds(3.0f);
if (autoStartReplay)
AutoStartReplay();
SwitchRaceState(RaceState.Complete);
}
void CalculateRaceRewards(int pos)
{
if (raceRewards.Count >= pos)
{
//Give currency
if (raceRewards[pos - 1].currency > 0)
{
PlayerData.AddCurrency(raceRewards[pos - 1].currency);
RaceUI.instance.SetRewardText(raceRewards[pos - 1].currency.ToString("N0"), "", "");
Debug.Log("Reward Currency : " + raceRewards[pos - 1].currency);
}
//Vehicle Unlock
if (raceRewards[pos - 1].vehicleUnlock != "" && !PlayerPrefs.HasKey(raceRewards[pos - 1].vehicleUnlock))
{
PlayerData.Unlock(raceRewards[pos - 1].vehicleUnlock);
RaceUI.instance.SetRewardText("", raceRewards[pos - 1].vehicleUnlock, "");
Debug.Log("Reward Vehicle : " + raceRewards[pos - 1].vehicleUnlock);
}
//Track Unlock
if (raceRewards[pos - 1].trackUnlock != "" && !PlayerPrefs.HasKey(raceRewards[pos - 1].trackUnlock))
{
PlayerData.Unlock(raceRewards[pos - 1].trackUnlock);
RaceUI.instance.SetRewardText("", "", raceRewards[pos - 1].trackUnlock);
Debug.Log("Reward Track : " + raceRewards[pos - 1].trackUnlock);
}
}
}
public void PauseRace()
{
//No point for pausing in completed or starting grid states
if (raceCompleted || _raceState == RaceState.StartingGrid) return;
if (_raceState == RaceState.Paused)
{
//Handle un-pausing
SwitchRaceState(RaceState.Racing);
Time.timeScale = 1.0f;
SoundManager.instance.SetVolume();
}
else
{
//Handle pausing
SwitchRaceState(RaceState.Paused);
Time.timeScale = 0.0f;
AudioListener.volume = 0.0f;
}
}
void CalculateEliminationTime()
{
if (!raceStarted || _raceState == RaceState.Complete) return;
eliminationCounter -= Time.deltaTime;
if (eliminationCounter <= 0)
{
eliminationCounter = eliminationTime;
if (RankManager.instance.currentRacers > 1) { KnockoutRacer(GetLastPlace()); }
//end the race after all opponent racers have been eliminated
AllOpponentsEliminated();
}
}
//Used to knockout a racer
public void KnockoutRacer(Statistics racer)
{
racer.knockedOut = true;
if (racer.tag == "Player")
{
SwitchRaceState(RaceState.KnockedOut);
racer.AIMode();
//RaceUI Fail Race Panel Config
string title = (_raceType == RaceType.Elimination) ? "ELIMINATED" : (_raceType == RaceType.LapKnockout) ? "KNOCKED OUT" : "TIMED OUT";
string reason = (_raceType == RaceType.Elimination) ? "You were eliminated from the race." : (_raceType == RaceType.LapKnockout) ? "You were knocked out of the race." : "You ran out of time.";
RaceUI.instance.SetFailRace(title, reason);
//Stop Recording
if (ReplayManager.instance) { ReplayManager.instance.StopRecording(); }
}
if (showRaceInfoMessages)
{
string keyword = (_raceType == RaceType.Elimination) ? " eliminated." : (_raceType == RaceType.LapKnockout) ? " knocked out." : " timed out.";
RaceUI.instance.ShowRaceInfo(racer.racerDetails.racerName + keyword, 2.0f, Color.white);
}
ChangeLayer(racer.transform, "IgnoreCollision");
RankManager.instance.RefreshRacerCount();
}
//Creates an active ghost car
public void CreateGhostVehicle(GameObject racer)
{
//Destroy any active ghost
if (activeGhostCar)
{
Destroy(activeGhostCar);
}
//Create a duplicate ghost car
GameObject ghost = (GameObject)Instantiate(racer, Vector3.zero, Quaternion.identity);
ghost.name = "Ghost";
ghost.tag = "Untagged";
activeGhostCar = ghost;
ChangeLayer(ghost.transform, "IgnoreCollision");
ChangeMaterial(ghost.transform);
DisableRacerInput(ghost);
ghost.GetComponent<GhostVehicle>().StartGhost();
}
//Format a float to a time string
public string FormatTime(float time)
{
int minutes = (int)Mathf.Floor(time / 60);
int seconds = (int)time % 60;
int milliseconds = (int)(time * 100) % 100;
return string.Format("{0:00}:{1:00}:{2:00}", minutes, seconds, milliseconds);
}
//Loads racer names from a .txt resource file
public void LoadRacerNames()
{
if (!(TextAsset)Resources.Load("RacerNames", typeof(TextAsset)))
{
Debug.Log("Names not found! Please add a .txt file named 'RacerNames' with a list of names to /Resources folder.");
return;
}
int lineCount = 0;
opponentNames = (TextAsset)Resources.Load("RacerNames", typeof(TextAsset));
nameReader = new StringReader(opponentNames.text);
string txt = nameReader.ReadLine();
while (txt != null)
{
lineCount++;
if (opponentNamesList.Count < lineCount)
{
opponentNamesList.Add(txt);
}
txt = nameReader.ReadLine();
}
}
//Used to calculate track distance(in meters) & rotate the nodes correctly
void ConfigureNodes()
{
Transform[] m_path = pathContainer.GetComponentsInChildren<Transform>();
List<Transform> m_pathList = new List<Transform>();
foreach (Transform node in m_path)
{
if (node != pathContainer)
{
m_pathList.Add(node);
}
}
for (int i = 0; i < m_pathList.Count; i++)
{
if (i < m_pathList.Count - 1)
{
m_pathList[i].transform.LookAt(m_pathList[i + 1].transform);
}
else {
m_pathList[i].transform.LookAt(m_pathList[0].transform);
}
}
raceDistance = pathContainer.GetComponent<WaypointCircuit>().distances[pathContainer.GetComponent<WaypointCircuit>().distances.Length - 1];
}
//used to respawn a racer
public void RespawnRacer(Transform racer, Transform node, float ignoreCollisionTime)
{
if (raceStarted)
StartCoroutine(Respawn(racer, node, ignoreCollisionTime));
}
IEnumerator Respawn(Transform racer, Transform node, float ignoreCollisionTime)
{
//Flip the car over and place it at the last passed node
racer.rotation = Quaternion.LookRotation(racer.forward);
racer.GetComponent<Rigidbody>().velocity = Vector3.zero;
racer.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
racer.position = new Vector3(node.position.x, node.position.y + 0.1f, node.position.z);
racer.rotation = node.rotation;
ChangeLayer(racer, "IgnoreCollision");
yield return new WaitForSeconds(ignoreCollisionTime);
ChangeLayer(racer, "Default");
}
//used to change a racers layer to "ignore collision" after being knocked out & on respawn
public void ChangeLayer(Transform racer, string LayerName)
{
for (int i = 0; i < racer.childCount; i++)
{
racer.GetChild(i).gameObject.layer = LayerMask.NameToLayer(LayerName);
ChangeLayer(racer.GetChild(i), LayerName);
}
}
//used to change a racers material when creating a ghost car
public void ChangeMaterial(Transform racer)
{
Transform[] m = racer.GetComponentsInChildren<Transform>();
foreach (Transform t in m)
{
if (t.GetComponent<Renderer>())
{
//If the vehicle only uses one material
if (t.GetComponent<Renderer>().materials.Length == 1)
{
if (!useGhostMaterial)
{
Material instance = t.gameObject.GetComponent<Renderer>().material;
instance.shader = (ghostShader) ? ghostShader : Shader.Find("Transparent/Diffuse");
Color col = instance.color;
col.a = ghostAlpha;
instance.color = col;
t.gameObject.GetComponent<Renderer>().material = instance;
}
else
{
t.gameObject.GetComponent<Renderer>().material = ghostMaterial;
}
}
else {
//If the vehicle uses more than one material
Material[] instances = new Material[t.GetComponent<Renderer>().materials.Length];
Color[] col = new Color[t.GetComponent<Renderer>().materials.Length];
for (int i = 0; i < instances.Length; i++)
{
if (!useGhostMaterial)
{
instances[i] = t.gameObject.GetComponent<Renderer>().materials[i];
instances[i].shader = ghostShader;
col[i] = instances[i].color;
col[i].a = ghostAlpha;
instances[i].color = col[i];
t.gameObject.GetComponent<Renderer>().materials[i] = instances[i];
}
else {
instances[i] = ghostMaterial;
t.gameObject.GetComponent<Renderer>().materials = instances;
}
}
}
}
}
}
//Used to disable input for when viewing a replay or for a ghost car
public void DisableRacerInput(GameObject racer)
{
if (racer.GetComponent<PlayerControl>())
racer.GetComponent<PlayerControl>().enabled = false;
if (racer.GetComponent<OpponentControl>())
racer.GetComponent<OpponentControl>().enabled = false;
if (!racer.GetComponent<Statistics>().finishedRace)
racer.GetComponent<Statistics>().finishedRace = true;
}
public void SwitchRaceState(RaceState state)
{
_raceState = state;
//Update UI
RaceUI.instance.UpdateUIPanels();
}
/// <summary>
/// Automatically starts the reply by manually setting the appropriate values
/// </summary>
void AutoStartReplay()
{
if (ReplayManager.instance.TotalFrames <= 0) return;
StartCoroutine(RaceUI.instance.ScreenFadeOut(0.5f));
_raceState = RaceState.Replay;
ReplayManager.instance.replayState = ReplayManager.ReplayState.Playing;
CameraManager.instance.ActivateCinematicCamera();
for (int i = 0; i < ReplayManager.instance.racers.Count; i++)
{
DisableRacerInput(ReplayManager.instance.racers[i].racer.gameObject);
}
}
// Checks if all racers have finished
public bool AllRacersFinished()
{
bool allFinished = false;
Statistics[] allRacers = GameObject.FindObjectsOfType(typeof(Statistics)) as Statistics[];
for (int i = 0; i < allRacers.Length; i++)
{
if (allRacers[i].finishedRace)
allFinished = true;
else
allFinished = false;
}
return allFinished;
}
void AllOpponentsEliminated()
{
for (int i = 0; i < eliminationList.Count; i++)
{
if (eliminationList[i].knockedOut)
{
eliminationList.Remove(eliminationList[i]);
}
if (eliminationList.Count == 1 && eliminationList[0].gameObject.tag == "Player")
{
eliminationList[0].FinishRace();
}
}
}
public Statistics GetLastPlace()
{
return RankManager.instance.racerRanks[RankManager.instance.currentRacers - 1].racer.GetComponent<Statistics>();
}
private int SetValue(int val, int otherVal)
{
int myVal = val;
if (val > otherVal)
{
myVal = otherVal;
}
else if (val <= 0)
{
myVal = 1;
}
return myVal;
}
string ReplaceString(string stringValue, string toRemove)
{
return stringValue.Replace(toRemove, "");
}
}
}
//Race_UI.cs handles displaying all UI in the race.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
namespace RGSK
{
public class RaceUI : MonoBehaviour
{
#region Grouped UI Classes
[System.Serializable]
public class RacerInfoUI
{
public Text position;
public Text name;
public Text vehicleName;
public Text bestLapTime;
public Text totalTime;
}
[System.Serializable]
public class RacingUI
{
public Text rank;
public Text lap;
public Text currentLapTime;
public Text previousLapTime;
public Text bestLapTime;
public Text totalTime;
public Text countdown;
public Text raceInfo;
public Text finishedText;
[Header("In Race Standings")]
public List<RacerInfoUI> inRaceStandings = new List<RacerInfoUI>();
public Color playerColor = Color.green;
public Color normalColor = Color.white;
[Header("Wrongway Indication")]
public Text wrongwayText;
public Image wrongwayImage;
}
[System.Serializable]
public class DriftingUI
{
public GameObject driftPanel;
public Text totalDriftPoints;
public Text currentDriftPoints;
public Text driftMultiplier;
public Text driftStatus;
public Text goldPoints, silverPoints, bronzePoints;
}
[System.Serializable]
public class DriftResults
{
public Text totalPoints;
public Text driftRaceTime;
public Text bestDrift;
public Text longestDrift;
public Image gold, silver, bronze;
}
[System.Serializable]
public class VehicleUI
{
public Text currentRPM;
public Text currentSpeed;
public Text currentGear;
public Image nitroBar;
public TextMesh speedText3D, gearText3D;
private string speedUnit;
[Header("Speedometer")]
public RectTransform needle;
public float minNeedleAngle = -20.0f;
public float maxNeedleAngle = 220.0f;
public float rotationMultiplier = 0.85f;
[HideInInspector]
public float needleRotation;
}
[System.Serializable]
public class Rewards
{
public Text rewardCurrency;
public Text rewardVehicle;
public Text rewardTrack;
}
#endregion
public static RaceUI instance;
private Statistics player;
private DriftPointController driftpointcontroller;
[Header("Starting Grid UI")]
public GameObject startingGridPanel;
public List<RacerInfoUI> startingGrid = new List<RacerInfoUI>();
[Header("Racing UI")]
public GameObject racePanel;
public GameObject pausePanel;
public RacingUI racingUI;
public DriftingUI driftUI;
public VehicleUI vehicleUI;
[Header("Fail Race UI")]
public GameObject failRacePanel;
public Text failTitle;
public Text failReason;
[Header("Race Finished UI")]
public GameObject raceCompletePanel;
public GameObject raceResultsPanel, driftResultsPanel;
public List<RacerInfoUI> raceResults = new List<RacerInfoUI>();
public DriftResults driftResults;
public Rewards rewardTexts;
[Header("Replay UI")]
public GameObject replayPanel;
public Image progressBar;
[Header("ScreenFade")]
public Image screenFade;
public float fadeSpeed = 0.5f;
public bool fadeOnStart = true;
public bool fadeOnExit = true;
[Header("Scene Ref")]
public string menuScene = "Menu";
[HideInInspector]
public List<string> raceInfos = new List<string>();
/// <summary>
/// 旋转页面
/// </summary>
public GameObject rotatePlane;
/// <summary>
/// 启动页面
/// </summary>
public GameObject PulseonPlane;
/// <summary>
/// 转盘页面
/// </summary>
public GameObject zhuanpanPlane;
bool bOneStart = true;
void Awake()
{
instance = this;
}
IEnumerator Start()
{
if (fadeOnStart && screenFade) StartCoroutine(ScreenFadeOut(fadeSpeed));
ClearUI();
ConfigureUiBasedOnRaceType();
UpdateUIPanels();
yield return new WaitForSeconds(0.1f);
StartCountDown(0);
if (rotatePlane)
rotatePlane.transform.SetGameObjectActive(false);
if (PulseonPlane)
PulseonPlane.transform.SetGameObjectActive(true);
if (zhuanpanPlane)
((RectTransform)zhuanpanPlane.transform).anchoredPosition = new Vector2(-650, 320);
if (TestUI.Instance != null)
TestUI.Instance.HideGearUi(true);
}
void ClearUI()
{
//Clear Starting Grid
if (startingGrid.Count > 0)
{
for (int i = 0; i < startingGrid.Count; i++)
{
startingGrid[i].position.text = string.Empty;
startingGrid[i].name.text = string.Empty;
startingGrid[i].vehicleName.text = string.Empty;
}
}
//Clear In Race Standings
if (racingUI.inRaceStandings.Count > 0)
{
for (int i = 0; i < racingUI.inRaceStandings.Count; i++)
{
racingUI.inRaceStandings[i].position.text = (i + 1).ToString();
//Disable the parent if one exists so we can activate it later based on how many racers there are
if (racingUI.inRaceStandings[i].position.transform.parent)
racingUI.inRaceStandings[i].position.transform.parent.gameObject.SetActive(false);
}
}
//Clear Race Reults
if (raceResults.Count > 0)
{
for (int i = 0; i < raceResults.Count; i++)
{
if (raceResults[i].position) raceResults[i].position.text = string.Empty;
if (raceResults[i].name) raceResults[i].name.text = string.Empty;
if (raceResults[i].totalTime) raceResults[i].totalTime.text = string.Empty;
if (raceResults[i].vehicleName) raceResults[i].vehicleName.text = string.Empty;
if (raceResults[i].bestLapTime) raceResults[i].bestLapTime.text = string.Empty;
}
}
//Clear other texts
if (racingUI.raceInfo) racingUI.raceInfo.text = string.Empty;
if (racingUI.countdown) racingUI.countdown.text = string.Empty;
if (racingUI.finishedText) racingUI.finishedText.text = string.Empty;
if (rewardTexts.rewardCurrency) rewardTexts.rewardCurrency.text = string.Empty;
if (rewardTexts.rewardVehicle) rewardTexts.rewardVehicle.text = string.Empty;
if (rewardTexts.rewardTrack) rewardTexts.rewardTrack.text = string.Empty;
}
void ConfigureUiBasedOnRaceType()
{
if (!RaceManager.instance) return;
if (driftUI.driftPanel) driftUI.driftPanel.SetActive(RaceManager.instance._raceType == RaceManager.RaceType.Drift);
if (raceResultsPanel) raceResultsPanel.SetActive(RaceManager.instance._raceType != RaceManager.RaceType.Drift);
if (driftResultsPanel) driftResultsPanel.SetActive(RaceManager.instance._raceType == RaceManager.RaceType.Drift);
if (RaceManager.instance._raceType == RaceManager.RaceType.Drift)
{
if (driftUI.goldPoints) driftUI.goldPoints.text = RaceManager.instance.goldDriftPoints.ToString("N0");
if (driftUI.silverPoints) driftUI.silverPoints.text = RaceManager.instance.silverDriftPoints.ToString("N0");
if (driftUI.bronzePoints) driftUI.bronzePoints.text = RaceManager.instance.bronzeDriftPoints.ToString("N0");
}
}
void Update()
{
if (!player)
{
if (GameObject.FindGameObjectWithTag("Player"))
{
player = GameObject.FindGameObjectWithTag("Player").GetComponent<Statistics>();
if (player && player.GetComponent<DriftPointController>())
driftpointcontroller = player.GetComponent<DriftPointController>();
}
}
else
{
UpdateUI();
VehicleGUI();
}
if (RaceManager.instance.raceStarted && bOneStart)
{
if (rotatePlane)
rotatePlane.transform.SetGameObjectActive(true);
if (PulseonPlane)
PulseonPlane.transform.SetGameObjectActive(false);
if (zhuanpanPlane)
((RectTransform)zhuanpanPlane.transform).anchoredPosition = new Vector2(650, 320);
if (TestUI.Instance != null)
TestUI.Instance.HideGearUi(false);
bOneStart = false;
}
}
void UpdateUI()
{
if (!RaceManager.instance) return;
//yanjiang 结束游戏//
if (player.LapTimeCounter >= 60)
{
player.FinishRace();
}
switch (RaceManager.instance._raceType)
{
case RaceManager.RaceType.Circuit:
DefaultUI();
break;
/*case RaceManager.RaceType.Sprint:
DefaultUI();
break;
*/
case RaceManager.RaceType.LapKnockout:
DefaultUI();
break;
case RaceManager.RaceType.TimeTrial:
TimeTrialUI();
break;
case RaceManager.RaceType.SpeedTrap:
DefaultUI();
break;
case RaceManager.RaceType.Checkpoints:
CheckpointRaceUI();
break;
case RaceManager.RaceType.Elimination:
EliminationRaceUI();
break;
case RaceManager.RaceType.Drift:
DriftRaceUI();
break;
}
switch (RaceManager.instance._raceState)
{
case RaceManager.RaceState.StartingGrid:
ShowStartingGrid();
break;
case RaceManager.RaceState.Racing:
ShowInRaceStandings();
WrongwayUI();
break;
case RaceManager.RaceState.Complete:
if (RaceManager.instance._raceType != RaceManager.RaceType.Drift)
{
ShowRaceResults();
}
else
{
ShowDriftResults();
}
break;
case RaceManager.RaceState.Replay:
ShowReplayUI();
break;
}
}
#region RaceTypes UI
void DefaultUI()
{
//POS
if (racingUI.rank)
racingUI.rank.text = "Pos " + player.rank + "/" + RankManager.instance.currentRacers;
//LAP
if (racingUI.lap)
racingUI.lap.text = "Lap " + player.lap + "/" + RaceManager.instance.totalLaps;
//LAP TIME
if (racingUI.currentLapTime)
{
racingUI.currentLapTime.text = "Current " + player.currentLapTime;
TestUI.Instance.SetCurrentTime(player.currentLapTime);
}
//TOTAL TIME
if (racingUI.totalTime)
racingUI.totalTime.text = "Total " + player.totalRaceTime;
//LAST LAP TIME
if (racingUI.previousLapTime)
racingUI.previousLapTime.text = GetPrevLapTime();
//BEST LAP TIME
if (racingUI.bestLapTime)
racingUI.bestLapTime.text = GetBestLapTime();
}
void TimeTrialUI()
{
//POS
if (racingUI.rank)
racingUI.rank.text = "Pos " + player.GetComponent<Statistics>().rank + "/" + RankManager.instance.currentRacers;
//LAP
if (racingUI.lap)
racingUI.lap.text = "Lap " + player.lap;
//LAP TIME
if (racingUI.currentLapTime)
{
racingUI.currentLapTime.text = "Current " + player.currentLapTime;
TestUI.Instance.SetCurrentTime(player.currentLapTime);
}
//TOTAL TIME
if (racingUI.totalTime)
racingUI.totalTime.text = "Total " + player.totalRaceTime;
//LAST LAP TIME
if (racingUI.previousLapTime)
racingUI.previousLapTime.text = GetPrevLapTime();
//BEST LAP TIME
if (racingUI.bestLapTime)
racingUI.bestLapTime.text = GetBestLapTime();
}
void CheckpointRaceUI()
{
//POS
if (racingUI.rank)
racingUI.rank.text = "Pos " + player.GetComponent<Statistics>().rank + "/" + RankManager.instance.currentRacers;
//CHECKPOINTS
if (racingUI.lap)
racingUI.lap.text = "CP " + player.checkpoint + "/" + player.checkpoints.Count * RaceManager.instance.totalLaps;
//TIMER
if (racingUI.currentLapTime)
{
racingUI.currentLapTime.text = "Current " + player.currentLapTime;
TestUI.Instance.SetCurrentTime(player.currentLapTime);
}
//BEST LAP TIME
if (racingUI.bestLapTime)
racingUI.bestLapTime.text = GetBestLapTime();
//EMPTY strings
if (racingUI.previousLapTime)
racingUI.previousLapTime.text = "";
if (racingUI.totalTime)
racingUI.totalTime.text = "";
}
void EliminationRaceUI()
{
//POS
if (racingUI.rank)
racingUI.rank.text = "Pos " + player.GetComponent<Statistics>().rank + "/" + RankManager.instance.currentRacers;
//LAP
if (racingUI.lap)
racingUI.lap.text = "Lap " + player.lap + "/" + RaceManager.instance.totalLaps;
//TIMER
if (racingUI.currentLapTime)
{
racingUI.currentLapTime.text = "Time : " + RaceManager.instance.FormatTime(RaceManager.instance.eliminationCounter);
TestUI.Instance.SetCurrentTime(player.currentLapTime);
}
//TOTAL TIME
if (racingUI.totalTime)
racingUI.totalTime.text = "Total " + player.totalRaceTime;
//LAST LAP
if (racingUI.previousLapTime)
racingUI.previousLapTime.text = GetPrevLapTime();
//BEST LAP
if (racingUI.bestLapTime)
racingUI.bestLapTime.text = GetBestLapTime();
}
void DriftRaceUI()
{
//DRIFT UI
if (driftUI.totalDriftPoints)
driftUI.totalDriftPoints.text = player.GetComponent<DriftPointController>().totalDriftPoints.ToString("N0") + " Pts";
if (driftUI.currentDriftPoints)
driftUI.currentDriftPoints.text = driftpointcontroller.currentDriftPoints > 0 ? "+ " + player.GetComponent<DriftPointController>().currentDriftPoints.ToString("N0") + " Pts" : string.Empty;
if (driftUI.driftMultiplier)
driftUI.driftMultiplier.text = driftpointcontroller.driftMultiplier > 1 ? "x " + driftpointcontroller.driftMultiplier : string.Empty;
//POS
if (racingUI.rank)
racingUI.rank.text = string.Empty;
//LAP
if (racingUI.lap)
racingUI.lap.text = "Lap " + player.lap + "/" + RaceManager.instance.totalLaps;
//LAP TIME
if (racingUI.currentLapTime)
racingUI.currentLapTime.text = "Time " + player.currentLapTime;
//TOTAL TIME
if (racingUI.totalTime)
racingUI.totalTime.text = "Total " + player.totalRaceTime;
//LAST LAP TIME
if (racingUI.previousLapTime)
racingUI.previousLapTime.text = GetPrevLapTime();
//BEST LAP TIME
if (racingUI.bestLapTime)
racingUI.bestLapTime.text = GetBestLapTime();
}
#endregion
void VehicleGUI()
{
//RPM
if (vehicleUI.currentRPM)
{
if (player.GetComponent<Car_Controller>())
vehicleUI.currentRPM.text = (player.GetComponent<Car_Controller>().FR_WheelCollider.rpm).ToString("f0") + "RPM";
if (player.GetComponent<Motorbike_Controller>())
vehicleUI.currentRPM.text = (player.GetComponent<Motorbike_Controller>().frontWheelCollider.rpm).ToString("f0") + "RPM";
}
//Speed
if (vehicleUI.currentSpeed)
{
if (player.GetComponent<Car_Controller>())
vehicleUI.currentSpeed.text = player.GetComponent<Car_Controller>().currentSpeed + player.GetComponent<Car_Controller>()._speedUnit.ToString();
if (player.GetComponent<Motorbike_Controller>())
vehicleUI.currentSpeed.text = player.GetComponent<Motorbike_Controller>().currentSpeed + player.GetComponent<Motorbike_Controller>()._speedUnit.ToString();
}
//Gear
if (vehicleUI.currentGear)
{
if (player.GetComponent<Car_Controller>())
vehicleUI.currentGear.text = player.GetComponent<Car_Controller>().currentGear.ToString();
if (player.GetComponent<Motorbike_Controller>())
vehicleUI.currentGear.text = player.GetComponent<Motorbike_Controller>().currentGear.ToString();
}
//Speedometer
if (vehicleUI.needle)
{
float fraction = 0;
if (player.GetComponent<Car_Controller>())
{
fraction = player.GetComponent<Car_Controller>().currentSpeed / vehicleUI.maxNeedleAngle;
}
if (player.GetComponent<Motorbike_Controller>())
{
fraction = player.GetComponent<Motorbike_Controller>().currentSpeed / vehicleUI.maxNeedleAngle;
}
vehicleUI.needleRotation = Mathf.Lerp(vehicleUI.minNeedleAngle, vehicleUI.maxNeedleAngle, (fraction * vehicleUI.rotationMultiplier));
vehicleUI.needle.transform.eulerAngles = new Vector3(vehicleUI.needle.transform.eulerAngles.x, vehicleUI.needle.transform.eulerAngles.y, -vehicleUI.needleRotation);
}
//Nitro Bar
if (vehicleUI.nitroBar)
{
if (player.GetComponent<Car_Controller>())
vehicleUI.nitroBar.fillAmount = player.GetComponent<Car_Controller>().nitroCapacity;
if (player.GetComponent<Motorbike_Controller>())
vehicleUI.nitroBar.fillAmount = player.GetComponent<Motorbike_Controller>().nitroCapacity;
}
//3D text mesh
if (!vehicleUI.speedText3D && GameObject.Find("3DSpeedText"))
vehicleUI.speedText3D = GameObject.Find("3DSpeedText").GetComponent<TextMesh>();
if (!vehicleUI.gearText3D && GameObject.Find("3DGearText"))
vehicleUI.gearText3D = GameObject.Find("3DGearText").GetComponent<TextMesh>();
if (vehicleUI.speedText3D)
{
if (player.GetComponent<Car_Controller>())
vehicleUI.speedText3D.text = player.GetComponent<Car_Controller>().currentSpeed + player.GetComponent<Car_Controller>()._speedUnit.ToString();
if (player.GetComponent<Motorbike_Controller>())
vehicleUI.speedText3D.text = player.GetComponent<Motorbike_Controller>().currentSpeed + player.GetComponent<Motorbike_Controller>()._speedUnit.ToString();
}
if (vehicleUI.gearText3D)
{
if (player.GetComponent<Car_Controller>())
vehicleUI.gearText3D.text = player.GetComponent<Car_Controller>().currentGear.ToString();
if (player.GetComponent<Motorbike_Controller>())
vehicleUI.gearText3D.text = player.GetComponent<Motorbike_Controller>().currentGear.ToString();
}
}
public void UpdateUIPanels()
{
if (!RaceManager.instance) return;
switch (RaceManager.instance._raceState)
{
//if starting grid, set all other panels active to false except from the starting panel
case RaceManager.RaceState.StartingGrid:
if (startingGridPanel) startingGridPanel.SetActive(true);
if (racePanel) racePanel.SetActive(false);
if (pausePanel) pausePanel.SetActive(false);
if (failRacePanel) failRacePanel.SetActive(false);
if (raceCompletePanel) raceCompletePanel.SetActive(false);
if (replayPanel) replayPanel.SetActive(false);
break;
//if racing, set all other panels active to false except from the racing panel
case RaceManager.RaceState.Racing:
if (startingGridPanel) startingGridPanel.SetActive(false);
if (racePanel) racePanel.SetActive(true);
if (pausePanel) pausePanel.SetActive(false);
if (failRacePanel) failRacePanel.SetActive(false);
if (raceCompletePanel) raceCompletePanel.SetActive(false);
if (replayPanel) replayPanel.SetActive(false);
break;
//if paused, set all other panels active to false except from the pause panel
case RaceManager.RaceState.Paused:
if (startingGridPanel) startingGridPanel.SetActive(false);
if (racePanel) racePanel.SetActive(false);
if (pausePanel) pausePanel.SetActive(true);
if (failRacePanel) failRacePanel.SetActive(false);
if (raceCompletePanel) raceCompletePanel.SetActive(false);
if (replayPanel) replayPanel.SetActive(false);
break;
//if the race is complete, set all other panels active to false except from the completion panel
case RaceManager.RaceState.Complete:
if (startingGridPanel) startingGridPanel.SetActive(false);
if (racePanel) racePanel.SetActive(false);
if (pausePanel) pausePanel.SetActive(false);
if (failRacePanel) failRacePanel.SetActive(false);
if (raceCompletePanel) raceCompletePanel.SetActive(true);
if (replayPanel) replayPanel.SetActive(false);
break;
//if the player is knocked out, set all other panels active to false except from the ko panel
case RaceManager.RaceState.KnockedOut:
if (startingGridPanel) startingGridPanel.SetActive(false);
if (racePanel) racePanel.SetActive(false);
if (pausePanel) pausePanel.SetActive(false);
if (failRacePanel) failRacePanel.SetActive(true);
if (raceCompletePanel) raceCompletePanel.SetActive(false);
if (replayPanel) replayPanel.SetActive(false);
break;
case RaceManager.RaceState.Replay:
if (startingGridPanel) startingGridPanel.SetActive(false);
if (racePanel) racePanel.SetActive(false);
if (pausePanel) pausePanel.SetActive(false);
if (failRacePanel) failRacePanel.SetActive(false);
if (raceCompletePanel) raceCompletePanel.SetActive(false);
if (replayPanel) replayPanel.SetActive(true);
break;
}
}
void ShowStartingGrid()
{
//loop through the total number of cars & show their race standings
if (startingGrid.Count > 0)
{
for (int i = 0; i < RankManager.instance.totalRacers; i++)
{
Statistics _statistics = RankManager.instance.racerRanks[i].racer.GetComponent<Statistics>();
if (_statistics == null) return;
//Position
if (startingGrid[i].position) startingGrid[i].position.text = _statistics.rank.ToString();
//Name
if (startingGrid[i].name) startingGrid[i].name.text = _statistics.racerDetails.racerName;
//Vehicle name
if (startingGrid[i].vehicleName) startingGrid[i].vehicleName.text = _statistics.racerDetails.vehicleName;
}
}
}
void ShowInRaceStandings()
{
if (racingUI.inRaceStandings.Count <= 0 || RankManager.instance.totalRacers <= 1)
return;
//in race standings
for (int i = 0; i < RankManager.instance.totalRacers; i++)
{
if (i < racingUI.inRaceStandings.Count)
{
Statistics _statistics = RankManager.instance.racerRanks[i].racer.GetComponent<Statistics>();
if (_statistics == null) return;
//Name
if (racingUI.inRaceStandings[i].name) racingUI.inRaceStandings[i].name.text = (RaceManager.instance._raceType != RaceManager.RaceType.SpeedTrap) ? _statistics.racerDetails.racerName
: _statistics.racerDetails.racerName + " [" + RankManager.instance.racerRanks[i].speedRecord + " mph]";
//Colors
if (player == _statistics)
{
racingUI.inRaceStandings[i].position.color = racingUI.playerColor;
racingUI.inRaceStandings[i].name.color = racingUI.playerColor;
}
else
{
racingUI.inRaceStandings[i].position.color = racingUI.normalColor;
racingUI.inRaceStandings[i].name.color = racingUI.normalColor;
}
}
}
}
public void RefreshInRaceStandings()
{
if (RankManager.instance.totalRacers <= 1) return;
for (int i = 0; i < racingUI.inRaceStandings.Count; i++)
{
if (i < RankManager.instance.totalRacers)
{
if (racingUI.inRaceStandings[i].position.transform.parent)
racingUI.inRaceStandings[i].position.transform.parent.gameObject.SetActive(true);
}
}
}
/// <summary>
/// Loops through the total number of racers and shows their standings
/// This function is called for non drift races because of different UI setup
/// </summary>
void ShowRaceResults()
{
if (raceResults.Count > 0)
{
for (int i = 0; i < RankManager.instance.totalRacers; i++)
{
Statistics _statistics = RankManager.instance.racerRanks[i].racer.GetComponent<Statistics>();
if (_statistics == null) return;
//Position
if (raceResults[i].position) raceResults[i].position.text = _statistics.rank.ToString();
//Name
if (raceResults[i].name)
{
if (RaceManager.instance._raceType != RaceManager.RaceType.SpeedTrap)
{
raceResults[i].name.text = _statistics.racerDetails.racerName;
}
else
{
raceResults[i].name.text = _statistics.racerDetails.racerName + " [" + RankManager.instance.racerRanks[i].speedRecord + " mph]";
}
}
//Total Race Time
if (raceResults[i].totalTime)
{
if (_statistics.finishedRace && !_statistics.knockedOut)
{
raceResults[i].totalTime.text = _statistics.totalRaceTime;
}
else if (_statistics.knockedOut)
{
raceResults[i].totalTime.text = "Knocked Out";
}
else
{
raceResults[i].totalTime.text = "Running...";
}
}
//Best Lap Time
if (raceResults[i].bestLapTime)
{
raceResults[i].bestLapTime.text = (_statistics.bestLapTime == string.Empty) ? "--:--:--" : _statistics.bestLapTime;
}
//Vehicle Name
if (raceResults[i].vehicleName)
{
raceResults[i].vehicleName.text = _statistics.racerDetails.vehicleName;
}
}
}
}
/// <summary>
/// Gets drift information from the driftpointcontroller and displays them
/// This function is only called for drift races because of different UI setup
/// </summary>
void ShowDriftResults()
{
if (driftpointcontroller)
{
if (driftResults.totalPoints)
driftResults.totalPoints.text = "Total Points : " + driftpointcontroller.totalDriftPoints.ToString("N0");
if (driftResults.driftRaceTime)
driftResults.driftRaceTime.text = "Time : " + driftpointcontroller.GetComponent<Statistics>().totalRaceTime;
if (driftResults.bestDrift)
driftResults.bestDrift.text = "Best Drift : " + driftpointcontroller.bestDrift.ToString("N0") + " pts";
if (driftResults.longestDrift)
driftResults.longestDrift.text = "Longest Drift : " + driftpointcontroller.longestDrift.ToString("0.00") + " s";
if (driftResults.gold)
driftResults.gold.gameObject.SetActive(driftpointcontroller.GetComponent<Statistics>().rank == 1);
if (driftResults.silver)
driftResults.silver.gameObject.SetActive(driftpointcontroller.GetComponent<Statistics>().rank == 2);
if (driftResults.bronze)
driftResults.bronze.gameObject.SetActive(driftpointcontroller.GetComponent<Statistics>().rank > 2);
}
}
public void ShowReplayUI()
{
//Display the replay progress bar
if (progressBar)
progressBar.fillAmount = ReplayManager.instance.ReplayPercent;
}
//Used to show useful race info
public void ShowRaceInfo(string info, float time, Color c)
{
StartCoroutine(RaceInfo(info, time, c));
}
IEnumerator RaceInfo(string info, float time, Color c)
{
if (!racingUI.raceInfo)
yield break;
if (racingUI.raceInfo.text == "")
{
racingUI.raceInfo.text = info;
Color col = c;
col.a = 1.0f;
racingUI.raceInfo.color = col;
yield return new WaitForSeconds(time);
//Do Fade Out
while (col.a > 0.0f)
{
col.a -= Time.deltaTime * 2.0f;
racingUI.raceInfo.color = col;
yield return null;
}
if (col.a <= 0.01f)
{
racingUI.raceInfo.text = string.Empty;
}
//Check if there are any other race infos that need to be displayed
CheckRaceInfoList();
}
else
{
raceInfos.Add(info);
}
}
public IEnumerator ShowDriftRaceInfo(string info, Color c)
{
if (!driftUI.driftStatus) yield break;
driftUI.driftStatus.text = info;
driftUI.driftStatus.color = c;
yield return new WaitForSeconds(2.0f);
driftUI.driftStatus.text = string.Empty;
}
public void CheckRaceInfoList()
{
if (raceInfos.Count > 0)
{
ShowRaceInfo(raceInfos[raceInfos.Count - 1], 2.0f, Color.white);
raceInfos.RemoveAt(raceInfos.Count - 1);
}
}
void WrongwayUI()
{
//Wrong way indication
if (racingUI.wrongwayText)
{
if (player.GetComponent<Statistics>().goingWrongway)
{
racingUI.wrongwayText.text = "Wrong Way!";
}
else
{
racingUI.wrongwayText.text = string.Empty;
}
}
if (racingUI.wrongwayImage)
{
if (player.GetComponent<Statistics>().goingWrongway)
{
racingUI.wrongwayImage.enabled = true;
}
else
{
racingUI.wrongwayImage.enabled = false;
}
}
}
string GetPrevLapTime()
{
if (player.prevLapTime != "")
{
return "Last " + player.prevLapTime;
}
else
{
return "Last --:--:--";
}
}
string GetBestLapTime()
{
if (PlayerPrefs.HasKey("BestTime" + SceneManager.GetActiveScene().name))
{
return "Best " + PlayerPrefs.GetString("BestTime" + SceneManager.GetActiveScene().name);
}
else
{
return "Best --:--:--";
}
}
public void SetCountDownText(string value)
{
if (!racingUI.countdown) return;
racingUI.countdown.text = value;
}
public void SetFailRace(string title, string reason)
{
if (failTitle) failTitle.text = title;
if (failReason) failReason.text = reason;
}
/// <summary>
/// Gets rid of all other UI apart from the FinishedText to show the "Race Completed" text in the End Race Rountine
/// </summary>
public void DisableRacePanelChildren()
{
if (!racingUI.finishedText) return;
RectTransform[] rectTransforms = racePanel.GetComponentsInChildren<RectTransform>();
foreach (RectTransform t in rectTransforms)
{
if (t != racePanel.GetComponent<RectTransform>() && t != racingUI.finishedText.GetComponent<RectTransform>())
{
t.gameObject.SetActive(false);
}
}
}
public void SetFinishedText(string word)
{
if (racingUI.finishedText)
racingUI.finishedText.text = word;
}
public void SetRewardText(string currency, string vehicleUnlock, string trackUnlock)
{
if (currency != "" && rewardTexts.rewardCurrency)
rewardTexts.rewardCurrency.text = "You won : " + currency + " Cr";
if (vehicleUnlock != "" && rewardTexts.rewardVehicle)
rewardTexts.rewardVehicle.text = "You Unlocked : " + vehicleUnlock;
if (trackUnlock != "" && rewardTexts.rewardTrack)
rewardTexts.rewardTrack.text = "You Unlocked : " + trackUnlock;
}
#region Screen Fade
public IEnumerator ScreenFadeOut(float speed)
{
//Get the color
Color col = screenFade.color;
if (col.a > 0.0f) yield break;
//Change the alpha to 1
col.a = 1;
screenFade.color = col;
//Fade out
while (col.a > 0.0f)
{
col.a -= Time.deltaTime * speed;
screenFade.color = col;
yield return null;
}
}
public IEnumerator ScreenFadeIn(float speed, bool loadScene, string scene)
{
//Get the color
Color col = screenFade.color;
//Change the alpha to 0
col.a = 0;
screenFade.color = col;
//Fade in
while (col.a < 1.0f)
{
col.a += Time.deltaTime * speed;
screenFade.color = col;
yield return null;
//Load the menu scene when fade completes
if (col.a >= 1.0f)
SceneManager.LoadScene(scene);
}
}
#endregion
#region UI Button Functions
public void StartCountDown(float time)
{
StartCoroutine(RaceManager.instance.Countdown(time));
}
public void PauseResume()
{
RaceManager.instance.PauseRace();
}
public void BackHome()
{
SceneController.JumpToScene(BPGSceneName.BPGHome);
}
public void Restart()
{
//unpause inorder to reset timescale & audiolistener vol
if (RaceManager.instance._raceState == RaceManager.RaceState.Paused)
{
PauseResume();
}
if (fadeOnExit && screenFade)
{
StartCoroutine(ScreenFadeIn(fadeSpeed * 2, true, SceneManager.GetActiveScene().name));
}
else
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
public void Exit()
{
//unpause inorder to reset timescale & audiolistener vol
if (RaceManager.instance._raceState == RaceManager.RaceState.Paused)
{
PauseResume();
}
if (fadeOnExit && screenFade)
{
StartCoroutine(ScreenFadeIn(fadeSpeed * 2, true, menuScene));
}
else
{
SceneManager.LoadScene(menuScene);
}
}
#endregion
}
}