【问题标题】:Unity, Calling Resources.Load from a different threadUnity,从不同的线程调用 Resources.Load
【发布时间】:2019-11-06 20:44:11
【问题描述】:

我制作了一个要在游戏中实例化的预制件。

但是因为我希望它在“幕后”被实例化,这意味着,在“玩家正在做其他事情时”创建所有这些预制件的多个副本。

所以我把生成预制件的代码放在“另一个线程”中。

但是Unity告诉我“Load只能从主线程调用”。

我试图将代码移动到协程中,但不幸的是协程在“主线程”中运行!

或者我应该说,他们不会“并行和同时”执行多个协程!

那么请有人这么好心教我该怎么做!?

非常感谢!

代码:(如果需要,尽管我认为它不会有任何好处)

void Start()
{
    Thread t = new Thread(Do);

    t.Start();
}

private void Do()
{
    for(int i=0;i<1000;i++)
    {
        GameObject RaceGO = (GameObject)(Resources.Load("Race"));

        RaceGO.transform.SetParent(Content);
    }
}

【问题讨论】:

  • 它不是解决方案,但您无法从除主线程之外的任何外部线程访问 Unity API。由于统一只在主线程上运行,所以你必须在主线程中做每一件事,比如实例化、加载场景、协同程序等,但是你可以在主线程之外进行计算,然后将这些信息带回主线程随心所欲。
  • 但是在这种情况下,有一个统一的工作系统可能会有所帮助。您可以查看很多教程。例如:youtube.com/watch?v=gibqhg0wMA0
  • 你不能。我猜你要找的是Resources.LoadAsync
  • @derHugo 你想说的是“我无法同时实例化多个预制件”!?
  • 不.. 我说的是你不能从线程调用Resources.Load 或在线程上运行它。 Unity 的大部分 API 只能在主线程中使用。您应该更改标题,因为这实际上是您标题的答案;)

标签: c# multithreading unity3d instantiation


【解决方案1】:

我无法测试这段代码 atm,但我想你明白了。

GameObject raceGameObject;
// Start "Message" can be a coroutine
IEnumerator Start()
{
    // Load the resource "Race" asynchronously
    var request = Resources.LoadAsync<GameObject>("Race");
    while(!request.IsDone) {
        yield return request;
    }
    raceGameObject = request.asset;
    Do();
}

private void Do()
{
    // Instantiating 1000 gameobjects is nothing imo, if yes split it then, with a coroutine
    for(int i=0;i<1000;i++)
    {
        GameObject RaceGO = Instantaite(raceGameObject);
        RaceGO.transform.SetParent(Content);
    }
}

我也不建议这样做,您应该在编辑器中创建一个public Gameobject myGameObj; 字段,然后为它分配一个值,然后这样做:

// Assign this inside the editor
public GameObject Race;

void Start()
{
    Do();
}

private void Do()
{
    // Instantiating 1000 gameobjects is nothing imo, if yes split it then, with a coroutine
    for(int i=0;i<1000;i++)
    {
        GameObject RaceGO = Instantaite(Race);
        RaceGO.transform.SetParent(Content);
    }
}

【讨论】:

  • 我认为这个while(!request.IsDone) { yield return request; } 有点多余,你可以直接yield return Resources.LoadAsync(...); 或者只是yield return null; 在循环中
  • @derHugo 我认为你是对的,肯定返回请求是多余的,当我尝试代码时会编辑答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
相关资源
最近更新 更多