在Unity3D游戏引擎中,如何做延迟?
In Unity3D game engine, how to make a delay?
这只与游戏引擎Unity3D有关。
假设我有一行代码,然后是另一行。我将如何在这两行代码之间进行延迟。重复一遍,我也在为 Unity3D 做这个。
我到处都找过了,但没有任何效果。
作为 FRAME-BASED 游戏引擎,显然,Unity 具有各种可以想象的计时器和 运行 内置循环控制。
制作定时器绝对是微不足道的...
Debug.Log("Race begins!");
// 3 seconds later, make the crowd cheer
Invoke("CrowdCheers", 3f);
// 7 seconds later, show fireworks
Invoke("Fireworks", 3f);
private void CrowdCheers()
{
crowd.Play();
}
private void Fireworks()
{
fireworks.SetActive(true);
}
如果您的编码水平更高,可以使用 "coroutines"。协程是访问 运行 循环的一种非常简单的方法。示例:
using UnityEngine;
using System.Collections;
public class demo : MonoBehaviour {
// Details at: http://docs.unity3d.com/Manual/Coroutines.html
// Use this for initialization
void Start () {
// Some start up code here...
Debug.Log("Co-1");
StartCoroutine("OtherThing");
Debug.Log("Co-2");
}
IEnumerator OtherThing()
{
Debug.Log("Co-3");
yield return new WaitForSeconds(0f);
Debug.Log("Co-4");
DoOneThing();
yield return new WaitForSeconds(1f);
Debug.Log("Co-5");
DoOtherThing();
}
void DoOneThing()
{
Debug.Log("Co-6");
}
void DoOtherThing()
{
Debug.Log("Co-7");
}
}
How would I make a delay between those two lines of code.
一般来说,你最不想放入游戏的是线程休眠,即使它是在工作线程中.
如上venerik所述:
I think you should take another approach. Invest some time in studying the game loop. Then, you can split your code to do something (your first line) and then execute something else (your second line) after some Time.deltaTime has passed. Thread.Sleep
is almost always a very big no-no
当然可以使用 yield return
和 Unity3D 的 WaitForSeconds()
,但是这样的方法 无法扩展 并且很可能会占用线程池,尤其是如果您经常为每个对象每帧调用此方法!
我可能会问 "what is your intention for the delay in the first place?"
如果是为了每帧更新 1000 秒游戏对象的状态,那么 thread sleep not 是一个明智的选择。
Whosebug 的 "How do I write a good answer?" 是这样说的:
The answer can be “don’t do that”, but it should also include “try this instead”.
至此,我给你我的建议:
代码行之间的逻辑延迟
相反,一种常见的技术是延迟处理。您可以在其中安排某些事情应该开始的时间,并且在此之前您可以跳过任何处理。它有助于避免您必须同时处理许多事情的情况。相反,您可以延长处理时间。它有助于减少处理中的峰值和帧速率的下降。
在下面的示例中,我有一个包含 1000 辆汽车的游戏,所有汽车都带有 GPS,这些 GPS 必须定期更新以找到到达目的地的最佳路径。我不是每帧都执行此计算(这样效率很低),而是每辆车每 3 秒执行一次。汽车被分成 10 批次,以避免在等待 3 秒后一次处理所有汽车。
例如
class CarWithGps
{
private DateTime _lastUpdate = DateTime.MinValue;
public CarWithGps()
{
}
public DateTime UpdateAt { get; set; }
public TimeSpan UpdateInterval { get; set; }
public void Update()
{
if (UpdateAt>DateTime.Now)
{
return;
}
// calculate new optimised GPS path
.
.
.
UpdateAt = DateTime.Now + UpdateInterval;
}
}
public class GpsGame : MonoBehaviour
{
private List<CarWithGps> _cars;
void Start()
{
_cars = new List<CarWithGps>();
for (int i = 0; i < 1000; i++)
{
_cars.Add(new CarWithGps {UpdateAt = DateTime.Now.AddSeconds(i/10), UpdateInterval = TimeSpan.FromSeconds(3)});
}
}
void Update()
{
// update car GPS optimal path ever few seconds
_cars.ForEach(x => x.Update());
}
}
游戏 Cities:Skylines 使用延迟处理来计算车辆行驶的路径,以便在不影响帧率的情况下到达目的地。
好处
- 没有线程休眠
- 线程池上没有作业排队
- 线程池没有耗尽
只是游戏主循环 运行 全力以赴!
这只与游戏引擎Unity3D有关。
假设我有一行代码,然后是另一行。我将如何在这两行代码之间进行延迟。重复一遍,我也在为 Unity3D 做这个。
我到处都找过了,但没有任何效果。
作为 FRAME-BASED 游戏引擎,显然,Unity 具有各种可以想象的计时器和 运行 内置循环控制。
制作定时器绝对是微不足道的...
Debug.Log("Race begins!");
// 3 seconds later, make the crowd cheer
Invoke("CrowdCheers", 3f);
// 7 seconds later, show fireworks
Invoke("Fireworks", 3f);
private void CrowdCheers()
{
crowd.Play();
}
private void Fireworks()
{
fireworks.SetActive(true);
}
如果您的编码水平更高,可以使用 "coroutines"。协程是访问 运行 循环的一种非常简单的方法。示例:
using UnityEngine;
using System.Collections;
public class demo : MonoBehaviour {
// Details at: http://docs.unity3d.com/Manual/Coroutines.html
// Use this for initialization
void Start () {
// Some start up code here...
Debug.Log("Co-1");
StartCoroutine("OtherThing");
Debug.Log("Co-2");
}
IEnumerator OtherThing()
{
Debug.Log("Co-3");
yield return new WaitForSeconds(0f);
Debug.Log("Co-4");
DoOneThing();
yield return new WaitForSeconds(1f);
Debug.Log("Co-5");
DoOtherThing();
}
void DoOneThing()
{
Debug.Log("Co-6");
}
void DoOtherThing()
{
Debug.Log("Co-7");
}
}
How would I make a delay between those two lines of code.
一般来说,你最不想放入游戏的是线程休眠,即使它是在工作线程中.
如上venerik所述:
I think you should take another approach. Invest some time in studying the game loop. Then, you can split your code to do something (your first line) and then execute something else (your second line) after some Time.deltaTime has passed.
Thread.Sleep
is almost always a very big no-no
当然可以使用 yield return
和 Unity3D 的 WaitForSeconds()
,但是这样的方法 无法扩展 并且很可能会占用线程池,尤其是如果您经常为每个对象每帧调用此方法!
我可能会问 "what is your intention for the delay in the first place?"
如果是为了每帧更新 1000 秒游戏对象的状态,那么 thread sleep not 是一个明智的选择。
Whosebug 的 "How do I write a good answer?" 是这样说的:
The answer can be “don’t do that”, but it should also include “try this instead”.
至此,我给你我的建议:
代码行之间的逻辑延迟
相反,一种常见的技术是延迟处理。您可以在其中安排某些事情应该开始的时间,并且在此之前您可以跳过任何处理。它有助于避免您必须同时处理许多事情的情况。相反,您可以延长处理时间。它有助于减少处理中的峰值和帧速率的下降。
在下面的示例中,我有一个包含 1000 辆汽车的游戏,所有汽车都带有 GPS,这些 GPS 必须定期更新以找到到达目的地的最佳路径。我不是每帧都执行此计算(这样效率很低),而是每辆车每 3 秒执行一次。汽车被分成 10 批次,以避免在等待 3 秒后一次处理所有汽车。
例如
class CarWithGps
{
private DateTime _lastUpdate = DateTime.MinValue;
public CarWithGps()
{
}
public DateTime UpdateAt { get; set; }
public TimeSpan UpdateInterval { get; set; }
public void Update()
{
if (UpdateAt>DateTime.Now)
{
return;
}
// calculate new optimised GPS path
.
.
.
UpdateAt = DateTime.Now + UpdateInterval;
}
}
public class GpsGame : MonoBehaviour
{
private List<CarWithGps> _cars;
void Start()
{
_cars = new List<CarWithGps>();
for (int i = 0; i < 1000; i++)
{
_cars.Add(new CarWithGps {UpdateAt = DateTime.Now.AddSeconds(i/10), UpdateInterval = TimeSpan.FromSeconds(3)});
}
}
void Update()
{
// update car GPS optimal path ever few seconds
_cars.ForEach(x => x.Update());
}
}
游戏 Cities:Skylines 使用延迟处理来计算车辆行驶的路径,以便在不影响帧率的情况下到达目的地。
好处
- 没有线程休眠
- 线程池上没有作业排队
- 线程池没有耗尽
只是游戏主循环 运行 全力以赴!