112 lines
4.1 KiB
C#
112 lines
4.1 KiB
C#
using UnityEngine;
|
|
|
|
public enum DriveType { FWD, RWD, AWD } // Передний, Задний, Полный привод
|
|
|
|
[RequireComponent(typeof(Rigidbody))]
|
|
public class CarController : MonoBehaviour
|
|
{
|
|
[Header("Drive Settings")]
|
|
public DriveType driveType = DriveType.AWD;
|
|
[SerializeField] private float motorForce = 1500f;
|
|
[SerializeField] private float brakeForce = 3000f;
|
|
[SerializeField] private float maxSteerAngle = 30f;
|
|
|
|
[Header("Arcade Feel")]
|
|
[SerializeField] private Transform centerOfMass; // Заниженный центр тяжести
|
|
|
|
[Header("Wheel Colliders")]
|
|
[SerializeField] private WheelCollider frontLeftCollider;
|
|
[SerializeField] private WheelCollider frontRightCollider;
|
|
[SerializeField] private WheelCollider rearLeftCollider;
|
|
[SerializeField] private WheelCollider rearRightCollider;
|
|
|
|
[Header("Wheel Meshes (для визуализации)")]
|
|
[SerializeField] private Transform frontLeftMesh;
|
|
[SerializeField] private Transform frontRightMesh;
|
|
[SerializeField] private Transform rearLeftMesh;
|
|
[SerializeField] private Transform rearRightMesh;
|
|
|
|
private Rigidbody rb;
|
|
private float currentMotorForce;
|
|
private float currentBrakeForce;
|
|
private float currentSteerAngle;
|
|
|
|
private void Start()
|
|
{
|
|
rb = GetComponent<Rigidbody>();
|
|
if (centerOfMass != null)
|
|
{
|
|
rb.centerOfMass = centerOfMass.localPosition; // Смещаем центр масс вниз для аркадности
|
|
}
|
|
}
|
|
|
|
// Метод вызывается из другого скрипта (ввода)
|
|
public void ProcessInput(float verticalInput, float horizontalInput, bool isBraking)
|
|
{
|
|
currentSteerAngle = maxSteerAngle * horizontalInput;
|
|
currentMotorForce = verticalInput * motorForce;
|
|
currentBrakeForce = isBraking ? brakeForce : 0f;
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
HandleMotor();
|
|
HandleSteering();
|
|
ApplyBraking();
|
|
UpdateWheelPoses();
|
|
}
|
|
|
|
private void HandleMotor()
|
|
{
|
|
// Распределяем крутящий момент в зависимости от типа привода
|
|
switch (driveType)
|
|
{
|
|
case DriveType.FWD: // Передний (недостаточная поворачиваемость, стабилен)
|
|
frontLeftCollider.motorTorque = currentMotorForce;
|
|
frontRightCollider.motorTorque = currentMotorForce;
|
|
break;
|
|
case DriveType.RWD: // Задний (склонен к заносам / дрифту)
|
|
rearLeftCollider.motorTorque = currentMotorForce;
|
|
rearRightCollider.motorTorque = currentMotorForce;
|
|
break;
|
|
case DriveType.AWD: // Полный (отличный старт и сцепление)
|
|
float halfForce = currentMotorForce / 2f;
|
|
frontLeftCollider.motorTorque = halfForce;
|
|
frontRightCollider.motorTorque = halfForce;
|
|
rearLeftCollider.motorTorque = halfForce;
|
|
rearRightCollider.motorTorque = halfForce;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void HandleSteering()
|
|
{
|
|
frontLeftCollider.steerAngle = currentSteerAngle;
|
|
frontRightCollider.steerAngle = currentSteerAngle;
|
|
}
|
|
|
|
private void ApplyBraking()
|
|
{
|
|
frontLeftCollider.brakeTorque = currentBrakeForce;
|
|
frontRightCollider.brakeTorque = currentBrakeForce;
|
|
rearLeftCollider.brakeTorque = currentBrakeForce;
|
|
rearRightCollider.brakeTorque = currentBrakeForce;
|
|
}
|
|
|
|
private void UpdateWheelPoses()
|
|
{
|
|
UpdateWheelPose(frontLeftCollider, frontLeftMesh);
|
|
UpdateWheelPose(frontRightCollider, frontRightMesh);
|
|
UpdateWheelPose(rearLeftCollider, rearLeftMesh);
|
|
UpdateWheelPose(rearRightCollider, rearRightMesh);
|
|
}
|
|
|
|
private void UpdateWheelPose(WheelCollider collider, Transform mesh)
|
|
{
|
|
if (mesh == null) return;
|
|
|
|
collider.GetWorldPose(out Vector3 pos, out Quaternion rot);
|
|
mesh.position = pos;
|
|
mesh.rotation = rot;
|
|
}
|
|
} |