folder structure

This commit is contained in:
zmoixdev
2026-03-08 14:03:58 -06:00
parent 67d558ae8f
commit b446ce8940
25 changed files with 1918 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
using UnityEngine;
public class CarControl : MonoBehaviour
{
[Header("Car Properties")]
public float motorTorque = 2000f;
public float brakeTorque = 2000f;
public float maxSpeed = 20f;
public float steeringRange = 30f;
public float steeringRangeAtMaxSpeed = 10f;
public float centreOfGravityOffset = -1f;
private WheelControl[] wheels;
private Rigidbody rigidBody;
private CarInputActions carControls; // Reference to the new input system
void Awake()
{
carControls = new CarInputActions(); // Initialize Input Actions
}
void OnEnable()
{
carControls.Enable();
}
void OnDisable()
{
carControls.Disable();
}
// Start is called before the first frame update
void Start()
{
rigidBody = GetComponent<Rigidbody>();
// Adjust center of mass to improve stability and prevent rolling
Vector3 centerOfMass = rigidBody.centerOfMass;
centerOfMass.y += centreOfGravityOffset;
rigidBody.centerOfMass = centerOfMass;
// Get all wheel components attached to the car
wheels = GetComponentsInChildren<WheelControl>();
}
// FixedUpdate is called at a fixed time interval
void FixedUpdate()
{
// Read the Vector2 input from the new Input System
Vector2 inputVector = carControls.Car.Movement.ReadValue<Vector2>();
// Get player input for acceleration and steering
float vInput = inputVector.y; // Forward/backward input
float hInput = inputVector.x; // Steering input
// Calculate current speed along the car's forward axis
float forwardSpeed = Vector3.Dot(transform.forward, rigidBody.linearVelocity);
float speedFactor = Mathf.InverseLerp(0, maxSpeed, Mathf.Abs(forwardSpeed)); // Normalized speed factor
// Reduce motor torque and steering at high speeds for better handling
float currentMotorTorque = Mathf.Lerp(motorTorque, 0, speedFactor);
float currentSteerRange = Mathf.Lerp(steeringRange, steeringRangeAtMaxSpeed, speedFactor);
// Determine if the player is accelerating or trying to reverse
bool isAccelerating = Mathf.Sign(vInput) == Mathf.Sign(forwardSpeed);
foreach (var wheel in wheels)
{
// Apply steering to wheels that support steering
if (wheel.steerable)
{
wheel.WheelCollider.steerAngle = hInput * currentSteerRange;
}
if (isAccelerating)
{
// Apply torque to motorized wheels
if (wheel.motorized)
{
wheel.WheelCollider.motorTorque = vInput * currentMotorTorque;
}
// Release brakes when accelerating
wheel.WheelCollider.brakeTorque = 0f;
}
else
{
// Apply brakes when reversing direction
wheel.WheelCollider.motorTorque = 0f;
wheel.WheelCollider.brakeTorque = Mathf.Abs(vInput) * brakeTorque;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0665500128106154f8d28bace7476416

View File

@@ -0,0 +1,355 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was auto-generated by com.unity.inputsystem:InputActionCodeGenerator
// version 1.14.0
// from Assets/Car/CarInputActions.inputactions
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;
/// <summary>
/// Provides programmatic access to <see cref="InputActionAsset" />, <see cref="InputActionMap" />, <see cref="InputAction" /> and <see cref="InputControlScheme" /> instances defined in asset "Assets/Car/CarInputActions.inputactions".
/// </summary>
/// <remarks>
/// This class is source generated and any manual edits will be discarded if the associated asset is reimported or modified.
/// </remarks>
/// <example>
/// <code>
/// using namespace UnityEngine;
/// using UnityEngine.InputSystem;
///
/// // Example of using an InputActionMap named "Player" from a UnityEngine.MonoBehaviour implementing callback interface.
/// public class Example : MonoBehaviour, MyActions.IPlayerActions
/// {
/// private MyActions_Actions m_Actions; // Source code representation of asset.
/// private MyActions_Actions.PlayerActions m_Player; // Source code representation of action map.
///
/// void Awake()
/// {
/// m_Actions = new MyActions_Actions(); // Create asset object.
/// m_Player = m_Actions.Player; // Extract action map object.
/// m_Player.AddCallbacks(this); // Register callback interface IPlayerActions.
/// }
///
/// void OnDestroy()
/// {
/// m_Actions.Dispose(); // Destroy asset object.
/// }
///
/// void OnEnable()
/// {
/// m_Player.Enable(); // Enable all actions within map.
/// }
///
/// void OnDisable()
/// {
/// m_Player.Disable(); // Disable all actions within map.
/// }
///
/// #region Interface implementation of MyActions.IPlayerActions
///
/// // Invoked when "Move" action is either started, performed or canceled.
/// public void OnMove(InputAction.CallbackContext context)
/// {
/// Debug.Log($"OnMove: {context.ReadValue&lt;Vector2&gt;()}");
/// }
///
/// // Invoked when "Attack" action is either started, performed or canceled.
/// public void OnAttack(InputAction.CallbackContext context)
/// {
/// Debug.Log($"OnAttack: {context.ReadValue&lt;float&gt;()}");
/// }
///
/// #endregion
/// }
/// </code>
/// </example>
public partial class @CarInputActions: IInputActionCollection2, IDisposable
{
/// <summary>
/// Provides access to the underlying asset instance.
/// </summary>
public InputActionAsset asset { get; }
/// <summary>
/// Constructs a new instance.
/// </summary>
public @CarInputActions()
{
asset = InputActionAsset.FromJson(@"{
""name"": ""CarInputActions"",
""maps"": [
{
""name"": ""Car"",
""id"": ""c19f950c-3a7a-4a76-8523-1aa6fe6fcc3f"",
""actions"": [
{
""name"": ""Movement"",
""type"": ""Value"",
""id"": ""a3955e03-93cf-4eb3-aa7e-d47eb8f6589c"",
""expectedControlType"": ""Vector2"",
""processors"": """",
""interactions"": """",
""initialStateCheck"": true
}
],
""bindings"": [
{
""name"": ""2D Vector"",
""id"": ""4acb7ca1-35a7-4da8-8538-b419114f937a"",
""path"": ""2DVector"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Movement"",
""isComposite"": true,
""isPartOfComposite"": false
},
{
""name"": ""up"",
""id"": ""7cf87b87-53dc-449a-a3c4-f2e1f37f588a"",
""path"": ""<Keyboard>/w"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Movement"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""down"",
""id"": ""6f7380e9-0226-4816-92cb-3d668bd040f9"",
""path"": ""<Keyboard>/s"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Movement"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""left"",
""id"": ""5bf6f0e5-ee39-410a-9997-d4ef3362d1a2"",
""path"": ""<Keyboard>/a"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Movement"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""right"",
""id"": ""e9e1e925-1395-4159-a82a-b359f9767e77"",
""path"": ""<Keyboard>/d"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Movement"",
""isComposite"": false,
""isPartOfComposite"": true
}
]
}
],
""controlSchemes"": []
}");
// Car
m_Car = asset.FindActionMap("Car", throwIfNotFound: true);
m_Car_Movement = m_Car.FindAction("Movement", throwIfNotFound: true);
}
~@CarInputActions()
{
UnityEngine.Debug.Assert(!m_Car.enabled, "This will cause a leak and performance issues, CarInputActions.Car.Disable() has not been called.");
}
/// <summary>
/// Destroys this asset and all associated <see cref="InputAction"/> instances.
/// </summary>
public void Dispose()
{
UnityEngine.Object.Destroy(asset);
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.bindingMask" />
public InputBinding? bindingMask
{
get => asset.bindingMask;
set => asset.bindingMask = value;
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.devices" />
public ReadOnlyArray<InputDevice>? devices
{
get => asset.devices;
set => asset.devices = value;
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.controlSchemes" />
public ReadOnlyArray<InputControlScheme> controlSchemes => asset.controlSchemes;
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.Contains(InputAction)" />
public bool Contains(InputAction action)
{
return asset.Contains(action);
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.GetEnumerator()" />
public IEnumerator<InputAction> GetEnumerator()
{
return asset.GetEnumerator();
}
/// <inheritdoc cref="IEnumerable.GetEnumerator()" />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.Enable()" />
public void Enable()
{
asset.Enable();
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.Disable()" />
public void Disable()
{
asset.Disable();
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.bindings" />
public IEnumerable<InputBinding> bindings => asset.bindings;
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.FindAction(string, bool)" />
public InputAction FindAction(string actionNameOrId, bool throwIfNotFound = false)
{
return asset.FindAction(actionNameOrId, throwIfNotFound);
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.FindBinding(InputBinding, out InputAction)" />
public int FindBinding(InputBinding bindingMask, out InputAction action)
{
return asset.FindBinding(bindingMask, out action);
}
// Car
private readonly InputActionMap m_Car;
private List<ICarActions> m_CarActionsCallbackInterfaces = new List<ICarActions>();
private readonly InputAction m_Car_Movement;
/// <summary>
/// Provides access to input actions defined in input action map "Car".
/// </summary>
public struct CarActions
{
private @CarInputActions m_Wrapper;
/// <summary>
/// Construct a new instance of the input action map wrapper class.
/// </summary>
public CarActions(@CarInputActions wrapper) { m_Wrapper = wrapper; }
/// <summary>
/// Provides access to the underlying input action "Car/Movement".
/// </summary>
public InputAction @Movement => m_Wrapper.m_Car_Movement;
/// <summary>
/// Provides access to the underlying input action map instance.
/// </summary>
public InputActionMap Get() { return m_Wrapper.m_Car; }
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionMap.Enable()" />
public void Enable() { Get().Enable(); }
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionMap.Disable()" />
public void Disable() { Get().Disable(); }
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionMap.enabled" />
public bool enabled => Get().enabled;
/// <summary>
/// Implicitly converts an <see ref="CarActions" /> to an <see ref="InputActionMap" /> instance.
/// </summary>
public static implicit operator InputActionMap(CarActions set) { return set.Get(); }
/// <summary>
/// Adds <see cref="InputAction.started"/>, <see cref="InputAction.performed"/> and <see cref="InputAction.canceled"/> callbacks provided via <param cref="instance" /> on all input actions contained in this map.
/// </summary>
/// <param name="instance">Callback instance.</param>
/// <remarks>
/// If <paramref name="instance" /> is <c>null</c> or <paramref name="instance"/> have already been added this method does nothing.
/// </remarks>
/// <seealso cref="CarActions" />
public void AddCallbacks(ICarActions instance)
{
if (instance == null || m_Wrapper.m_CarActionsCallbackInterfaces.Contains(instance)) return;
m_Wrapper.m_CarActionsCallbackInterfaces.Add(instance);
@Movement.started += instance.OnMovement;
@Movement.performed += instance.OnMovement;
@Movement.canceled += instance.OnMovement;
}
/// <summary>
/// Removes <see cref="InputAction.started"/>, <see cref="InputAction.performed"/> and <see cref="InputAction.canceled"/> callbacks provided via <param cref="instance" /> on all input actions contained in this map.
/// </summary>
/// <remarks>
/// Calling this method when <paramref name="instance" /> have not previously been registered has no side-effects.
/// </remarks>
/// <seealso cref="CarActions" />
private void UnregisterCallbacks(ICarActions instance)
{
@Movement.started -= instance.OnMovement;
@Movement.performed -= instance.OnMovement;
@Movement.canceled -= instance.OnMovement;
}
/// <summary>
/// Unregisters <param cref="instance" /> and unregisters all input action callbacks via <see cref="CarActions.UnregisterCallbacks(ICarActions)" />.
/// </summary>
/// <seealso cref="CarActions.UnregisterCallbacks(ICarActions)" />
public void RemoveCallbacks(ICarActions instance)
{
if (m_Wrapper.m_CarActionsCallbackInterfaces.Remove(instance))
UnregisterCallbacks(instance);
}
/// <summary>
/// Replaces all existing callback instances and previously registered input action callbacks associated with them with callbacks provided via <param cref="instance" />.
/// </summary>
/// <remarks>
/// If <paramref name="instance" /> is <c>null</c>, calling this method will only unregister all existing callbacks but not register any new callbacks.
/// </remarks>
/// <seealso cref="CarActions.AddCallbacks(ICarActions)" />
/// <seealso cref="CarActions.RemoveCallbacks(ICarActions)" />
/// <seealso cref="CarActions.UnregisterCallbacks(ICarActions)" />
public void SetCallbacks(ICarActions instance)
{
foreach (var item in m_Wrapper.m_CarActionsCallbackInterfaces)
UnregisterCallbacks(item);
m_Wrapper.m_CarActionsCallbackInterfaces.Clear();
AddCallbacks(instance);
}
}
/// <summary>
/// Provides a new <see cref="CarActions" /> instance referencing this action map.
/// </summary>
public CarActions @Car => new CarActions(this);
/// <summary>
/// Interface to implement callback methods for all input action callbacks associated with input actions defined by "Car" which allows adding and removing callbacks.
/// </summary>
/// <seealso cref="CarActions.AddCallbacks(ICarActions)" />
/// <seealso cref="CarActions.RemoveCallbacks(ICarActions)" />
public interface ICarActions
{
/// <summary>
/// Method invoked when associated input action "Movement" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnMovement(InputAction.CallbackContext context);
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ce4bc8ceb06ac494c929dc2ee1148479

View File

@@ -0,0 +1,78 @@
{
"name": "CarInputActions",
"maps": [
{
"name": "Car",
"id": "c19f950c-3a7a-4a76-8523-1aa6fe6fcc3f",
"actions": [
{
"name": "Movement",
"type": "Value",
"id": "a3955e03-93cf-4eb3-aa7e-d47eb8f6589c",
"expectedControlType": "Vector2",
"processors": "",
"interactions": "",
"initialStateCheck": true
}
],
"bindings": [
{
"name": "2D Vector",
"id": "4acb7ca1-35a7-4da8-8538-b419114f937a",
"path": "2DVector",
"interactions": "",
"processors": "",
"groups": "",
"action": "Movement",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "up",
"id": "7cf87b87-53dc-449a-a3c4-f2e1f37f588a",
"path": "<Keyboard>/w",
"interactions": "",
"processors": "",
"groups": "",
"action": "Movement",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "down",
"id": "6f7380e9-0226-4816-92cb-3d668bd040f9",
"path": "<Keyboard>/s",
"interactions": "",
"processors": "",
"groups": "",
"action": "Movement",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "left",
"id": "5bf6f0e5-ee39-410a-9997-d4ef3362d1a2",
"path": "<Keyboard>/a",
"interactions": "",
"processors": "",
"groups": "",
"action": "Movement",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "right",
"id": "e9e1e925-1395-4159-a82a-b359f9767e77",
"path": "<Keyboard>/d",
"interactions": "",
"processors": "",
"groups": "",
"action": "Movement",
"isComposite": false,
"isPartOfComposite": true
}
]
}
],
"controlSchemes": []
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 686e90d9bee6e9d4cbff2ff59322f557
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
generateWrapperCode: 1
wrapperCodePath:
wrapperClassName:
wrapperCodeNamespace:

View File

@@ -0,0 +1,33 @@
using UnityEngine;
public class WheelControl : MonoBehaviour
{
public Transform wheelModel;
[HideInInspector] public WheelCollider WheelCollider;
// Create properties for the CarControl script
// (You should enable/disable these via the
// Editor Inspector window)
public bool steerable;
public bool motorized;
Vector3 position;
Quaternion rotation;
// Start is called before the first frame update
private void Start()
{
WheelCollider = GetComponent<WheelCollider>();
}
// Update is called once per frame
void Update()
{
// Get the Wheel collider's world pose values and
// use them to set the wheel model's position and rotation
WheelCollider.GetWorldPose(out position, out rotation);
wheelModel.transform.position = position;
wheelModel.transform.rotation = rotation;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 484c6bad1888141449bbccb931f4b3cf