Unity3D/Script
timeScale Lerp for Unity 3D: Custom Time Manager
blueasa
2015. 3. 9. 23:24
timeScale Lerp – Custom Time Manager
By now I need a timeScale Lerp and this need to be Time.deltaTime independent so, for anyone who needs this too, here’s what I’ve got (C#). You can also use it to create slow motion effects and control the play /pause of your game (assuming that you are using a Time.timeScale dependent approach):
You cal also get this code at GitHub
/// <summary>
/// Time Manager.
/// Time.deltaTime independent Time.timeScale Lerp.
/// Author: Fabio Paes Pedro
/// </summary>
///
///
using UnityEngine;
using System.Collections;
public class CustomTimeManager : MonoBehaviour
{
/// <summary>
/// CustomTimeManager is Paused or not
/// </summary>
[SerializeField]
private bool _isPaused = false;
/// <summary>
/// CustomTimeManager is Fading (from _minScale to _scale or vice-versa)
/// </summary>
[SerializeField]
private bool _isFading = false;
/// <summary>
/// CustomTimeManager will pause after fading (is going from _scale to _minScale)
/// </summary>
[SerializeField]
private bool _willPause = false;
[SerializeField]
private float _scale = 1f;
private float _fadeToScaleDifference = 0f;
private float _scaleToFade = 0f;
[SerializeField]
private float _deltaTime = 0f;
private float _lastTime = 0f;
private float _maxScale = 3f;
private float _minScale = 0f;
private bool _fadeToScaleIsGreater = false;
#region PseudoSingleton
private static CustomTimeManager _instance;
public static CustomTimeManager Instance
{
get
{
return _instance;
}
}
void Awake()
{
if (_instance != null) Debug.LogError("There's another instance of " + this + " already");
_instance = this;
}
void OnDestroy()
{
_instance = null;
}
#endregion
void Start()
{
Scale = Time.timeScale;
StartCoroutine("UpdateDeltaTime");
}
public bool WillPause
{
get
{
return _willPause;
}
}
public bool IsFading
{
get
{
return _isFading;
}
}
public bool IsPaused
{
get
{
return _isPaused;
}
}
/// <summary>
/// Time.timeScale independent deltaTime
/// </summary>
/// <value>
/// time.timeScale independent Delta Time
/// </value>
public float DeltaTime
{
get
{
return _deltaTime;
}
}
/// <summary>
/// Getter and Setter for the CustomTimeManager Scale (time.timeScale). This will set IsPaused to true automatically if the scale == 0f
/// </summary>
/// <value>
/// Scale (Time.timeScale)
/// </value>
public float Scale
{
get
{
return _scale;
}
set
{
_scale = value;
_scale = _scale < _minScale ? _minScale : _scale > _maxScale ? _maxScale : _scale;
Time.timeScale = _scale;
_isPaused = _scale <= 0.001f;
if (_isPaused)
{
_scale = 0f;
_willPause = false;
}
}
}
/// <summary>
/// Pause toggle (Changes the "IsPaused" flag from true to false and vice-versa)
/// </summary>
/// </param>
/// <param name='time'>
/// Time until Pause or Play
/// </param>
/// <param name='playScale'>
/// Play scale.
/// </param>
public void TogglePause(float time = 0f, float playScale = -1f)
{
StopStepper();
// WillPause == true means that a "Pause" was already called: this will make "WillPause" change to false and call "Play" function.
// Else just toggle.
_willPause = _willPause == true ? false : !_isPaused;
if (_willPause)
{
Pause(time);
}
else
{
Play(time, playScale);
}
}
void StopStepper()
{
_instance.StopCoroutine("FadeStepper");
}
/// <summary>
/// CustomTimeManager Pause
/// </summary>
/// <param name='time'>Fading time until Time.timeScale == 0f</param>
public void Pause(float time = 0f)
{
if (Mathf.Approximately(time, 0f))
{
_willPause = false;
_instance.StopCoroutine("FadeStepper");
Scale = 0f;
}
else
{
_willPause = true;
FadeTo(0f, time);
}
}
/// <summary>
/// CustomTimeManager Play
/// </summary>
/// <param name='time'>
/// Fading time until Time.timeScale == scale param
/// </param>
/// <param name='scale'>
/// Final scale for Time.timeScale
/// </param>
public void Play(float time = 0f, float scale = 1f)
{
if (Mathf.Approximately(time, 0f))
{
_instance.StopCoroutine("FadeStepper");
Scale = scale;
}
else
{
FadeTo(scale, time);
}
}
/// <summary>
/// CustomTimeManager Scale Fading.
/// </summary>
/// <param name='scale'>
/// The final Time.timeScale
/// </param>
/// <param name='time'>
/// The transition time to reach the desired scale
/// </param>
public void FadeTo(float scale, float time)
{
_instance.StopCoroutine("FadeStepper");
_scaleToFade = scale;
_fadeToScaleDifference = scale - _scale;
_fadeToScaleIsGreater = _fadeToScaleDifference > 0f;
float scalePerFrame = _fadeToScaleDifference / time;
_instance.StartCoroutine("FadeStepper", scalePerFrame);
}
/// <summary>
/// Coroutine to fade the Unity's timeScale
/// </summary>
IEnumerator FadeStepper(float scalePerFrame)
{
bool achieved = false;
_isFading = true;
while (achieved == false)
{
Scale += scalePerFrame * _deltaTime;
if (_fadeToScaleIsGreater)
{
achieved = _scale >= _scaleToFade;
}
else
{
achieved = _scale <= _scaleToFade;
}
yield return null;
}
Scale = _scaleToFade;
_isFading = false;
_willPause = false;
}
/// <summary>
/// Updating our internal _deltaTime
/// </summary>
IEnumerator UpdateDeltaTime()
{
while (true)
{
float timeSinceStartup = Time.realtimeSinceStartup;
_deltaTime = timeSinceStartup - _lastTime;
_lastTime = timeSinceStartup;
yield return null;
}
}
}
출처 : http://fliperamma.com/timescale-lerp-custom-time-manager/
반응형