2017-05-29 3 views
0

Ich bin mit Unity gestartet, und ich brauche (bevor Spiel in Pause ist) ein Ereignis auslösen. Gibt es eine Möglichkeit, ein Ereignis auszulösen, wenn die Time.timeScale auf 0 geändert wird? Etwas wie: Time.timeScale.onBeforeChange() ...Handle Time.timeScale onChange Ereignis

Vielen Dank.

+0

Haben Sie versucht, es in void Update() zu setzen? – Universus

+0

Ehrlich gesagt, ich mag 'Time.timeScale' nicht zum Pausieren, ich hätte lieber einen booleschen Code in meiner Hauptspielklasse, der, wenn er zutrifft, während' Update() 'alle Spiellogik überspringt bedeutender deltaTime-Wert für Dinge wie das Tweening von Menüs und so weiter. – Draco18s

+0

Danke, draco18s, aber ich muss auch handeln, wenn Benutzer Anwendung unerwartet schließen. –

Antwort

3

Machen Sie die Sache, die die Zeitskala einen Controller ändert, dann veranlassen Sie diesen Controller, das Ereignis auszulösen.

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

In anderen Ländern können Sie den Zeitplan von

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

tun ändern Und hier ist eine andere Komponente, die für die Änderung zuhört und bricht die Änderung, wenn die Änderung auch vor kurzem geschehen ist;

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