using UnityEngine; namespace RaceFields.Vehicles { [ExecuteAlways] public sealed class BuggyWheelSetup : MonoBehaviour { [SerializeField] private string frontLeftWheelName = "F_L"; [SerializeField] private string frontRightWheelName = "F_R"; [SerializeField] private string rearLeftWheelName = "B_L"; [SerializeField] private string rearRightWheelName = "B_R"; [SerializeField] private string frontLeftColliderName = "WheelCollider_FL"; [SerializeField] private string frontRightColliderName = "WheelCollider_FR"; [SerializeField] private string rearLeftColliderName = "WheelCollider_RL"; [SerializeField] private string rearRightColliderName = "WheelCollider_RR"; [SerializeField] private float radiusMultiplier = 0.5f; [SerializeField] private float minimumRadius = 0.12f; [SerializeField] private float suspensionDistance = 0.28f; [SerializeField] private float wheelMass = 20f; private void Awake() { AlignAllWheels(); } private void OnValidate() { AlignAllWheels(); } [ContextMenu("Align Wheel Colliders")] public void AlignAllWheels() { AlignWheel(frontLeftWheelName, frontLeftColliderName); AlignWheel(frontRightWheelName, frontRightColliderName); AlignWheel(rearLeftWheelName, rearLeftColliderName); AlignWheel(rearRightWheelName, rearRightColliderName); } private void AlignWheel(string visualName, string colliderName) { Transform visual = FindChild(visualName); WheelCollider wheelCollider = FindWheelCollider(colliderName); if (visual == null || wheelCollider == null) return; wheelCollider.transform.position = visual.position; wheelCollider.transform.rotation = transform.rotation; wheelCollider.transform.localScale = Vector3.one; wheelCollider.mass = wheelMass; wheelCollider.radius = Mathf.Max(minimumRadius, EstimateWheelRadius(visual) * radiusMultiplier); wheelCollider.suspensionDistance = suspensionDistance; wheelCollider.forceAppPointDistance = 0.05f; wheelCollider.wheelDampingRate = 0.35f; } private float EstimateWheelRadius(Transform visual) { Renderer renderer = visual.GetComponentInChildren(); if (renderer == null) return minimumRadius; Vector3 size = renderer.bounds.size; return Mathf.Max(size.y, size.z); } private WheelCollider FindWheelCollider(string colliderName) { Transform child = FindChild(colliderName); return child != null ? child.GetComponent() : null; } private Transform FindChild(string childName) { Transform[] children = GetComponentsInChildren(true); for (int i = 0; i < children.Length; i++) { if (children[i].name == childName) return children[i]; } return null; } } }