我从Unity开始,我需要(在游戏暂停之前)触发一个事件。当Time.timeScale
更改为0时,有没有办法触发任何事件?类似于:Time.timeScale.onBeforeChange()
...
非常感谢。
答案 0 :(得分:3)
制作改变控制器时间刻度的东西,然后让控制器举起事件。
[System.Serializable]
public class BeforeTimeChangedData
{
public bool canceled;
public float oldValue;
public float newValue;
}
[System.Serializable]
public class BeforeTimeChangedEvent : UnityEvent<BeforeTimeChangedData>
{
}
//Attach this to a game object that gets loaded in your pre-load scene with the tag "Singletons"
public class TimeController : MonoBehaviour
{
void Awake()
{
DontDestroyOnLoad(gameObject);
if(BeforeTimeChanged == null)
BeforeTimeChanged = new BeforeTimeChangedEvent();
}
public BeforeTimeChangedEvent BeforeTimeChanged;
public bool ChangeTimeScale(float newValue)
{
var args = new BeforeTimeChangedData();
args.oldValue = Time.timeScale;
args.newValue = Time.timeScale;
BeforeTimeChanged.Invoke(args);
if(!args.canceled)
{
Time.timeScale = newValue;
}
return args.canceled;
}
}
在其他地方,您可以通过
更改时间刻度public class TimeSlower : MonoBehaviour
{
private TimeController _timeController;
public Text TimeChanged;
void Start()
{
var singletons = GameObject.FindWithTag("Singletons");
_timeController = singletons.GetComponent<TimeController>();
if(_timeController == null)
throw new System.ArgumentNullException("Could not find a TimeController on the Singletons object");
}
void Update()
{
if(Input.GetButton("SlowTime"))
{
var changed = _timeController.ChangeTimeScale(0.5f);
if(changed)
{
TimeChanged.text = "Time Changed!";
}
}
}
}
这是另一个监听变化的组件,如果最近发生了变化,则取消更改;
public class TimeChangeLimiter : MonoBehaviour
{
private float lastTimeChange = 0;
private TimeController _timeController;
public Text TimeChanged;
[Range(0, float.MaxValue)]
public float Cooldown;
void Start()
{
var singletons = GameObject.FindWithTag("Singletons");
_timeController = singletons.GetComponent<TimeController>();
if(_timeController == null)
throw new System.ArgumentNullException("Could not find a TimeController on the Singletons object");
_timeController.BeforeTimeChanged.AddListener(OnBeforeTimeChanged);
}
void OnDestroy()
{
_timeController.BeforeTimeChanged.RemoveListener(OnBeforeTimeChanged);
}
void OnBeforeTimeChanged(BeforeTimeChangedData args)
{
if(Time.time - lastTimeChange < Cooldown)
{
args.canceled = true;
return;
}
lastTimeChange = Time.time;
}
}