Download examples/open_world_city/Assets/Scripts/VehicleController.cs from ryzerrr/unity-game-agent: direct link, hf CLI and curl.
- Browser
- Download file 4.73 kB
-
https://huggingface.co/ryzerrr/unity-game-agent/resolve/main/examples/open_world_city/Assets/Scripts/VehicleController.cs
- Command line
-
hf download hf://ryzerrr/unity-game-agent/examples/open_world_city/Assets/Scripts/VehicleController.cs
-
curl -L -o VehicleController.cs https://huggingface.co/ryzerrr/unity-game-agent/resolve/main/examples/open_world_city/Assets/Scripts/VehicleController.cs
4.73 kB
| using UnityEngine; | |
| namespace UnityAgent | |
| { | |
| /// <summary> | |
| /// Arcade car physics: motor torque, steering, braking and a simple | |
| /// four-wheel raycast suspension. Place this on a root GameObject with | |
| /// a Rigidbody and four wheel transforms. | |
| /// </summary> | |
| [] | |
| public class VehicleController : MonoBehaviour | |
| { | |
| [] | |
| public class Wheel | |
| { | |
| public Transform transform; | |
| public bool isSteering; | |
| public bool isPowered; | |
| public bool isBraking; | |
| [] public bool isGrounded; | |
| [] public float suspensionOffset; | |
| } | |
| [] | |
| public Wheel[] wheels = new Wheel[4]; | |
| [] | |
| public float motorTorque = 1500f; | |
| public float brakeTorque = 3000f; | |
| public float maxSteerAngle = 30f; | |
| public float maxSpeedKph = 180f; | |
| [] | |
| public float suspensionRestLength = 0.5f; | |
| public float suspensionSpring = 35000f; | |
| public float suspensionDamper = 4500f; | |
| public float wheelRadius = 0.35f; | |
| public LayerMask wheelMask = ~0; | |
| [] | |
| public float downforce = 100f; | |
| public float centerOfMassOffset = -0.5f; | |
| private Rigidbody _rb; | |
| private float _throttle; | |
| private float _steer; | |
| private float _brake; | |
| private void Awake() | |
| { | |
| _rb = GetComponent<Rigidbody>(); | |
| _rb.centerOfMass += Vector3.up * centerOfMassOffset; | |
| _rb.interpolation = RigidbodyInterpolation.Interpolate; | |
| } | |
| private void Update() | |
| { | |
| _throttle = Input.GetAxis("Vertical"); | |
| _steer = Input.GetAxis("Horizontal"); | |
| _brake = Input.GetKey(KeyCode.Space) ? 1f : 0f; | |
| } | |
| private void FixedUpdate() | |
| { | |
| UpdateWheels(); | |
| ApplySuspension(); | |
| ApplyDrive(); | |
| ApplyDownforce(); | |
| } | |
| private void UpdateWheels() | |
| { | |
| foreach (var w in wheels) | |
| { | |
| if (w.transform == null) continue; | |
| Vector3 origin = w.transform.position; | |
| bool hit = Physics.Raycast( | |
| origin, -transform.up, out RaycastHit r, | |
| suspensionRestLength + wheelRadius, wheelMask, | |
| QueryTriggerInteraction.Ignore); | |
| w.isGrounded = hit; | |
| w.suspensionOffset = hit ? r.distance - wheelRadius : suspensionRestLength; | |
| } | |
| } | |
| private void ApplySuspension() | |
| { | |
| foreach (var w in wheels) | |
| { | |
| if (!w.isGrounded) continue; | |
| float force = (suspensionRestLength - w.suspensionOffset) * suspensionSpring; | |
| Vector3 velocity = _rb.GetPointVelocity(w.transform.position); | |
| float upwardVel = Vector3.Dot(transform.up, velocity); | |
| force -= upwardVel * suspensionDamper; | |
| _rb.AddForceAtPosition(transform.up * Mathf.Max(0f, force), w.transform.position); | |
| } | |
| } | |
| private void ApplyDrive() | |
| { | |
| float kph = _rb.velocity.magnitude * 3.6f; | |
| float speedFactor = Mathf.Clamp01(1f - kph / maxSpeedKph); | |
| foreach (var w in wheels) | |
| { | |
| if (!w.isGrounded) continue; | |
| if (w.isPowered) | |
| { | |
| Vector3 force = transform.forward * (_throttle * motorTorque * speedFactor); | |
| _rb.AddForceAtPosition(force, w.transform.position, ForceMode.Force); | |
| } | |
| if (w.isBraking && _brake > 0.01f) | |
| { | |
| Vector3 brakeForce = -transform.forward * (_brake * brakeTorque); | |
| _rb.AddForceAtPosition(brakeForce, w.transform.position, ForceMode.Force); | |
| } | |
| if (w.isSteering) | |
| { | |
| // Rotate the visual wheel and apply a small yaw torque. | |
| w.transform.localRotation = Quaternion.Euler(0f, _steer * maxSteerAngle, 0f); | |
| } | |
| } | |
| // Steering yaw torque. | |
| if (Mathf.Abs(_steer) > 0.01f) | |
| { | |
| float turn = _steer * maxSteerAngle * 0.02f; | |
| _rb.AddTorque(transform.up * turn * (_rb.velocity.magnitude + 1f), ForceMode.Force); | |
| } | |
| } | |
| private void ApplyDownforce() | |
| { | |
| _rb.AddForce(-transform.up * downforce * _rb.velocity.magnitude); | |
| } | |
| } | |
| } | |