completed prototyping. Integrated abstraction layer from previous project. Refactored gameplay code. Found an issue with drifting and added a quick fix for the same. Added camera system for chasing player movement.
176 lines
5.0 KiB
C#
176 lines
5.0 KiB
C#
|
|
using System;
|
|
using UnityEngine;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEngine.EventSystems;
|
|
using Newtonsoft.Json;
|
|
|
|
public class CarController : MonoBehaviour
|
|
{
|
|
[SerializeField] private bool isDebugTest = false;
|
|
|
|
[SerializeField] private Transform[] tireTransforms;
|
|
[SerializeField] private Transform[] frontTireTransforms;
|
|
[SerializeField] private Transform[] tireMeshes;
|
|
|
|
[SerializeField] private Rigidbody carRigidbody;
|
|
|
|
[SerializeField] private CarSpecs carSpecs;
|
|
[SerializeField] private Vector3 customCenterOfMass;
|
|
[SerializeField] private AnimationCurve steerLeftAnimCurve;
|
|
[SerializeField] private AnimationCurve steerRightAnimCurve;
|
|
[SerializeField] private AnimationCurve accelAnimCurve;
|
|
|
|
[Category("Input Attributes")]
|
|
private float steeringInput;
|
|
private float accelInput;
|
|
|
|
[Category("Global-Script-Attributes")]
|
|
private int tiresCount = 0;
|
|
private float remTime = 0f;
|
|
private float tiresInGround = 0f;
|
|
|
|
[Category("Script-Object-Refs.")]
|
|
private CarSystem carSystem;
|
|
private TimerSystem timerSystem;
|
|
|
|
[Category("Tags.")]
|
|
private const string checkpointTag = "Checkpoint";
|
|
private const string finishCheckpointTag = "Finish";
|
|
|
|
private RaycastHit hitInfo;
|
|
private bool isGameOver = false;
|
|
private Coroutine GroundCheckCoroutine = null;
|
|
|
|
[Category("Action Delegates")]
|
|
public static Action<float> OnCheckpointReached;
|
|
public Action<float, Transform, float, Transform> OnApplyForce;
|
|
public Action<float> OnCarRotate;
|
|
public Action<string> OnGameOver;
|
|
|
|
public void Init()
|
|
{
|
|
isGameOver = false;
|
|
tiresCount = tireTransforms.Length;
|
|
|
|
timerSystem = new TimerSystem();
|
|
remTime = timerSystem.Timer;
|
|
carSystem = new CarSystem(this, carRigidbody, carSpecs, frontTireTransforms, steerLeftAnimCurve: steerLeftAnimCurve, steerRightAnimCurve: steerRightAnimCurve, accelAnimCurve: accelAnimCurve);
|
|
}
|
|
|
|
private void EnableGameOverState()
|
|
{
|
|
return;
|
|
|
|
OnGameOver?.Invoke("");
|
|
isGameOver = true;
|
|
}
|
|
|
|
/* Editor movement inputs */
|
|
private void ProcessInputs()
|
|
{
|
|
accelInput = Input.GetAxis("Vertical");
|
|
steeringInput = Input.GetAxis("Horizontal");
|
|
}
|
|
|
|
private void CheckGameOverStates()
|
|
{
|
|
if (isGameOver)
|
|
return;
|
|
|
|
/* Check for Time run out */
|
|
if (remTime < 1)
|
|
{
|
|
EnableGameOverState();
|
|
return;
|
|
}
|
|
|
|
/* Check for Tires out of bounds (ground/platform) */
|
|
if (tiresInGround < 3 && GroundCheckCoroutine == null)
|
|
GroundCheckCoroutine = StartCoroutine(CheckTiresInGround());
|
|
}
|
|
|
|
/* Check if car/rigidbody is out of bounds/ground/platform */
|
|
private IEnumerator CheckTiresInGround()
|
|
{
|
|
yield return new WaitForSeconds(3f);
|
|
if (tiresInGround >= 3)
|
|
{
|
|
StopCoroutine();
|
|
}
|
|
|
|
/* Check for dealing with edge cases where
|
|
car would be moving through the edge of the platforms */
|
|
yield return new WaitForSeconds(2f);
|
|
|
|
if (tiresInGround < 3 && !isGameOver)
|
|
{
|
|
EnableGameOverState();
|
|
StopCoroutine();
|
|
}
|
|
}
|
|
|
|
private void StopCoroutine()
|
|
{
|
|
if (GroundCheckCoroutine != null)
|
|
{
|
|
StopCoroutine(GroundCheckCoroutine);
|
|
GroundCheckCoroutine = null;
|
|
}
|
|
}
|
|
|
|
/* Functions mapped to event triggers of associated buttons */
|
|
public void MoveInput(float input) => accelInput = input;
|
|
public void SteerInput(float input) => steeringInput = input;
|
|
|
|
public void RestartLevel()
|
|
{
|
|
StopCoroutine();
|
|
SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().buildIndex);
|
|
}
|
|
|
|
#region Monobehaviour Callbacks
|
|
|
|
private void Awake()
|
|
{
|
|
Debug.Log($" Default Center of mass: {carRigidbody.centerOfMass} ");
|
|
carRigidbody.centerOfMass = customCenterOfMass;
|
|
}
|
|
|
|
/* Apply force to Car's rigidbody for Suspension(Y-Axis),
|
|
steering(X-Axis), and acceleration(Z-Axis) for each tire. */
|
|
private void FixedUpdate()
|
|
{
|
|
tiresInGround = 0;
|
|
for (int tireIndex = 0; tireIndex < tiresCount; tireIndex++)
|
|
{
|
|
if (Physics.Raycast(tireTransforms[tireIndex].position, -tireTransforms[tireIndex].up, out hitInfo, carSpecs.hitDist))
|
|
{
|
|
tiresInGround++;
|
|
Debug.Log($"## Input :: accelInput: {accelInput}");
|
|
OnApplyForce?.Invoke(hitInfo.distance, tireTransforms[tireIndex], accelInput, tireMeshes[tireIndex]);
|
|
}
|
|
}
|
|
|
|
CheckGameOverStates();
|
|
}
|
|
|
|
// Updates the timer for UI and Rotation of the wheels (transforms) according to input
|
|
private void Update()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.R))
|
|
RestartLevel();
|
|
|
|
OnCarRotate?.Invoke(steeringInput);
|
|
|
|
#if UNITY_EDITOR
|
|
if (isDebugTest)
|
|
ProcessInputs();
|
|
#endif
|
|
}
|
|
|
|
#endregion
|
|
}
|