Unity 游戏在协程 运行 时停止
Unity game stops while coroutine running
Unity(角色移动和当前游戏场景中的一切)在从网络下载纹理时停止 url。
我正在使用 Socket.IO
进行在线多人游戏。
- 在
void Start()
中使用 socket.emit 请求 'map info'
- 获取 'map info' 并使用
Instantiate()
创建地图实体
- 从url获取个人资料图像(纹理)并更改地图实体的纹理
IEnumerator DownloadImage(string MediaUrl, SpriteRenderer spr) {
// check if url is malformed
if (MediaUrl == null || MediaUrl.Contains("Null")) {
yield break;
}
UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.DataProcessingError || request.result == UnityWebRequest.Result.ProtocolError)
Debug.Log(request.error);
else {
Texture2D tex = ((DownloadHandlerTexture)request.downloadHandler).texture;
spr.sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), tex.width / 2f);
}
}
有没有办法在下载纹理时保持游戏 运行 用户交互(角色移动或按钮操作)?
Unity co-routines (CR) 是一种 entry-level 在 Unity 主线程 上对一系列帧执行工作的危险形式。它们对于跨越一系列帧(例如 fading、explode-my-spaceship-after-5-seconds 或 deferring 的本质上是逻辑的 lerp
很有用驾驶舱显示更新.
CR 被分割并在主线程上多路复用,因此游戏中最慢的部分将成为单帧中对时间需求最大的 CR。在每帧 yield
期间执行任何冗长的操作都会减慢您的游戏速度,尤其是 I/O 操作 .
备选方案 - Unity 工作
相反,请考虑使用 Unity 'IJob',它允许在工作线程上执行操作,从而释放 Unity 线程来做它最擅长的事情,并且 不会很长 I/O 操作.
统一:
Use IJob to schedule a single job that runs in parallel to other jobs and the main thread. When a job is scheduled, the job's Execute method is invoked on a worker thread. More...
现在浪费整个线程可能会花费一生等待 I/O 完成可以说是对一个非常好的线程的浪费,但它肯定比阻塞主线程更好。
协程...成为龙
所以之前我提到 “危险” 关于 CR,原因是 three-fold:
- 在每秒调用多次的方法(例如
Update()
中触发 CR 时,请确保您 充分保护 StartCoroutine()
否则您最终可能会有数以万计的 运行 只到 运行 内存不足。这个在 Stack Overflow 上很常见
- 不要错误地认为它们是工作线程或其他不会减慢主线程速度的魔法
- 在许多方面,CR 在 Visual Basic 和 .NET 中分别类似于
DoEvents
、Application.DoEvents
和两者都会导致 re-entrancy 的严重情况(其中状态被破坏且不可预测,就像在 multi-threaded 应用程序中一样,但 没有线程 )
还有整个 Unity 是否在促进 IEnumerator
和 yield
的奇怪用法? 辩论。
我的另一个提示是,如果你需要一些 lerped 或延迟的东西并且没有做 I/O,考虑只做一个 class 并使用 Time
.
例如in my flight sim,我只想每 100 毫秒左右更新一次驾驶舱显示。为此,我定义了一个 Delay
class:
public class Delay
{
private float _lastInterval;
/// <summary>
/// The timeout in seconds
/// </summary>
/// <param name="timeout"></param>
private Delay(float timeout)
{
Timeout = timeout;
_lastInterval = Time.time;
}
public float Timeout { get; }
public bool IsTimedOut => Time.time> _lastInterval + Timeout;
public void Reset()
{
_lastInterval = Time.time;
}
public static Delay StartNew(float delayInSeconds)
{
return new Delay(delayInSeconds);
}
}
.
.
.
private void Update()
{
if (!_delay.IsTimedOut)
{
return;
}
// Do something time consuming
_delay.Reset();
}
Unity(角色移动和当前游戏场景中的一切)在从网络下载纹理时停止 url。
我正在使用 Socket.IO
进行在线多人游戏。
- 在
void Start()
中使用 socket.emit 请求 'map info'
- 获取 'map info' 并使用
Instantiate()
创建地图实体
- 从url获取个人资料图像(纹理)并更改地图实体的纹理
IEnumerator DownloadImage(string MediaUrl, SpriteRenderer spr) {
// check if url is malformed
if (MediaUrl == null || MediaUrl.Contains("Null")) {
yield break;
}
UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.DataProcessingError || request.result == UnityWebRequest.Result.ProtocolError)
Debug.Log(request.error);
else {
Texture2D tex = ((DownloadHandlerTexture)request.downloadHandler).texture;
spr.sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), tex.width / 2f);
}
}
有没有办法在下载纹理时保持游戏 运行 用户交互(角色移动或按钮操作)?
Unity co-routines (CR) 是一种 entry-level 在 Unity 主线程 上对一系列帧执行工作的危险形式。它们对于跨越一系列帧(例如 fading、explode-my-spaceship-after-5-seconds 或 deferring 的本质上是逻辑的 lerp
很有用驾驶舱显示更新.
CR 被分割并在主线程上多路复用,因此游戏中最慢的部分将成为单帧中对时间需求最大的 CR。在每帧 yield
期间执行任何冗长的操作都会减慢您的游戏速度,尤其是 I/O 操作 .
备选方案 - Unity 工作
相反,请考虑使用 Unity 'IJob',它允许在工作线程上执行操作,从而释放 Unity 线程来做它最擅长的事情,并且 不会很长 I/O 操作.
统一:
Use IJob to schedule a single job that runs in parallel to other jobs and the main thread. When a job is scheduled, the job's Execute method is invoked on a worker thread. More...
现在浪费整个线程可能会花费一生等待 I/O 完成可以说是对一个非常好的线程的浪费,但它肯定比阻塞主线程更好。
协程...成为龙
所以之前我提到 “危险” 关于 CR,原因是 three-fold:
- 在每秒调用多次的方法(例如
Update()
中触发 CR 时,请确保您 充分保护StartCoroutine()
否则您最终可能会有数以万计的 运行 只到 运行 内存不足。这个在 Stack Overflow 上很常见
- 不要错误地认为它们是工作线程或其他不会减慢主线程速度的魔法
- 在许多方面,CR 在 Visual Basic 和 .NET 中分别类似于
DoEvents
、Application.DoEvents
和两者都会导致 re-entrancy 的严重情况(其中状态被破坏且不可预测,就像在 multi-threaded 应用程序中一样,但 没有线程 )
还有整个 Unity 是否在促进 IEnumerator
和 yield
的奇怪用法? 辩论。
我的另一个提示是,如果你需要一些 lerped 或延迟的东西并且没有做 I/O,考虑只做一个 class 并使用 Time
.
例如in my flight sim,我只想每 100 毫秒左右更新一次驾驶舱显示。为此,我定义了一个 Delay
class:
public class Delay
{
private float _lastInterval;
/// <summary>
/// The timeout in seconds
/// </summary>
/// <param name="timeout"></param>
private Delay(float timeout)
{
Timeout = timeout;
_lastInterval = Time.time;
}
public float Timeout { get; }
public bool IsTimedOut => Time.time> _lastInterval + Timeout;
public void Reset()
{
_lastInterval = Time.time;
}
public static Delay StartNew(float delayInSeconds)
{
return new Delay(delayInSeconds);
}
}
.
.
.
private void Update()
{
if (!_delay.IsTimedOut)
{
return;
}
// Do something time consuming
_delay.Reset();
}