Reputation: 11317
For example this Coroutine. Let's say I have a ui button that pause the game :
Time.timeScale = 0f;
But timeScale is not working on Coroutines.
And if I have many Coroutines in the game is there a way to find all the Coroutines and then loop on them and pause them or do I need to add a pause loop to each Coroutine ?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.PostProcessing;
public class DepthOfField : MonoBehaviour
{
public UnityEngine.GameObject player;
public PostProcessingProfile postProcessingProfile;
public bool dephOfFieldFinished = false;
public LockSystem playerLockMode;
private Animator playerAnimator;
private float clipLength;
private Coroutine depthOfFieldRoutineRef;
void Start()
{
if (depthOfFieldRoutineRef != null)
{
StopCoroutine(depthOfFieldRoutineRef);
}
playerAnimator = player.GetComponent<Animator>();
AnimationClip[] clips = playerAnimator.runtimeAnimatorController.animationClips;
foreach (AnimationClip clip in clips)
{
clipLength = clip.length;
}
var depthOfField = postProcessingProfile.depthOfField.settings;
depthOfField.focalLength = 300;
StartCoroutine(changeValueOverTime(depthOfField.focalLength, 1, clipLength));
postProcessingProfile.depthOfField.settings = depthOfField;
}
IEnumerator changeValueOverTime(float fromVal, float toVal, float duration)
{
playerLockMode.PlayerLockState(true, true);
float counter = 0f;
while (counter < duration)
{
var dof = postProcessingProfile.depthOfField.settings;
if (Time.timeScale == 0)
counter += Time.unscaledDeltaTime;
else
counter += Time.deltaTime;
float val = Mathf.Lerp(fromVal, toVal, counter / duration);
dof.focalLength = val;
postProcessingProfile.depthOfField.settings = dof;
yield return null;
}
playerAnimator.enabled = false;
dephOfFieldFinished = true;
depthOfFieldRoutineRef = null;
}
}
Upvotes: 1
Views: 2269
Reputation: 18919
You could use the Observer Pattern and create a set of states for the game like: LoadingGame
, Paused
, LoadingLevel
etc and use events to hook into state changes and take appropriate action.
For example:
public enum GameState {
LoadingGame,
LoadingLevel,
Paused,
...
}
Then in a global manager, fire off an event when the state changes:
public event Action<GameState, GameState> OnGameStateChange;
public void SwitchGameState (GameState to) {
previousState = CurrentState;
CurrentState = to;
switch (to) {
case GameState.Paused:
...
break;
...
}
OnGameStateChange?.Invoke (previousState, CurrentState);
}
Any other components, like your DepthOfField
can listen to the event and take appropriate action:
void Awake () {
gameManager.OnGameStateChange += HandleGameStateChange;
}
void HandleGameStateChange (GameState from, GameState to) {
switch (to) {
case GameState.Paused:
// stop or pause couroutine etc
StartCoroutine(coroutine);
break;
}
}
Upvotes: 3