【问题标题】:The Object you want to instantiate is null. Unity 3D您要实例化的对象为空。统一 3D
【发布时间】:2020-01-30 13:19:46
【问题描述】:

我的统一代码有问题,我不明白为什么它不起作用。我对统一有点陌生,刚刚开始学习它。我在项目树中有4个具有不同名称的预制件,我希望每秒生成一个预制件,但我希望它在不使用“if”的情况下随机化,所以我尝试将预制件名称保存在一个数组中然后实例化与数组值同名的 GameObject。当我在 Unity 中运行我的脚本时,它说我要实例化的对象为空,我试图在网上找到答案,但我什么也没找到。你能帮助我吗?

这是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawnnoif : MonoBehaviour
{
    public GameObject cub;
    public GameObject capsula;
    public GameObject cilindru;
    public GameObject sfera;
    public int x;
    public GameObject paleta;
    public float delta;
    public string[] a = { "cub", "capsula", "cilindru", "sfera" };

    void Start()
    {
        Vector3 position = new Vector3(UnityEngine.Random.Range(-1.88f, 2.1f), 1, UnityEngine.Random.Range(-7.81f, -3.1f));
        x = UnityEngine.Random.Range(0, 3);
        Instantiate(GameObject.Find(a[x]), position, Quaternion.identity);
    }

    IEnumerator Spawn()
    {
        while (true)
        {
            Vector3 position = new Vector3(UnityEngine.Random.Range(-1.88f, 2.1f), 1, UnityEngine.Random.Range(-7.81f, -3.1f));
            x = UnityEngine.Random.Range(0, 3);
            Instantiate(GameObject.Find(a[x]), position, Quaternion.identity);
            yield return new WaitForSeconds(1.0f);
        }
    }
}

【问题讨论】:

  • 你确定GameObject.Find(a[x]) 会返回一些东西吗?
  • 我现在将游戏对象移到场景中,看起来这是个问题,但它仍然只生成立方体,没有生成其他对象
  • 所有对象的标签名都正确吗?
  • @krobelusmeetsyndra Find 与标签无关,仅与对象名称有关

标签: c# unity3d


【解决方案1】:

不要为此使用Find!它非常昂贵!而且不可靠!

这个函数只返回活跃的GameObjects。如果找不到具有名称的 GameObject,则返回 null

特别是因为您似乎想将其用于仅存在于资产中而不存在于场景中的预制件,因此它将始终返回 null,因为它仅从场景中查找对象。


宁可使用数组

public GameObject[] Prefabs;

在这里引用您的对象并简单地做

Vector3 position = new Vector3(Random.Range(-1.88f, 2.1f), Random.Range(-7.81f, -3.1f));
Instantiate(Prefabs[Random.Range(0, Prefabs.Length)], position, Quaternion.identity);

致您的IEnuemrator ...好吧,您永远不会将其作为协程启动,因此它根本不会运行。

您可以直接在Start 中使用StartCoroutine 进行操作

private void Start()
{
    StartCoroutine(Spawn());
}

private IEnumerator Spawn()
{
    while (true)
    {
        Vector3 position = new Vector3(Random.Range(-1.88f, 2.1f), Random.Range(-7.81f, -3.1f));
        Instantiate(Prefabs[Random.Range(0, Prefabs.Length)], position, Quaternion.identity);

        yield return new WaitForSeconds(1.0f);
    }
}

其实你甚至可以直接使用

private IEnumerator Start()
{
    while (true)
    {
        Vector3 position = new Vector3(Random.Range(-1.88f, 2.1f), Random.Range(-7.81f, -3.1f));
        Instantiate(Prefabs[Random.Range(0, Prefabs.Length)], position, Quaternion.identity);

        yield return new WaitForSeconds(1.0f);
    }
}

如果Start 被声明为IEnumerator,Unity 会自动将其作为协程运行。


或者在这种简单的情况下,您甚至可以使用 InvokeRepeating 之类的

private void Start()
{
    // second parameter is the initial delay
    // last parameter the repeat interval
    InvokeRepeating(nameof(Spawn), 0, 1.0f);
}

private void Spawn()
{
    Vector3 position = new Vector3(Random.Range(-1.88f, 2.1f), Random.Range(-7.81f, -3.1f));
    Instantiate(Prefabs[Random.Range(0, Prefabs.Length)], position, Quaternion.identity);
}

【讨论】:

  • @schneebuzz No! 正如Random.Range for int 的最后一个参数是exclusive 并且因此可以达到。你确实传入Length - 1Note max is exclusive. Random.Range(0, 10) can return a value between 0 and 9.
  • 成功了,非常感谢!现在我仍然对 IEnumerator 有问题,它没有产生任何其他游戏对象,只是在 Start() 中调用的第一个游戏对象
  • @MorarMihai 好吧......你永远不会启动那个协程 ^^ 查看更新
【解决方案2】:

您可以使用一组游戏对象(预制件)并在编辑器中分配它们。然后,您可以在 Inspector 中分​​配任意数量的预制件并随机生成它们:

public class Spawnnoif : MonoBehaviour
{
    public GameObject[] prefabs;

    public int x;
    public GameObject paleta;
    public float delta;

    void Start()
    {
        Vector3 position = new Vector3(UnityEngine.Random.Range(-1.88f, 2.1f), 1, UnityEngine.Random.Range(-7.81f, -3.1f));
        x = UnityEngine.Random.Range(0, prefabs.Length);
        Instantiate(prefabs[x], position, Quaternion.identity);
    }
    ...
}

【讨论】:

  • @derHugo 是的,我猜你的速度稍微快了一点 :) 你是对的,我只是建议对你的帖子进行编辑,但实际上我错了。如果只有range 的实现在不同的技术中是相同的;)
  • 您需要在Spawn()方法中使用相同的代码。然后你还需要使用StartCoroutine(Spawn())启动Start里面的协程。
  • 成功了!很抱歉提出愚蠢的问题,但我还是个新手,一周前刚开始团结一致,我仍然很难理解我应该如何以及在哪里调用函数
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 2022-10-13
  • 1970-01-01
相关资源
最近更新 更多