rabidus-test/Assets/BNG Framework/Scripts/Extras/TimeController.cs

154 lines
4.8 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace BNG {
/// <summary>
/// Press Y to slow time by modifying Time.timeScale and Time.fixedDeltaTime
/// </summary>
public class TimeController : MonoBehaviour {
/// <summary>
/// Timescale to slow down to if slow down key is pressed
/// </summary>
[Tooltip("Timescale to slow down to if slow down key is pressed")]
public float SlowTimeScale = 0.5f;
/// <summary>
/// If true, Y Button will always slow time. Useful for debugging. Otherwise call SlowTime / ResumeTime yourself, or use a Unity InputActionReference
/// </summary>
[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;
/// <summary>
/// If true, will set Time.fixedDeltaTime to the device refresh rate
/// </summary>
[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<AudioSource>();
}
void Update() {
if(CheckInput) {
if (SlowTimeInputDown() || ForceTimeScale) {
SlowTime();
}
else {
ResumeTime();
}
}
}
/// <summary>
/// Returns true if SlowTimeAction is being held down
/// </summary>
/// <returns></returns>
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<float>() > 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;
}
}
}