using UnityEngine; using UnityEngine.UI; using UnityEngine.Rendering.PostProcessing; public class NOSController : MonoBehaviour { [Header("NOS Settings")] [SerializeField] float CurrentNOS = 0f; [SerializeField] float chargeSpeed = 1f; [SerializeField] float depletionSpeed = 1f; [SerializeField] float boostAcceleration = 40f; [SerializeField] float audioVolume = 0.5f; [Header("Audio")] [SerializeField] AudioSource boostAudio = null; [Header("Visuals")] [SerializeField] PostProcessVolume postProcessVolume; [Header("Boost Effects")] [SerializeField] private GameObject[] nosParticles; public bool _isBoosting { get; private set; } private VehicleController _vehicle; private Image _boostBarFill; private Button _boostButton; private LensDistortion lensDistortion; private ChromaticAberration chromaticAberration; private CameraController cameraController; private void Start() { _vehicle = GetComponent(); cameraController = Camera.main.GetComponent(); // Only assign UI for player car if (_vehicle != null && !_vehicle.AIControlled) { _boostBarFill = GameUIManager.Instance.boostBarFill; _boostButton = GameUIManager.Instance.boostButton; _boostButton.onClick.RemoveAllListeners(); _boostButton.onClick.AddListener(() => ActivateNOS(true)); } // Setup boost audio if (boostAudio != null) { boostAudio.playOnAwake = false; boostAudio.loop = true; boostAudio.volume = audioVolume; } // Assign post-processing effects if volume is assigned if (postProcessVolume != null) { postProcessVolume.profile.TryGetSettings(out lensDistortion); postProcessVolume.profile.TryGetSettings(out chromaticAberration); if (lensDistortion != null) { lensDistortion.active = true; lensDistortion.intensity.value = 0f; } if (chromaticAberration != null) { chromaticAberration.active = true; chromaticAberration.intensity.value = 0f; } } } private void FixedUpdate() { if (_vehicle == null) return; if (!_vehicle.nosActive) { CurrentNOS = Mathf.Min(100f, CurrentNOS + Time.fixedDeltaTime * (chargeSpeed * _vehicle.LocalVelocity.z / 30f)); } else { CurrentNOS = Mathf.Max(0f, CurrentNOS - Time.fixedDeltaTime * depletionSpeed); if (CurrentNOS <= 0f) ActivateNOS(false); } // Update UI only for player car if (_vehicle != null && !_vehicle.AIControlled && _boostBarFill != null) { _boostBarFill.fillAmount = CurrentNOS / 100f; } // Boost audio if (boostAudio != null) { if (_vehicle.nosActive && CurrentNOS > 0f) { if (!boostAudio.isPlaying) boostAudio.Play(); } else { if (boostAudio.isPlaying) boostAudio.Stop(); } } // Lens Distortion if (lensDistortion != null) { float targetDistortion = (_vehicle.nosActive && CurrentNOS > 0f) ? -20f : 0f; lensDistortion.intensity.value = Mathf.Lerp(lensDistortion.intensity.value, targetDistortion, Time.deltaTime * 5f); } // Chromatic Aberration if (chromaticAberration != null) { float targetChromatic = (_vehicle.nosActive && CurrentNOS > 0f) ? 1f : 0f; chromaticAberration.intensity.value = Mathf.Lerp(chromaticAberration.intensity.value, targetChromatic, Time.deltaTime * 5f); } } public void ActivateNOS(bool active) { _isBoosting = active; // Update camera FOV if (cameraController != null) cameraController.SetBoosting(active); // Toggle particle systems if (nosParticles != null) { foreach (var ps in nosParticles) { ps.SetActive(active); } } // Activate boost logic if (active) { if (CurrentNOS <= 0f) return; _vehicle.ActivateNOS(true, boostAcceleration); } else { _vehicle.ActivateNOS(false); } } // Assign PostProcessVolume after instantiating the car public void SetPostProcessVolume(PostProcessVolume volume) { postProcessVolume = volume; if (postProcessVolume != null) { postProcessVolume.profile.TryGetSettings(out lensDistortion); postProcessVolume.profile.TryGetSettings(out chromaticAberration); if (lensDistortion != null) { lensDistortion.active = true; lensDistortion.intensity.value = 0f; } if (chromaticAberration != null) { chromaticAberration.active = true; chromaticAberration.intensity.value = 0f; } } } }