You are on page 1of 11

using UnityEngine;

using UnityEngine.UI;
using System;
using System.Collections.Generic;
using System.Collections;
using UnityEngine.SceneManagement;

public class CarController : MonoBehaviour


{
public static bool CarAudio = true;

public static bool isMovingForward = false;


public static bool isGearDrive = true;
public static bool isCarNotMoving = false;
private float levelTimeStart = 0;

//Control Modes to Test on PC and Mobile Quickly


public enum ControlMode
{
Keyboard,
Buttons,
Tilt
};
public enum Axel
{
Front,
Rear
}

public enum SpeedUnit


{
KilometersPerHour,
MilesPerHour
}

[Serializable]
public struct Wheel
{
public GameObject wheelModel;
public WheelCollider wheelCollider;
public Axel axel;
}

public ControlMode control;


public SpeedUnit speedUnit;
private int speedLimit = 80;

public float maxAcceleration = 45.0f;


public float brakeAcceleration = 80.0f;

public float turnSensitivity = 1.0f;


public float maxSteerAngle = 30.0f;

public Vector3 _centerOfMass;

public List<Wheel> wheels;


float moveInput;
float steerInput;

private Rigidbody carRb;

//Camera
private CameraFollow cameraFollow;

public GameObject BackLights;


public GameObject HeadLights;
public GameObject SteerButtons;

[HideInInspector]
public float isAccelerating = 0;
[HideInInspector]
public float Gear = 1;
[HideInInspector]
public bool isChangingGear = true;
[HideInInspector]
public int isBraking = 0;

//Indicators
public GameObject LeftIndicator;
public GameObject RightIndicator;

public Toggle leftIndicatorToggle;


public Toggle rightIndicatorToggle;

private bool leftIndicatorActive = false;


private bool rightIndicatorActive = false;

private WaitForSeconds blinkDuration = new WaitForSeconds(0.5f);


private WaitForSeconds blinkInterval = new WaitForSeconds(0.25f);

private Coroutine blinkCoroutine;

private ScoreManager scoreManager;


public GameObject Canvas;

int typecontrol;
//Speed
private Vector3 lastPosition;
private float speed;
public Text CarSpeed;
public Text GearText;

//Sounds of Car
public AudioClip Idle_Sound;
public AudioClip Accelerating_Sound;

// Additional variables for pitch control


private float minPitch = 1f; // Minimum pitch value
private float maxPitch = 2f; // Maximum pitch value
private float pitchChangeSpeed = 0.1f; // Speed of pitch change
private AudioSource audiosource;

public bool frontlightsON = false;

void Start()
{

audiosource = gameObject.AddComponent<AudioSource>();
PlayIdleSound();

string currentSceneName = SceneManager.GetActiveScene().name;


GetCarSpec();
if (currentSceneName == "MainMenu" || currentSceneName == "Garage")
{
audiosource.volume=0;
Canvas.SetActive(false);
}
else
{
Canvas.SetActive(true);
audiosource.volume = 1;
cameraFollow = FindObjectOfType<CameraFollow>();
scoreManager = FindObjectOfType<ScoreManager>();
levelTimeStart = Time.time;
}
carRb = GetComponent<Rigidbody>();
carRb.centerOfMass = _centerOfMass;

leftIndicatorToggle.onValueChanged.AddListener(OnLeftIndicatorToggleChange);

rightIndicatorToggle.onValueChanged.AddListener(OnRightIndicatorToggleChange);

//---------------------------------------------------------

}
private void GetCarSpec()
{
string carName = PlayerPrefs.GetString(PlayerPrefsKeys.CAR_NAME, "Honda");
maxAcceleration = PlayerPrefs.GetInt(carName +
PlayerPrefsKeys.CAR_ACCELERATION, 20);
brakeAcceleration = PlayerPrefs.GetInt(carName +
PlayerPrefsKeys.CAR_BRAKING, 40);
turnSensitivity = PlayerPrefs.GetFloat(carName +
PlayerPrefsKeys.CAR_HANDLING, 1);
maxSteerAngle = PlayerPrefs.GetInt(carName +
PlayerPrefsKeys.CAR_STEERANGLE, 30);
speedLimit = PlayerPrefs.GetInt(carName + PlayerPrefsKeys.CAR_SPPED, 80);

}
void Update()
{
if(PauseMenu.isGamePaused || CompletionMenu.isCompleted)
{
Time.timeScale = 0;
return;
}
isCarNotMoving = IsCarStopped();
GetControlType();
AnimateWheels();
isMoving();
Steer();
Brake();
if(!CarAudio)
{
audiosource.Pause();
}
else
{
audiosource.UnPause();

}
UpdateSounds();
}
private void FixedUpdate()
{
if (PauseMenu.isGamePaused || CompletionMenu.isCompleted)
{
return;
}
GetDistanceUnit();
}
private void GetControlType()
{
typecontrol = PlayerPrefs.GetInt(PlayerPrefsKeys.CONTROL_MODE_KEY,0);
if (typecontrol == 0)
{
control = ControlMode.Buttons;
}
else if (typecontrol == 1)
{
control = ControlMode.Tilt;
}
GetInputs();
}

private void GetDistanceUnit()


{
typecontrol = PlayerPrefs.GetInt(PlayerPrefsKeys.GAME_DISTANCE_UNIT, 0);
if (typecontrol == 0)
{
speedUnit = SpeedUnit.KilometersPerHour;
}
else if (typecontrol == 1)
{
speedUnit = SpeedUnit.MilesPerHour;
}
CalculateSpeed();
}
public void MoveInput(float input)
{
moveInput = input;
}

public void SteerInput(float input)


{
steerInput = input;
}

void GetInputs()
{
if (control == ControlMode.Keyboard)
{
moveInput = Input.GetAxis("Vertical");
steerInput = Input.GetAxis("Horizontal");
}
else if (control == ControlMode.Tilt)
{
SteerButtons.SetActive(false);
// Use tilt input for steering
steerInput = Input.acceleration.x * turnSensitivity;
}
else if (control == ControlMode.Buttons)
{
SteerButtons.SetActive(true);
}
}

void Move()
{
//Removing Decelaration
foreach (var wheel in wheels)
{
wheel.wheelCollider.brakeTorque = 0;
}

float currentSpeed = carRb.velocity.magnitude * 3.6f; // Convert m/s to


km/h

// Check and limit the speed


if (currentSpeed < speedLimit)
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.motorTorque = Gear * 180 * maxAcceleration *
Time.deltaTime;
}
}
else
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.motorTorque = 0;
}
}
}

void Steer()
{
foreach (var wheel in wheels)
{
if (wheel.axel == Axel.Front)
{
if (control == ControlMode.Tilt)
{
// Adjust steering based on tilt input
var tiltSteer = Input.acceleration.x * turnSensitivity *
maxSteerAngle;
wheel.wheelCollider.steerAngle =
Mathf.Lerp(wheel.wheelCollider.steerAngle, tiltSteer, 0.6f);
}
else
{
// Use regular input for steering
var keyboardSteer = steerInput * turnSensitivity *
maxSteerAngle;
wheel.wheelCollider.steerAngle =
Mathf.Lerp(wheel.wheelCollider.steerAngle, keyboardSteer, 0.6f);
}
}
}
}

public void Brake()


{
//Deceleration
if (isBraking == 1)
{
foreach (var wheel in wheels)
{
wheel.wheelCollider.brakeTorque = 200 * brakeAcceleration *
Time.deltaTime;
}
BackLights.SetActive(true);

}
else
{
BackLights.SetActive(false);
foreach (var wheel in wheels)
{
wheel.wheelCollider.brakeTorque = 0;
}
}
}

void AnimateWheels()
{
foreach (var wheel in wheels)
{
Quaternion rot;
Vector3 pos;
wheel.wheelCollider.GetWorldPose(out pos, out rot);
wheel.wheelModel.transform.position = pos;
wheel.wheelModel.transform.rotation = rot;
}
}

public void setFrontLights()


{
if (!frontlightsON)
{
HeadLights.SetActive(true);
frontlightsON = true;
}
else if (frontlightsON)
{
HeadLights.SetActive(false);
frontlightsON = false;
}
}

public void isMoving()


{
BackLights.SetActive(false);
if (isAccelerating == 1)
{

//Stopping Deceleration
foreach (var wheel in wheels)
{
wheel.wheelCollider.attachedRigidbody.drag = 0f;
}
Move();
isMovingForward = true;
}
else if (isAccelerating != 1)
{

//Decelarating
foreach (var wheel in wheels)
{
wheel.wheelCollider.motorTorque = 0;
wheel.wheelCollider.attachedRigidbody.drag = 0.1f;
}
BackLights.SetActive(true);
isMovingForward = false;
}
}
public void ChangeGear()
{

if (Gear == 1)
{

isGearDrive = false;
Gear = -1;
GearText.text = "Gear\nR";

}
else if (Gear == -1)
{
isGearDrive = true;
Gear = 1;
GearText.text = "Gear\nD";
}
}
public void Accelerating(int input)
{
isAccelerating = input;
}
public void ToggleBraking(int brake)
{
isBraking = brake;
}

void OnLeftIndicatorToggleChange(bool value)


{
leftIndicatorActive = value;

if (value)
{
// If left indicator is turned on, turn off the right indicator
rightIndicatorToggle.isOn = false;
StartBlinking(LeftIndicator);
}
else
{
StopBlinking();
LeftIndicator.SetActive(false); // Turn off the lights immediately when
indicator is turned off
}
}

void OnRightIndicatorToggleChange(bool value)


{
rightIndicatorActive = value;

if (value)
{
// If right indicator is turned on, turn off the left indicator
leftIndicatorToggle.isOn = false;
StartBlinking(RightIndicator);
}
else
{
StopBlinking();
RightIndicator.SetActive(false); // Turn off the lights immediately
when indicator is turned off
}
}

void StartBlinking(GameObject indicatorLights)


{
StopBlinking(); // Stop any ongoing blinking coroutine

// Start a new blinking coroutine


blinkCoroutine = StartCoroutine(BlinkIndicator(indicatorLights));
}

void StopBlinking()
{
if (blinkCoroutine != null)
{
// Stop the ongoing blinking coroutine
StopCoroutine(blinkCoroutine);
blinkCoroutine = null;
}
}

IEnumerator BlinkIndicator(GameObject indicatorLights)


{
while (true)
{
indicatorLights.SetActive(true);
yield return blinkDuration;
indicatorLights.SetActive(false);
yield return blinkInterval;
}
}

void SetIndicatorLights()
{
LeftIndicator.SetActive(leftIndicatorActive);
RightIndicator.SetActive(rightIndicatorActive);
}

public bool IsCarStopped() //To check whether the car is stopped on not
{
//Debug.Log(carRb.velocity.magnitude);
return carRb.velocity.magnitude < 0.1f;
}

public void setCarSpeed(float speed) //Set the car speed for car Discovery time
{
maxAcceleration = speed;
}

public void ChangeCam()


{
cameraFollow.TogggleCam();
}

void CalculateSpeed()
{
Vector3 currentPosition = transform.position;
float distanceTraveled = Vector3.Distance(currentPosition, lastPosition);
speed = distanceTraveled / Time.deltaTime;

// Update the last position for the next frame


lastPosition = currentPosition;

// Convert speed based on the chosen unit


if (speedUnit == SpeedUnit.KilometersPerHour)
{
speed = speed * 3.6f;
}
else if (speedUnit == SpeedUnit.MilesPerHour)
{
speed = speed * 2.237f;
}

speed = Mathf.Min(speed, speedLimit);


//Converting to Int
int intspeed = (int)speed;
// Display the speed in the UI Text component

if (speedUnit == SpeedUnit.KilometersPerHour)
{
CarSpeed.text = intspeed + "\nkm/h";
}
else if (speedUnit == SpeedUnit.MilesPerHour)
{
CarSpeed.text = intspeed + "\nmp/h";
}

}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Boundary"))
{
if (scoreManager != null)
{
scoreManager.HandleCollisionWithBoundary();
}
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Complete"))
{
CompletionMenu.isCompleted = true;
scoreManager.LevelTime(levelTimeStart);
}
}

//Sounds
void UpdateSounds()
{
// Check if the car is accelerating and play the accelerating sound
if (isAccelerating == 1)
{
if (!audiosource.isPlaying || audiosource.clip != Accelerating_Sound)
{
PlayAcceleratingSound();
}

// Gradually increase the pitch while accelerating


if (audiosource.pitch < maxPitch)
{
audiosource.pitch += pitchChangeSpeed * Time.deltaTime;
}
}
else
{
// If not accelerating, play the idle sound
if (!audiosource.isPlaying || audiosource.clip != Idle_Sound)
{
PlayIdleSound();
}

// Reset pitch when not accelerating


if (audiosource.pitch > minPitch)
{
audiosource.pitch -= pitchChangeSpeed * Time.deltaTime;
}
}

// Check if there's a gear change and play the gear change sound
if (isChangingGear)
{
isChangingGear = false; // Reset the flag
}
}

void PlayIdleSound()
{
audiosource.clip = Idle_Sound;
audiosource.loop = true;
audiosource.pitch = 1f; // Reset pitch to default
audiosource.Play();
}

void PlayAcceleratingSound()
{
audiosource.clip = Accelerating_Sound;
audiosource.volume = 0.25f;
audiosource.loop = true;
audiosource.pitch = minPitch; // Set initial pitch to minPitch
audiosource.Play();
}

You might also like