170 lines
5.6 KiB
C#
170 lines
5.6 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Cinemachine;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using static UnityEngine.ParticleSystem;
|
|
|
|
public class GameManager : MonoBehaviour
|
|
{
|
|
public bool isAuto = false;
|
|
public static GameManager instance;
|
|
public void Awake(){
|
|
instance = this;
|
|
}
|
|
public static float movespeed = 0f;
|
|
public float acceleration = 5;
|
|
|
|
public float maxspeed = 30f;
|
|
public CinemachineVirtualCamera cam;
|
|
public ParticleSystem speedLinesEffect;
|
|
public float minFov = 50;
|
|
public float maxFov = 90;
|
|
public float Distance;
|
|
|
|
public float max_shake_ferquency = 2f;
|
|
public float max_shake_amplitude = 0.08f;
|
|
|
|
public TMP_Text txtSpeed;
|
|
public TMP_Text txtDistance;
|
|
public float FovRange => maxFov - minFov;
|
|
|
|
[Header("Obstacle avoidance")]
|
|
public int currentLaneId = 0;
|
|
public float laneSwitchSpeed = 10f;
|
|
public float laneSwitchRotationMultiplier = 0.2f;
|
|
public float[] laneXs = {-1.5f, 0f, 1.5f};
|
|
public Transform car;
|
|
public CollisionDetector collisionDetector;
|
|
|
|
EmissionModule speedLinesEmission;
|
|
public CinemachineImpulseSource impulseSource;
|
|
public GameObject trafficVehiclePrefab;
|
|
public List<GameObject> trafficVehicles = new List<GameObject>();
|
|
public int maxTrafficVehicles = 10;
|
|
public float trafficVehicleSpawnInterval = 5f;
|
|
float trafficVehicleSpawnTimer =0f;
|
|
|
|
float startRotationY;
|
|
void Start()
|
|
{
|
|
speedLinesEmission = speedLinesEffect.emission;
|
|
startRotationY = car.eulerAngles.y;
|
|
collisionDetector.OnEnter += OnTriggerEnter;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void FixedUpdate()
|
|
{
|
|
MoveForward();
|
|
}
|
|
|
|
void Update(){
|
|
if(isAuto){return;}
|
|
SwitchLanes();
|
|
TrafficVehicleSpawn();
|
|
}
|
|
|
|
void TrafficVehicleSpawn(){
|
|
trafficVehicleSpawnTimer += Time.deltaTime * movespeed / maxspeed;
|
|
if(trafficVehicleSpawnTimer >= trafficVehicleSpawnInterval){
|
|
trafficVehicleSpawnTimer = 0;
|
|
SpawnNextTrafficVehicle();
|
|
}
|
|
}
|
|
|
|
void SpawnNextTrafficVehicle(){
|
|
trafficVehicles.RemoveAll(item => item == null);
|
|
|
|
if(trafficVehicles.Count < maxTrafficVehicles){
|
|
GameObject trafficVehicle = Instantiate(trafficVehiclePrefab, new Vector3(laneXs[currentLaneId], 0, -500), Quaternion.Euler(0,-90,0));
|
|
trafficVehicles.Add(trafficVehicle);
|
|
}
|
|
}
|
|
|
|
float laneSwitchTime =0;
|
|
void SwitchLanes(){
|
|
|
|
if(displaySpeed < 10){return;}
|
|
|
|
float switchSpeedMultiplier = 1 + (displaySpeed/laneSwitchSpeed);
|
|
|
|
if(Input.GetKeyDown(KeyCode.LeftArrow)){
|
|
currentLaneId--;
|
|
laneSwitchTime = 0;
|
|
}
|
|
else if(Input.GetKeyDown(KeyCode.RightArrow)){
|
|
currentLaneId++;
|
|
laneSwitchTime = 0;
|
|
}
|
|
|
|
if(laneSwitchTime < 1){
|
|
laneSwitchTime += Time.deltaTime * 2;
|
|
}
|
|
|
|
currentLaneId = Mathf.Clamp(currentLaneId, 0, laneXs.Length - 1);
|
|
float lerper = switchSpeedMultiplier*Time.deltaTime * laneSwitchTime;
|
|
car.position = new Vector3(Mathf.Lerp(car.position.x,laneXs[currentLaneId],lerper), car.position.y, car.position.z);
|
|
|
|
float xDist = (car.position.x - laneXs[currentLaneId]);
|
|
|
|
Vector3 targetRotation = new Vector3(car.eulerAngles.x, startRotationY + Mathf.Atan2(xDist, 1) * Mathf.Rad2Deg * laneSwitchRotationMultiplier * (1-(movespeed/maxspeed)), car.eulerAngles.z);
|
|
car.eulerAngles = Vector3.Lerp(car.eulerAngles, targetRotation, lerper);
|
|
}
|
|
|
|
float displaySpeed = 0;
|
|
void MoveForward(){
|
|
float input = Input.GetAxis("Vertical");
|
|
|
|
if(isAuto){input = 0; movespeed = maxspeed /3f;}
|
|
movespeed += input * acceleration * Time.deltaTime;
|
|
movespeed = Mathf.Clamp(movespeed, 0, maxspeed);
|
|
|
|
float x = (FovRange / maxspeed) * movespeed;
|
|
|
|
cam.m_Lens.FieldOfView = minFov + x;
|
|
cam.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>().m_FrequencyGain = max_shake_ferquency * movespeed / maxspeed;
|
|
cam.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin>().m_AmplitudeGain = max_shake_amplitude * movespeed / maxspeed;
|
|
|
|
displaySpeed = movespeed * 2.5f;
|
|
|
|
txtSpeed.text = displaySpeed.ToString("n0") + " km/h";
|
|
Distance += displaySpeed * Time.deltaTime / 3600;
|
|
txtDistance.text = Distance.ToString("n2") + " km";
|
|
|
|
float fontSize = Mathf.Lerp(10f, 15f, movespeed / maxspeed);
|
|
txtSpeed.fontSize = isAuto ? 0 : fontSize;
|
|
txtDistance.fontSize = isAuto ? 0 : fontSize;
|
|
|
|
speedLinesEmission.rateOverTime = displaySpeed > 100 ? displaySpeed : 0;
|
|
}
|
|
|
|
public int lives = 3;
|
|
|
|
void OnTriggerEnter(Collider other)
|
|
{
|
|
Debug.Log("OnTriggerEnter: " + other.gameObject.name + " : " + other.gameObject.tag);
|
|
string objectNameLowered = other.gameObject.name.ToLower();
|
|
if(objectNameLowered.Contains("section")){
|
|
return;
|
|
}
|
|
|
|
if(objectNameLowered.Contains("player")){
|
|
return;
|
|
}
|
|
|
|
movespeed = maxspeed / 10f;
|
|
lives--;
|
|
LivesVisualizer.instance.SetLives(lives);
|
|
impulseSource.GenerateImpulse();
|
|
|
|
//Snap to lane
|
|
car.position = new Vector3(laneXs[currentLaneId], car.position.y, car.position.z);
|
|
|
|
if(other.GetComponent<TrafficVehicle>()!=null){
|
|
Destroy(other.gameObject);
|
|
}
|
|
}
|
|
|
|
}
|