2017-05-29 68 views
0

我开始使用Unity,我需要(在游戏暂停之前)触发avent。当Time.timeScale更改为0时,是否有任何方法触发任何事件?例如:Time.timeScale.onBeforeChange() ...Handle Time.timeScale onChange事件

非常感谢。

+0

你试过把它放在void Update()中吗? – Universus

+0

老实说,我不喜欢用'Time.timeScale'来暂停,我宁愿在我的主游戏类中有一个布尔值,如果为true,则在'Update()'期间跳过所有游戏逻辑,这允许我仍然有一个有意义的deltaTime值用于执行补间菜单等操作。 – Draco18s

+0

谢谢,draco18s,但如果用户意外关闭应用程序,我也需要讨论。 –

回答

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; 
    } 
}