Beispiel #1
0
    private void ComputeWheelForce(Axle a, RaycastWheel w, Vector3 wsPos, Vector3 wsDown, float fixedDeltaTime)
    {
        w.LocalWheelRotation = Quaternion.Euler(new Vector3(0f, w.yRad * Mathf.Rad2Deg, 0f));
        Quaternion wsWheelRot = transform.rotation * w.LocalWheelRotation;

        Debug.DrawLine(wsPos, wsWheelRot * Vector3.right * 10f * Mathf.Sign(steeringInput) + wsPos, Color.yellow);

        //Debug.Log($"wr:{w.yRad}");

        Vector3 wsAxleLeft = wsWheelRot * Vector3.left;


        ray.direction = wsDown;

        ray.origin = wsPos + wsAxleLeft * a.wheelWidth;
        RaycastHit hit1 = new RaycastHit();
        bool       b1   = Physics.Raycast(ray, out hit1, w.MaxDistance);


        ray.origin = wsPos - wsAxleLeft * a.wheelWidth;
        RaycastHit hit2 = new RaycastHit();
        bool       b2   = Physics.Raycast(ray, out hit2, w.MaxDistance);


        bool b0 = Physics.Raycast(ray, out w.hit, w.MaxDistance);


        if (!b0 || !b1 || !b2)
        {
            w.ResetCompression(fixedDeltaTime);

            return;
        }

        w.isGrounded = true;

        Vector3 suspensionForce = w.CalculateSuspensionForce(wsDown, w.hit.distance, w.hit.normal, fixedDeltaTime);

        rb.AddForceAtPosition(suspensionForce, w.hit.point);

        Debug.DrawRay(wsPos, w.hit.distance * wsDown, Color.magenta);

        Vector3 contact_up      = w.hit.normal;
        Vector3 contact_right   = (hit1.point - hit2.point).normalized;
        Vector3 contact_forward = Vector3.Cross(contact_up, contact_right);

        Vector3 wheelVelocity = rb.GetPointVelocity(w.hit.point);

        Vector3 rvel          = Vector3.Dot(wheelVelocity, contact_right) * contact_right;
        Vector3 fvel          = Vector3.Dot(wheelVelocity, contact_forward) * contact_forward;
        Vector3 slideVelocity = (rvel + fvel) * 0.5f;


        Vector3 slidingForce = (slideVelocity * rb.mass / fixedDeltaTime) / wheelsCount;

        Vector3 frictionForce = -slidingForce;

        Vector3 longitudinalForce = Vector3.Dot(frictionForce, contact_forward) * contact_forward;

        frictionForce -= longitudinalForce;



        rb.AddForceAtPosition(frictionForce, w.hit.point);



        float currentSpeed = _currentSpeedKmH;
        bool  brake        = false;

        if (currentSpeed < 0f && accelerationInput < 0f)
        {
            brake = true;
        }


        float forceMagnitude = Mathf.Sign(accelerationInput) * accelerationCurve.Evaluate(Mathf.Abs(accelerationInput)); //CalcAccelForceMagnitude();

        if (!brake && currentSpeed < capSpeed && Mathf.Abs(forceMagnitude) > 0.01f)
        {
            Vector3 forcePoint  = w.hit.point;
            Vector3 engineForce = contact_forward * forceMagnitude / wheelsCount / fixedDeltaTime;

            rb.AddForceAtPosition(engineForce, forcePoint);

            if (isDebugMode)
            {
                Debug.DrawRay(forcePoint, engineForce, Color.green);
            }
        }
    }