Unity有几种控制时间延迟的方法?

时间:2015-11-25 08:47:36

标签: c# unity3d timedelay

我环顾四周,显然我可以在这些库/解决方案之间做出选择:

之一:

public void Awake() {
    Invoke("InvokeAndPrint", 2);
}

void InvokeAndPrint() {
    print("InvokeAndPrint 2");
}

2:

void Start() {
    StartCoroutine(WaitAndPrint(2.0F));
}

IEnumerator WaitAndPrint(float waitTime) {
    yield return new WaitForSeconds(waitTime);
    print("WaitAndPrint " + Time.time);
}

如果还有其他更好的方法,我想知道吗?提前谢谢。

1 个答案:

答案 0 :(得分:1)

这是我上面评论的摘要

我能想到的另一种方法是老派注意开始的时间;然后在Update()方法中检查已用时间。你基本上自己做所有事情。虽然比上面的示例更冗长,但它是类型安全的,不需要任何额外的线程或线程作业对象。

最简单

首先我们需要定义一些字段:

private DateTime _start;
private bool _done;

在你开始时记下时间:

void Start()
{
    _start = DateTime.Now;
}

...然后在您的更新检查中查看已经过了多长时间。如果它超过你说2秒的超时时间,那么你可以做任何你希望做的事情 - 在这种情况下print()

void Update()
{
    if (! _done && (DateTime.Now - _start).TotalSeconds >= 2)
    {
        print("hello world");
        _done = true;
    }
}

就是这样。

可重复使用的代码

你可能会发现有很多地方需要这样做,所以如果有办法减少重复的代码就不会很常见。也许是一个将它包装起来的类?

class DelayedJob
{
    private readonly TimeSpan _delay;
    private readonly Action _action;
    private readonly DateTime _start;

    public DelayedJob(TimeSpan delay, Action action)
    {
        if (action == null)
        {
            throw new ArgumentNullException("action");
        }
        _delay = delay;
        _action = action;
        _start = DateTime.Now;
    }

    /// <summary>
    /// Updates this instance.
    /// </summary>
    /// <returns>true if there is more work to do, false otherwise</returns>
    public bool Update()
    {
        if (DateTime.Now - _start >= _delay)
        {
            _action();
            return false;
        }

        return true;
    }
}

然后你可以这样做:

void Start()
{
    _job = new DelayedJob(TimeSpan.FromSeconds(2), ()=> print("hello"));
}

...相应地更新Update()之后:

void Update()
{
    if (_job != null && !_job.Update())
    {
        _job = null;
    }
}

多个职位

只需将它们放在一个集合中并在运行时处理它。

private List<DelayedJob> _jobs; 

void Start()
{
    _jobs = new List<DelayedJob>
            {
                new DelayedJob(TimeSpan.FromSeconds(2), () => print("star wars")),
                new DelayedJob(TimeSpan.FromSeconds(3f), () => print("is coming!"))
            };
}

...... Update()的一些改动:

void Update()
{    
    bool again;

    do
    {
        again = false;
        // you probably want to optimise this so that we don't check the same items
        // at the start again after removing an item
        foreach (var delayedJob in _jobs)
        {
            if (!delayedJob.Update())
            {
                _jobs.Remove(delayedJob);
                again = true; // start over
                break;
            }
        }
    }
    while (again);    
}