using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; namespace BNG { /// /// Press Y to slow time by modifying Time.timeScale and Time.fixedDeltaTime /// public class TimeController : MonoBehaviour { /// /// Timescale to slow down to if slow down key is pressed /// [Tooltip("Timescale to slow down to if slow down key is pressed")] public float SlowTimeScale = 0.5f; /// /// If true, Y Button will always slow time. Useful for debugging. Otherwise call SlowTime / ResumeTime yourself, or use a Unity InputActionReference /// [Tooltip("If true, Y Button will always slow time. Useful for debugging. Otherwise call SlowTime / ResumeTime yourself")] public bool YKeySlowsTime = true; [Tooltip("Input Action used to initiate slow time")] public InputActionReference SlowTimeAction; [Tooltip("(Optional) Play this clip when starting to slow time")] public AudioClip SlowTimeClip; [Tooltip("(Optional) Play this clip when ending slow mo")] public AudioClip SpeedupTimeClip; /// /// If true, will set Time.fixedDeltaTime to the device refresh rate /// [Tooltip("If true, will set Time.fixedDeltaTime to the device refresh rate")] public bool SetFixedDelta = false; [Tooltip("If true, will check for input in Update to slow down time. If false you'll need to call SlowTime() / ResumeTime() manually from script")] public bool CheckInput = true; public bool TimeSlowing { get { return _slowingTime; } } bool _slowingTime = false; bool routineRunning = false; float originalFixedDelta; AudioSource audioSource; public bool ForceTimeScale = false; // Start is called before the first frame update void Start() { if(SetFixedDelta) { Time.fixedDeltaTime = (Time.timeScale / UnityEngine.XR.XRDevice.refreshRate); } originalFixedDelta = Time.fixedDeltaTime; audioSource = GetComponent(); } void Update() { if(CheckInput) { if (SlowTimeInputDown() || ForceTimeScale) { SlowTime(); } else { ResumeTime(); } } } /// /// Returns true if SlowTimeAction is being held down /// /// public virtual bool SlowTimeInputDown() { // Check default Y Key if ((YKeySlowsTime && InputBridge.Instance.YButton)) { return true; } // Check for Unity Input Action if (SlowTimeAction != null) { return SlowTimeAction.action.ReadValue() > 0f; } return false; } public void SlowTime() { if(!_slowingTime) { // Make sure we aren't running a routine if(resumeRoutine != null) { StopCoroutine(resumeRoutine); } // Play Slow time clip audioSource.clip = SlowTimeClip; audioSource.Play(); // Haptics if(SpeedupTimeClip) { InputBridge.Instance.VibrateController(0.1f, 0.2f, SpeedupTimeClip.length, ControllerHand.Left); } Time.timeScale = SlowTimeScale; Time.fixedDeltaTime = originalFixedDelta * Time.timeScale; _slowingTime = true; } } private IEnumerator resumeRoutine; public void ResumeTime() { // toggled over; play audio cue // Don't resume until we're done playing the initial sound clip if(_slowingTime && !audioSource.isPlaying && !routineRunning) { resumeRoutine = resumeTimeRoutine(); StartCoroutine(resumeRoutine); } } IEnumerator resumeTimeRoutine() { routineRunning = true; audioSource.clip = SpeedupTimeClip; audioSource.Play(); InputBridge.Instance.VibrateController(0.1f, 0.2f, SpeedupTimeClip.length, ControllerHand.Left); // Wait for a split second before resuming time again yield return new WaitForSeconds(0.35f); Time.timeScale = 1; Time.fixedDeltaTime = originalFixedDelta; _slowingTime = false; routineRunning = false; } } }