飞车-源代码UNITY

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

    }

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xdpcxq1029

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值