using System.Collections; using System.Collections.Generic; using Cinemachine; using TMPro; using UnityEngine; using static UnityEngine.ParticleSystem; public class GameManager : MonoBehaviour { 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 trafficVehicles = new List(); 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(){ 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"); movespeed += input * acceleration * Time.deltaTime; movespeed = Mathf.Clamp(movespeed, 0, maxspeed); float x = (FovRange / maxspeed) * movespeed; cam.m_Lens.FieldOfView = minFov + x; cam.GetCinemachineComponent().m_FrequencyGain = max_shake_ferquency * movespeed / maxspeed; cam.GetCinemachineComponent().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 = fontSize; txtDistance.fontSize = 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()!=null){ Destroy(other.gameObject); } } }