private void CalculateWheelRotationFromSpeed(RaycastWheel w, Vector3 wsPos) { Quaternion wsWheelRot = transform.rotation * Quaternion.Euler(0f, w.yRad * Mathf.Rad2Deg, 0f); Vector3 wsWheelForward = wsWheelRot * Vector3.forward; Vector3 velocityQueryPos = w.isGrounded ? w.hit.point : wsPos; Vector3 pointVelocity = rb.GetPointVelocity(velocityQueryPos); float longitudinalSpeed = Vector3.Dot(pointVelocity, wsWheelForward); float wheelLengthInMeters = 2 * Mathf.PI * w.radius; // revolutions per second float rps = longitudinalSpeed / wheelLengthInMeters; float deltaRot = Mathf.PI * 2f * rps * Time.deltaTime; w.visualRotationRad += deltaRot; }
void Initialize() { // Cache Vehicle Input input = GetComponent <VehicleInput>(); // Cache a reference to our car's transform carTransform = transform; // cache the rigidbody for our car carRigidbody = GetComponent <Rigidbody>(); // cache the mass of our vehicle carMass = GetComponent <Rigidbody>().mass; // call to set up our wheels array setUpWheels(); // we set a COG here and lower the center of mass to a //negative value in Y axis to prevent car from flipping over carRigidbody.centerOfMass = new Vector3(0f, -1.0f, -0f); frontLeftRayCast = frontLeftWheel.GetComponentInParent <RaycastWheel>(); frontRightRayCast = frontRightWheel.GetComponentInParent <RaycastWheel>(); rearLeftRayCast = rearLeftWheel.GetComponentInParent <RaycastWheel>(); rearRightRayCast = rearRightWheel.GetComponentInParent <RaycastWheel>(); gravityDirection = -transform.up; lastSafePos = carTransform.position; rc = FindObjectOfType <RaceManager>(); if (GetComponent <VehicleInput>()) { //Sets ai spline to find/follow hotspotspline if (rc != null && rc.orderedSplines.Length != 0) { _aiSplineScript = rc.orderedSplines[activeSpline].GetComponent <SplinePlus>(); _branchesAtStart = new Dictionary <int, Branch>(_aiSplineScript.SPData.DictBranches); InvokeRepeating("findNearest", 0, 2); } } }
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); } } }