Ejemplo n.º 1
0
    private void shiftGear()
    {
        float shiftThrottleFactor = Mathf.Clamp01((Time.time - lastShiftTime) / shiftSpeed);

        drivetrain.throttle      = throttle * shiftThrottleFactor;
        drivetrain.throttleInput = throttleInput;

        if (Input.GetKeyDown(KeyCode.A))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftUp();
        }
        if (Input.GetKeyDown(KeyCode.Z))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftDown();
        }
    }
Ejemplo n.º 2
0
    void Update()
    {
        // Steering
        Vector3 carDir          = transform.forward;
        float   fVelo           = GetComponent <Rigidbody>().velocity.magnitude;
        Vector3 veloDir         = GetComponent <Rigidbody>().velocity *(1 / fVelo);
        float   angle           = -Mathf.Asin(Mathf.Clamp(Vector3.Cross(veloDir, carDir).y, -1, 1));
        float   optimalSteering = angle / (wheels[0].maxSteeringAngle * Mathf.Deg2Rad);

        if (fVelo < 1)
        {
            optimalSteering = 0;
        }

        float steerInput = 0;

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            steerInput = -1;
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            steerInput = 1;
        }

        if (steerInput < steering)
        {
            float steerSpeed = (steering > 0)?(1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) :(1 / (steerTime + veloSteerTime * fVelo));
            if (steering > optimalSteering)
            {
                steerSpeed *= 1 + (steering - optimalSteering) * steerCorrectionFactor;
            }
            steering -= steerSpeed * Time.deltaTime;
            if (steerInput > steering)
            {
                steering = steerInput;
            }
        }
        else if (steerInput > steering)
        {
            float steerSpeed = (steering < 0)?(1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) :(1 / (steerTime + veloSteerTime * fVelo));
            if (steering < optimalSteering)
            {
                steerSpeed *= 1 + (optimalSteering - steering) * steerCorrectionFactor;
            }
            steering += steerSpeed * Time.deltaTime;
            if (steerInput < steering)
            {
                steering = steerInput;
            }
        }

        // Throttle/Brake

        bool accelKey = Input.GetKey(KeyCode.UpArrow);
        bool brakeKey = Input.GetKey(KeyCode.DownArrow);

        if (drivetrain.automatic && drivetrain.gear == 0)
        {
            accelKey = Input.GetKey(KeyCode.DownArrow);
            brakeKey = Input.GetKey(KeyCode.UpArrow);
        }

        if (Input.GetKey(KeyCode.LeftShift))
        {
            throttle      += Time.deltaTime / throttleTime;
            throttleInput += Time.deltaTime / throttleTime;
        }
        else if (accelKey)
        {
            if (drivetrain.slipRatio < 0.10f)
            {
                throttle += Time.deltaTime / throttleTime;
            }
            else if (!tractionControl)
            {
                throttle += Time.deltaTime / throttleTimeTraction;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }

            if (throttleInput < 0)
            {
                throttleInput = 0;
            }
            throttleInput += Time.deltaTime / throttleTime;
            brake          = 0;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }
        throttle = Mathf.Clamp01(throttle);

        if (brakeKey)
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake += Time.deltaTime / throttleTime;
            }
            else
            {
                brake += Time.deltaTime / throttleTimeTraction;
            }
            throttle       = 0;
            throttleInput -= Time.deltaTime / throttleTime;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                brake -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }
        brake         = Mathf.Clamp01(brake);
        throttleInput = Mathf.Clamp(throttleInput, -1, 1);

        // Handbrake
        handbrake = Mathf.Clamp01(handbrake + (Input.GetKey(KeyCode.Space)? Time.deltaTime: -Time.deltaTime));

        // Gear shifting
        float shiftThrottleFactor = Mathf.Clamp01((Time.time - lastShiftTime) / shiftSpeed);

        drivetrain.throttle      = throttle * shiftThrottleFactor;
        drivetrain.throttleInput = throttleInput;

        if (Input.GetKeyDown(KeyCode.A))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftUp();
        }
        if (Input.GetKeyDown(KeyCode.Z))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftDown();
        }

        // Apply inputs
        foreach (Wheel w in wheels)
        {
            w.brake     = brake;
            w.handbrake = handbrake;
            w.steering  = steering;
        }
    }
Ejemplo n.º 3
0
    void Update()
    {
        // Steering
        Vector3 carDir          = transform.forward;
        float   fVelo           = GetComponent <Rigidbody>().velocity.magnitude;
        Vector3 veloDir         = GetComponent <Rigidbody>().velocity *(1 / fVelo);
        float   angle           = -Mathf.Asin(Mathf.Clamp(Vector3.Cross(veloDir, carDir).y, -1, 1));
        float   optimalSteering = angle / (wheels[0].maxSteeringAngle * Mathf.Deg2Rad);

        if (fVelo < 1)
        {
            optimalSteering = 0;
        }

        float steerInput = 0;

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            steerInput = -1;
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            steerInput = 1;
        }

        if (steerInput < steering)
        {
            float steerSpeed = (steering > 0) ? (1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) : (1 / (steerTime + veloSteerTime * fVelo));
            if (steering > optimalSteering)
            {
                steerSpeed *= 1 + (steering - optimalSteering) * steerCorrectionFactor;
            }
            steering -= steerSpeed * Time.deltaTime;
            if (steerInput > steering)
            {
                steering = steerInput;
            }
        }
        else if (steerInput > steering)
        {
            float steerSpeed = (steering < 0) ? (1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) : (1 / (steerTime + veloSteerTime * fVelo));
            if (steering < optimalSteering)
            {
                steerSpeed *= 1 + (optimalSteering - steering) * steerCorrectionFactor;
            }
            steering += steerSpeed * Time.deltaTime;
            if (steerInput < steering)
            {
                steering = steerInput;
            }
        }


        bool accelKey = Input.GetKey(KeyCode.UpArrow);
        bool brakeKey = Input.GetKey(KeyCode.DownArrow);

        if (drivetrain.automatic && drivetrain.gear == 0)
        {
            accelKey = Input.GetKey(KeyCode.DownArrow);
            brakeKey = Input.GetKey(KeyCode.UpArrow);
        }

        if (Input.GetKey(KeyCode.LeftShift))
        {
            throttle      += Time.deltaTime / throttleTime;
            throttleInput += Time.deltaTime / throttleTime;
        }
        else if (accelKey)
        {
            if (drivetrain.slipRatio < 0.10f)
            {
                throttle += Time.deltaTime / throttleTime;
            }
            else if (!tractionControl)
            {
                throttle += Time.deltaTime / throttleTimeTraction;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }

            if (throttleInput < 0)
            {
                throttleInput = 0;
            }
            throttleInput += Time.deltaTime / throttleTime;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }

        throttle = Mathf.Clamp01(throttle);

        if (brakeKey)
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake += Time.deltaTime / throttleTime;
            }
            else
            {
                brake += Time.deltaTime / throttleTimeTraction;
            }
            throttle       = 0;
            throttleInput -= Time.deltaTime / throttleTime;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                brake -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }

        brake         = Mathf.Clamp01(brake);
        throttleInput = Mathf.Clamp(throttleInput, -1, 1);

        // Handbrake
        handbrake = (Input.GetKey(KeyCode.Space) || Input.GetKey(KeyCode.JoystickButton2)) ? 1f : 0f;

        // Gear shifting
        float shiftThrottleFactor = Mathf.Clamp01((Time.time - lastShiftTime) / shiftSpeed);

        if (drivetrain.gear == 0 && Input.GetKey(KeyCode.UpArrow))
        {
            throttle = 0.4f;// Anti reverse lock thingy??
        }

        if (drivetrain.gear == 0)
        {
            drivetrain.throttle = Input.GetKey(KeyCode.UpArrow) ? throttle : 0f;
        }
        else
        {
            drivetrain.throttle = Input.GetKey(KeyCode.UpArrow) ? (tractionControl ? throttle : 1) * shiftThrottleFactor : 0f;
        }

        drivetrain.throttleInput = throttleInput;

        if (Input.GetKeyDown(KeyCode.A))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftUp();
        }

        if (Input.GetKeyDown(KeyCode.Z))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftDown();
        }

        //play gear shift sound
        if (gearShifted && gearShiftedFlag && drivetrain.gear != 1)
        {
            GetComponent <SoundController>().playShiftUp();
            gearShifted     = false;
            gearShiftedFlag = false;
        }


        // ABS Trigger (This prototype version is used to prevent wheel lock , currently expiremental)
        if (absControl)
        {
            brake -= brake >= 0.1f ? 0.1f : 0f;
        }

        // Apply inputs
        foreach (Wheel w in wheels)
        {
            w.brake     = Input.GetKey(KeyCode.DownArrow) ? brake :  0;
            w.handbrake = handbrake;
            w.steering  = steering;
        }

        // Reset Car position and rotation in case it rolls over
        if (Input.GetKeyDown(KeyCode.R))
        {
            transform.position = new Vector3(transform.position.x, transform.position.y + 2f, transform.position.z);
            transform.rotation = Quaternion.Euler(0, transform.localRotation.y, 0);
        }


        // Traction Control Toggle
        if (Input.GetKeyDown(KeyCode.T))
        {
            if (tractionControl)
            {
                tractionControl = false;
            }
            else
            {
                tractionControl = true;
            }
        }

        // Anti-Brake Lock Toggle
        if (Input.GetKeyDown(KeyCode.B))
        {
            if (absControl)
            {
                absControl = false;
            }
            else
            {
                absControl = true;
            }
        }
    }
Ejemplo n.º 4
0
    void Update()
    {
        // Steering
        Vector3 carDir          = transform.forward;
        float   fVelo           = rigidbody.velocity.magnitude;
        Vector3 veloDir         = rigidbody.velocity * (1 / fVelo);
        float   angle           = -Mathf.Asin(Mathf.Clamp(Vector3.Cross(veloDir, carDir).y, -1, 1));
        float   optimalSteering = angle / (wheels[0].maxSteeringAngle * Mathf.Deg2Rad);

        if (fVelo < 1)
        {
            optimalSteering = 0;
        }

        float steerInput = 0;

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            steerInput = -1;
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            steerInput = 1;
        }

        if (steerInput < steering)
        {
            float steerSpeed = (steering > 0)?(1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) :(1 / (steerTime + veloSteerTime * fVelo));
            if (steering > optimalSteering)
            {
                steerSpeed *= 1 + (steering - optimalSteering) * steerCorrectionFactor;
            }
            steering -= steerSpeed * Time.deltaTime;
            if (steerInput > steering)
            {
                steering = steerInput;
            }
        }
        else if (steerInput > steering)
        {
            float steerSpeed = (steering < 0)?(1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) :(1 / (steerTime + veloSteerTime * fVelo));
            if (steering < optimalSteering)
            {
                steerSpeed *= 1 + (optimalSteering - steering) * steerCorrectionFactor;
            }
            steering += steerSpeed * Time.deltaTime;
            if (steerInput < steering)
            {
                steering = steerInput;
            }
        }

        // Throttle/Brake

        bool accelKey  = Input.GetKey(KeyCode.UpArrow);
        bool brakeKey  = Input.GetKey(KeyCode.DownArrow);
        bool brakeFull = Input.GetKey(KeyCode.B);
        bool resetCar  = Input.GetKeyDown(KeyCode.R);
        bool debugMode = Input.GetKeyDown(KeyCode.F1);

        if (resetCar)
        {
            this.rigidbody.rotation = Quaternion.identity;
            this.rigidbody.MovePosition(transform.position + transform.up * 0.5f);
        }

        if (drivetrain.automatic && drivetrain.gear == 0)
        {
            accelKey = Input.GetKey(KeyCode.DownArrow);
            brakeKey = Input.GetKey(KeyCode.UpArrow);
        }
        if (accelKey)
        {
            if (drivetrain.slipRatio < 0.10f)
            {
                throttle += Time.deltaTime / throttleTime;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }

            if (throttleInput < 0)
            {
                throttleInput = 0;
            }
            throttleInput += Time.deltaTime / throttleTime;
            brake          = 0;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }
        throttle = Mathf.Clamp01(throttle);

        if (brakeKey)
        {
            throttleInput -= Time.deltaTime / throttleTime;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                brake -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }
        brake         = Mathf.Clamp01(brake);
        throttleInput = Mathf.Clamp(throttleInput, -1, 1);

        // Handbrake
        handbrake = Mathf.Clamp01(handbrake + (Input.GetKey(KeyCode.Space)? Time.deltaTime: -Time.deltaTime));

        // Gear shifting
        float shiftThrottleFactor = Mathf.Clamp01((Time.time - lastShiftTime) / shiftSpeed);

        drivetrain.throttle      = throttle * shiftThrottleFactor;
        drivetrain.throttleInput = throttleInput;

        if (Input.GetKeyDown(KeyCode.A))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftUp();
        }
        if (Input.GetKeyDown(KeyCode.Z))
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftDown();
        }

        // Apply inputs
        foreach (Wheel w in wheels)
        {
            w.brake     = brake;
            w.handbrake = handbrake;
            w.steering  = steering;
            if (brakeFull)
            {
                w.angularVelocity = 0f;
            }
            if (debugMode)
            {
                bool temp = !w.debugWheelsVelo;
                w.debugWheelsVelo  = temp;
                w.debugRoadForce   = temp;
                w.debugCollisions  = temp;
                w.debugSuspensions = temp;
            }
        }
    }
    void Update()
    {
        // 拿車子的方向,速度 & 速度方向
        Vector3 carDir  = transform.forward;
        float   fVelo   = GetComponent <Rigidbody>().velocity.magnitude;
        Vector3 veloDir = GetComponent <Rigidbody>().velocity.normalized;

        // 算出車子 slipAngle 的夾角
        float angle           = -Mathf.Asin(Mathf.Clamp(Vector3.Cross(veloDir, carDir).y, -1, 1));
        float optimalSteering = angle / (wheels[0].maxSteeringAngle * Mathf.Deg2Rad);

        if (fVelo < 1)
        {
            optimalSteering = 0;
        }

        #region Steering 的 左右
        steerInput = 0;
        switch (Application.platform)
        {
        case RuntimePlatform.Android:
            /*if (MoblieLeft)
            *   steerInput = -1;
            *  if (MoblieRight)
            *   steerInput = 1;*/
            steerInput = GyroFunction(Input.gyro.gravity.x);
            //Mathf.Clamp(Input.gyro.gravity.x * 2, -1, 1);
            break;

        case RuntimePlatform.WindowsEditor:
            if (Input.GetKey(KeyCode.LeftArrow))
            {
                steerInput = -1;
            }
            if (Input.GetKey(KeyCode.RightArrow))
            {
                steerInput = 1;
            }
            if (Input.GetKey(KeyCode.Space))
            {
                MoblieDrift = true;
            }
            break;

        case RuntimePlatform.PS4:
            InputDevice input = InputManager.ActiveDevice;
            steerInput = input.LeftStickX.Value;
            break;
        }
        #endregion
#if UNITY_EDITOR
        if (bAutoControlled)
        {
            //For camera test scene
            if (autoLeft)
            {
                steerInput = -1;
            }
            if (autoRight)
            {
                steerInput = 1;
            }
        }
        if (leftFlag)
        {
            steerInput = -1;
        }
        if (rightFlag)
        {
            steerInput = 1;
        }
#endif
        if (steerInput < steering)                                          // 左轉
        {
            // Steering > 0 代表從右邊反打回來
            float steerSpeed = (steering > 0) ? (1 / steerReleaseTime) : (1 / (steerTime + veloSteerTime * fVelo));
            if (steering > optimalSteering)
            {
                steerSpeed *= 1 + (steering - optimalSteering) * steerCorrectionFactor;
            }
            steering -= steerSpeed * Time.deltaTime;

            // 要讓他卡在 -1
            if (steerInput > steering)
            {
                steering = steerInput;
            }
        }
        else if (steerInput > steering)                                     // 右轉
        {
            float steerSpeed = (steering < 0) ? (1 / steerReleaseTime) : (1 / (steerTime + veloSteerTime * fVelo));
            if (steering < optimalSteering)
            {
                steerSpeed *= 1 + (optimalSteering - steering) * steerCorrectionFactor;
            }
            steering += steerSpeed * Time.deltaTime;

            // 要讓他卡在 1
            if (steerInput < steering)
            {
                steering = steerInput;
            }
        }


        #region 油門按鍵 & 煞車鍵
        bool accelKey = false;
        bool brakeKey = false;
        switch (Application.platform)
        {
        case RuntimePlatform.Android:
            accelKey = !(MoblieBrake);
            brakeKey = MoblieBrake;
            break;

        case RuntimePlatform.WindowsEditor:
            accelKey = Input.GetKey(KeyCode.UpArrow);
            brakeKey = Input.GetKey(KeyCode.DownArrow);

            if (Input.GetKeyDown(KeyCode.Z))
            {
                UseNitrous = true;
            }
            else if (Input.GetKeyUp(KeyCode.Z))
            {
                UseNitrous = false;
            }
            break;

        case RuntimePlatform.PS4:
            InputDevice input = InputManager.ActiveDevice;
            accelKey   = input.RightTrigger.IsPressed;
            brakeKey   = input.LeftTrigger.IsPressed;
            UseNitrous = input.Action1.IsPressed;
            break;
        }
        #endregion

        // 倒車的時候,加速和煞車的鑑識相反的
        if (drivetrain.automatic && drivetrain.gear == 0)
        {
            switch (Application.platform)
            {
            case RuntimePlatform.Android:
                accelKey = MoblieBrake;
                brakeKey = !(MoblieBrake);
                break;

            case RuntimePlatform.WindowsEditor:
                accelKey = Input.GetKey(KeyCode.DownArrow);
                brakeKey = Input.GetKey(KeyCode.UpArrow);
                break;

            case RuntimePlatform.PS4:
                InputDevice input = InputManager.ActiveDevice;
                accelKey = input.LeftTrigger.IsPressed;
                brakeKey = input.RightTrigger.IsPressed;
                break;
            }
        }
#if UNITY_EDITOR
        if (bAutoControlled)
        {
            //For camera test scene
            accelKey = autoAccel || accelKey;
            brakeKey = autoBrake || brakeKey;
        }
        if (accelFlag)
        {
            accelKey = true;
        }
#endif

        if (accelKey)
        {
            // 引擎也有 slipRatio? 當然。
            if (drivetrain.slipRatio < 0.10f)
            {
                throttle += Time.deltaTime / throttleTime;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }

            if (throttleInput < 0)
            {
                throttleInput = 0;
            }
            if (throttleForDrifting < 0)
            {
                throttleForDrifting = 0;
            }

            throttleInput       += Time.deltaTime / throttleTime;
            throttleForDrifting += Time.deltaTime / throttleTime;
            brake = 0;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTimeTraction;
            }

            throttleForDrifting -= Time.deltaTime / throttleReleaseTime;
        }
        throttle            = Mathf.Clamp01(throttle);
        throttleForDrifting = Mathf.Clamp01(throttleForDrifting);

        if (brakeKey)
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake += Time.deltaTime / throttleTime;
            }
            else
            {
                brake += Time.deltaTime / throttleTimeTraction;
            }
            throttle       = 0;
            throttleInput -= Time.deltaTime / throttleTime;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                brake -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }
        brake         = Mathf.Clamp01(brake);
        throttleInput = Mathf.Clamp(throttleInput, -1, 1);

        // Handbrake
        handbrake = Mathf.Clamp01(handbrake + (Input.GetKey(KeyCode.Space) ? Time.deltaTime : -Time.deltaTime));

        // Gear shifting
        float shiftThrottleFactor = Mathf.Clamp01((Time.time - lastShiftTime) / shiftSpeed);
        drivetrain.throttle      = throttle * shiftThrottleFactor;
        drivetrain.throttleInput = throttleInput;

        if (!drivetrain.automatic)
        {
            if (Input.GetKeyDown(KeyCode.A))
            {
                lastShiftTime = Time.time;
                drivetrain.ShiftUp();
            }
            else if (Input.GetKeyDown(KeyCode.Z))
            {
                lastShiftTime = Time.time;
                drivetrain.ShiftDown();
            }
        }

        // Apply inputs
        foreach (Wheel w in wheels)
        {
            w.brake     = brake;
            w.handbrake = handbrake;
            w.steering  = steering;
        }
    }
Ejemplo n.º 6
0
    void Update()
    {
        // 解决车轮转向
        Vector3 carDir          = transform.forward;
        float   fVelo           = rigidbody.velocity.magnitude;
        Vector3 veloDir         = rigidbody.velocity * (1 / fVelo);
        float   angle           = -Mathf.Asin(Mathf.Clamp(Vector3.Cross(veloDir, carDir).y, -1, 1));
        float   optimalSteering = angle / (wheels[0].maxSteeringAngle * Mathf.Deg2Rad);

        if (fVelo < 1)
        {
            optimalSteering = 0;
        }

        float steerInput = 0;

        if (InputManager.GetInst().triggerSteeringLeft)
        {
            steerInput = -1;
        }
        if (InputManager.GetInst().triggerSteeringRight)
        {
            steerInput = 1;
        }

        // 车轮左转
        if (steerInput < steering)
        {
            float steerSpeed = (steering > 0)?(1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) :(1 / (steerTime + veloSteerTime * fVelo));
            if (steering > optimalSteering)
            {
                steerSpeed *= 1 + (steering - optimalSteering) * steerCorrectionFactor;
            }
            steering -= steerSpeed * Time.deltaTime;
            if (steerInput > steering)
            {
                steering = steerInput;
            }
        }
        // 车轮右转
        else if (steerInput > steering)
        {
            float steerSpeed = (steering < 0)?(1 / (steerReleaseTime + veloSteerReleaseTime * fVelo)) :(1 / (steerTime + veloSteerTime * fVelo));
            if (steering < optimalSteering)
            {
                steerSpeed *= 1 + (optimalSteering - steering) * steerCorrectionFactor;
            }
            steering += steerSpeed * Time.deltaTime;
            if (steerInput < steering)
            {
                steering = steerInput;
            }
        }

        // Throttle/Brake

        bool accelKey = InputManager.GetInst().triggerThrottle;
        bool brakeKey = InputManager.GetInst().triggerBreak;


        if (drivetrain.automatic && drivetrain.gear == 0)
        {
            accelKey = InputManager.GetInst().triggerBreak;
            brakeKey = InputManager.GetInst().triggerThrottle;
        }

        //if (Input.GetKey (KeyCode.LeftShift))
        //{
        //    throttle += Time.deltaTime / throttleTime;
        //    throttleInput += Time.deltaTime / throttleTime;
        //}
        //else
        if (accelKey)
        {
            if (drivetrain.slipRatio < 0.10f)
            {
                throttle += Time.deltaTime / throttleTime;
            }
            else if (!tractionControl)
            {
                throttle += Time.deltaTime / throttleTimeTraction;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }

            if (throttleInput < 0)
            {
                throttleInput = 0;
            }
            throttleInput += Time.deltaTime / throttleTime;
            brake          = 0;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                throttle -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                throttle -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }
        throttle = Mathf.Clamp01(throttle);

        if (brakeKey)
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake += Time.deltaTime / throttleTime;
            }
            else
            {
                brake += Time.deltaTime / throttleTimeTraction;
            }
            throttle       = 0;
            throttleInput -= Time.deltaTime / throttleTime;
        }
        else
        {
            if (drivetrain.slipRatio < 0.2f)
            {
                brake -= Time.deltaTime / throttleReleaseTime;
            }
            else
            {
                brake -= Time.deltaTime / throttleReleaseTimeTraction;
            }
        }
        brake         = Mathf.Clamp01(brake);
        throttleInput = Mathf.Clamp(throttleInput, -1, 1);

        // Handbrake
        handbrake = Mathf.Clamp01(handbrake + (InputManager.GetInst().triggerHandBreak ? Time.deltaTime : -Time.deltaTime));

        // Gear shifting
        float shiftThrottleFactor = Mathf.Clamp01((Time.time - lastShiftTime) / shiftSpeed);

        drivetrain.throttle      = throttle * shiftThrottleFactor;
        drivetrain.throttleInput = throttleInput;

        if (InputManager.GetInst().triggerShiftUp)
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftUp();
        }
        if (InputManager.GetInst().triggerShiftDown)
        {
            lastShiftTime = Time.time;
            drivetrain.ShiftDown();
        }

        // Apply inputs
        foreach (Wheel w in wheels)
        {
            w.brake     = brake;
            w.handbrake = handbrake;
            w.steering  = steering;
        }

        if (InputManager.GetInst().triggerNitro)
        {
            drivetrain.isUsingNitro = true;
        }
        else
        {
            drivetrain.isUsingNitro = false;
        }
    }