处理Time.timeScale onChange事件

时间:2017-05-29 17:05:15

标签: c# unity3d unity5

我从Unity开始,我需要(在游戏暂停之前)触发一个事件。当Time.timeScale更改为0时,有没有办法触发任何事件?类似于:Time.timeScale.onBeforeChange() ...

非常感谢。

1 个答案:

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