Exemplo n.º 1
0
    // Called once per physics update
    void FixedUpdate()
    {
        //Raycast down along the suspension to find out how far the ground is to the wheel
        if (Physics.Raycast(new Ray(_dummyWheel.position, -_dummyWheel.up), out _hit, groundDetectorDistance, groundLayers)) //The wheel is in contact with the ground
        {
            if (!_isGrounded)                                                                                                //If not previously grounded, set the prevPosition value to the wheel's current position.
            {
                _prevPosition = _dummyWheel.position;
            }
            _isGrounded = true;
        }
        else //The wheel is in the air
        {
            _isGrounded = false;
        }

        //Set steering angle of the wheel dummy
        _dummyWheel.localEulerAngles = new Vector3(0, _wheelSteerAngle, 0);
        //Calculate the wheel's rotation given it's angular velocity
        _wheelRotationAngle += _wheelAngularVelocity * Time.deltaTime;
        //Set the rotation and steer angle of the wheel model
        this.transform.localEulerAngles = new Vector3(_wheelRotationAngle, _wheelSteerAngle, 0);

        //Apply rolling force to tires if they are grounded and don't have motor torque applied to them.
        if (_isGrounded && _wheelMotorTorque == 0)
        {
            //Apply angular force to wheel from slip
            _wheelAngularVelocity -= Mathf.Sign(_forwardSlip) * _forwardFriction.Evaluate(_forwardSlip) / (Mathf.PI * 2.0f * radius) / mass * Time.deltaTime;
        }
        //Apply motor torque
        _wheelAngularVelocity += _wheelMotorTorque / radius / mass * Time.deltaTime;
        //Apply brake torque
        _wheelAngularVelocity -= Mathf.Sign(_wheelAngularVelocity) * Mathf.Min(Mathf.Abs(_wheelAngularVelocity), _wheelBrakeTorque * radius / mass * Time.deltaTime);

        if (_isGrounded && parentRigidbody != null)
        {
            //Calculate the wheel's linear velocity
            Vector3 velocity = (transform.position - _prevPosition) / Time.fixedDeltaTime;
            _prevPosition = transform.position;
            //Store the forward and sideways direction to improve performance
            Vector3 forward  = _dummyWheel.forward;
            Vector3 sideways = -_dummyWheel.right;
            //Calculate the forward and sideways velocity components relative to the wheel
            Vector3 forwardVelocity  = Vector3.Dot(velocity, forward) * forward;
            Vector3 sidewaysVelocity = Vector3.Dot(velocity, sideways) * sideways;
            //Calculate the slip velocities. Note that these values are different from the standard slip calculation.
            _forwardSlip  = -Mathf.Sign(Vector3.Dot(forward, forwardVelocity)) * forwardVelocity.magnitude + (_wheelAngularVelocity * Mathf.PI / 180.0f * radius);
            _sidewaysSlip = -Mathf.Sign(Vector3.Dot(sideways, sidewaysVelocity)) * sidewaysVelocity.magnitude;
            //Forward slip force
            _totalForce = _dummyWheel.forward * Mathf.Sign(_forwardSlip) * _forwardFriction.Evaluate(_forwardSlip);
            //Lateral slip force
            _totalForce -= _dummyWheel.right * Mathf.Sign(_sidewaysSlip) * _forwardFriction.Evaluate(_sidewaysSlip);

            parentRigidbody.AddForceAtPosition(_totalForce, transform.position);
        }
    }