2026-07-15 15:16:00 +03:00

90 lines
3.2 KiB
C#

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<Renderer>();
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<WheelCollider>() : null;
}
private Transform FindChild(string childName)
{
Transform[] children = GetComponentsInChildren<Transform>(true);
for (int i = 0; i < children.Length; i++)
{
if (children[i].name == childName)
return children[i];
}
return null;
}
}
}