2017-05-29 102 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; 
    } 
}