WheelController.SimulateTraction C# (CSharp) Method

SimulateTraction() public method

public SimulateTraction ( ) : void
return void
    void SimulateTraction()
    {
        weightTransfer = 1.9f * 1.0f / Vector3.Distance(transform.position, transform.root.GetComponent<Rigidbody>().worldCenterOfMass);

        fwd = rigidbody.transform.forward;
        fwd = Quaternion.Euler(0, steeringAngle, 0) * fwd;
        fwd.Normalize();

        Vector3 right = rigidbody.transform.right;
        right = Vector3.Cross(transform.up, fwd).normalized;
        right = ProjectVectorOnPlane(groundInfo.normal, right);

        //localVel = Vector3.Lerp(localVel, transform.InverseTransformDirection(rigidbody.GetPointVelocity(transform.position)), Time.fixedDeltaTime * 1.5f);
        localVel = transform.InverseTransformDirection(rigidbody.GetPointVelocity(transform.position));
        Debug.DrawLine(transform.position, transform.position + rigidbody.GetPointVelocity(transform.position), Color.green);
        //totalTorque = driveTorque + tractionTorque + brakeTorque;

        float wheelInertia = mass * radius * radius * 0.5f;    // Mass is 70.0kg
        //totalTorque = (-1.0f * Mathf.Sign(driveTorque) * tractionTorque + driveTorque - brakeTorque);
        //Mathf.Clamp(brakeTorque, -driveTorque, driveTorque);
        if (angularVelocityDegSec == 0.0f)
            brakeTorque = 0.0f;
        //brakeTorque = -brakeTorque;
        if (linearVel < 0.0f)
            brakeTorque = 0.0f;
        // totalTorque = driveTorque - brakeTorque;
        totalTorque = driveTorque + brakeTorque * -1.0f;//* (angularVelocityDegSec *0.1f);

        float wheelAngularAccel = (totalTorque) / wheelInertia;

        // If the wheel is driven by the engine or braking
        if (totalTorque != 0.0f)
        {
            angularVelocityDegSec += wheelAngularAccel * Time.fixedDeltaTime;
            linearVel = angularVelocityDegSec * 0.017453292519968f * radius;
        }
        // If the wheel is spinning free
        else
        {
            angularVelocityDegSec = (localVel.z) * (1.0f / 0.017453292519968f) * (1.0f / radius);
            //linearVel = Mathf.Lerp (linearVel, localVel.z, Time.fixedDeltaTime * 300.0f);
            linearVel = localVel.z;
        }

        if(eBrakeEnabled && driveTorque == 0.0f)
        {
            angularVelocityDegSec = 0.0f;
            linearVel = 0.0f;
        }

        if (connectedWheel == null) {
            slipRatio = (linearVel - localVel.z) / Mathf.Abs(localVel.z);// *0.1f;
            slipRatio = Mathf.Clamp(slipRatio, -6f, 6f);
            // If it's NaN, then the car and the wheel are stopped (0 / 0 division)
            if (float.IsNaN(slipRatio)) {
                slipRatio = 0.0f;
            }
            // If it's infinity, then the wheel is spinning but the car is stopped (x / 0) division
            else if (float.IsInfinity(slipRatio)) {
                slipRatio = 1.0f * Mathf.Sign(slipRatio);
            }
        } else {
            slipRatio = connectedWheel.slipRatio;
        }

        tractionForce = frictionCurve.Evaluate(Mathf.Abs(slipRatio)) * tractionCoeff * Mathf.Sign(slipRatio); //* sideCurve.Evaluate(Mathf.Abs(slipAngle / 90.0f));
        tractionForce = Mathf.Clamp(tractionForce, -maxTractionAmt, maxTractionAmt);
        tractionTorque = tractionForce / radius;

        Vector3 tractionForceV = fwd * tractionForce;
        //Debug.DrawLine(transform.position, 0.01f * tractionForceV + transform.position, Color.red);

        //if(Mathf.Abs(slipRatio) > 0.01f)
        if(totalTorque != 0.0f) {
            if(!(eBrakeEnabled && driveTorque != 0.0f))
                rigidbody.AddForceAtPosition(tractionForceV * weightTransfer * transform.root.GetComponent<Rigidbody>().mass, transform.position);
            //rigidbody.AddForceAtPosition(fwd * 100.0f, transform.position);
            //Debug.Log(gameObject.name + " " + tractionForce + " " + slipRatio + " " + linearVel + " " + localVel.z);
        }

        fwdForce = tractionForceV.magnitude;

        // Calculate the slip angle: Angle between forward direction vector of the wheel and velocity vector of the wheel

        slipAngle = Vector3.Angle(Mathf.Sign(linearVel) * fwd, rigidbody.velocity.normalized);
        Vector3 cross = Vector3.Cross(Mathf.Sign(linearVel) * fwd, rigidbody.velocity.normalized);

        if (cross.y < 0) slipAngle = -slipAngle;

        slipAngle *= Mathf.Sign(linearVel);

        Vector3 sideForce = -right * sideCurve.Evaluate(Mathf.Abs(slipAngle / 90.0f)) * Mathf.Sign(slipAngle) * sideTraction;// * Mathf.Clamp((Mathf.Abs(localVel.x) / 0.010f), 0.0f, 1.0f);

        float sideForceMultiplier = forceCurve.Evaluate(localVel.magnitude / 2.0f);
        sideForce *= sideForceMultiplier;
        //this.sideForce = sideForce.magnitude;
        sideForce = sideForce.magnitude > maxSideForce ? sideForce.normalized * maxSideForce : sideForce;
        //sideForce *= Mathf.Clamp(rigidbody.velocity.magnitude / 0.50f , - 1.0f, 1.0f);
        //sideForce = transform.TransformDirection(sideForce);

        Debug.DrawLine(transform.position, sideForce + transform.position, Color.yellow);

        prevPos = transform.position;

        Debug.DrawLine(transform.position, transform.position + fwd * 5.0f, Color.blue);
        //Debug.DrawLine(transform.position, transform.position + right * 5.0f, Color.red);
        //if (Mathf.Abs(linearVel) < 0.82f && totalTorque == 0.0f)
        //{
        //    rigidbody.drag = Mathf.Lerp(rigidbody.drag, 100.0f, Time.deltaTime * 10.0f);
        //}
        //else
        //{
        //    rigidbody.drag = Mathf.Lerp(rigidbody.drag, 0.0f, Time.deltaTime * 10.0f);
        rigidbody.AddForceAtPosition(sideForce * weightTransfer * transform.root.GetComponent<Rigidbody>().mass /** frictionCurve.Evaluate(Mathf.Abs(slipRatio) + 0.4f)*/, transform.position);

        //}

           // rigidbody.AddForce(-downForce * rigidbody.transform.up);
    }