【问题标题】:Trouble instantiating prefab object by calling function in external script (Unity/C#)通过调用外部脚本(Unity/C#)中的函数来实例化预制对象时遇到问题
【发布时间】:2019-05-03 21:54:27
【问题描述】:

我无法让一个脚本从另一个脚本调用实例化函数。下图说明了我是如何设置游戏对象的。

我有 2 个对象,Thing1 和 Thing2,它们根据附加到每个对象的移动脚本在屏幕上移动。 Thing1 还附上了一个反应脚本。当 Thing1 和 Thing2 发生碰撞时,Thing 3 应该会出现。 Thing3 附加了一个实例化脚本,其中包含一个带有实例化命令的函数。

当我在实例化脚本中调用实例化函数时(我把它放在 Thing3 的 Start 函数中),它工作正常。但是,当我将它从那里取出并尝试将其放入附加到 Thing2 的反应脚本的 Start 函数中时,我无法让它工作。目前,我在编译时没有收到任何错误,但游戏一开始我就得到以下信息(Thing1 和 Thing2 的行为似乎也受到了不利影响):

"NullReferenceException: Object reference not set to an instance of an object"

当我查找该错误的原因时,我发现最典型的原因是预制对象未附加到脚本。但是,我确实在脚本上附加了一个预制件。它附加到包含实例化函数的实例化脚本中。

下面是实例化脚本的代码和在实例化脚本中调用实例化函数的反应脚本。

//Instantiation
public class Thing3Instantiation : MonoBehaviour
{
    public GameObject thing3Obj;

    void Start()
    {
        //CreateThing3();
    }

    public void CreateThing3()
    {
        Instantiate(thing3Obj);
    }
}

和

//Reaction
public class Reaction : MonoBehaviour
{
    private Thing3Instatiation thing3instantiation;

    void Awake()
    {
        thing3instantiation = GetComponent<Thing3Instantiation>();
    }

    void Start()
    {
        thing3instantiation.CreateThing3();   //This line triggers the null error
    }

关于我做错了什么有什么想法吗?

【问题讨论】:

  • 错误消息应该告诉您错误是异常发生的确切行;您应该在代码示例中标记该行。
  • 另外,我要继续猜测你的Reaction 脚​​本中的空引用是transition。它是如何定义的,又是如何设置的?
  • 已编辑。 transition.CreateTransition 应该是 thing3instantiation.CreateThing3。

标签: c# function unity3d instantiation


【解决方案1】:

如果我正确理解您的设置:

  • 反应在 Thing1 上
  • Thing3Instantiation 在 Thing3 上

因此,当 Reaction唤醒 时,它会尝试在自己的游戏对象(Thing1)上找到名为 Thing3Instantiation 的组件。但它不在 Thing1 上,而在 Thing3 上,所以 GetComponent 返回 null。

因此,您的 NullReferenceException。

【讨论】:

  • 正确。但我从 Reaction 脚本调用 Thing3Instantiation 函数。我在 Reaction 脚本中创建了一个 Thing3Instantiation 类的实例。那么在调用/调用实例化函数(thing3instantiation.CreateThing3();)时,Thing3Instantiation 脚本不会接管吗?如果是这样,并且如果 Thing3 预制件附加到 Thing3Instantiation 脚本,为什么它不起作用?
  • @Siggytron 您已经创建了一个Thing3Instatiation 类型的变量,但您没有实际引用它的实例。在您的Awake 函数中,您尝试使用GetComponent 获取此引用。这就是重点:GetComponent 只搜索 Reaction 脚本所附加到的同一个游戏对象。如果Thing3Instatiation 类型的脚本不存在于与Reaction 相同的游戏对象上,GetComponent 将返回null。在你的启动函数中thing3instantiation.CreateThing3() 和调用null.CreateThing3() 一样,抛出异常。
  • 很好的解释。明白了。
【解决方案2】:

你的问题其实出在Instantiate(thing3Obj);这一行。

换句话说...当您实例化脚本时,您不会分配变量,在您的情况下为thing3Obj。无论您是否通过 Inspector 分配了它们,当 Instanciated 时,您都会获得该类的干净副本,未分配。您需要在调用之前分配它,这就是它给出 Null 异常的原因。

【讨论】:

  • 这很有趣。为什么我在 Thing3Instantiation 脚本的 Start 函数中调用 Instantiate(thing3Obj) 命令时它可以工作,但我通过从 Reaction 脚本调用实例化函数来调用它时它不起作用?
  • 另外,我将如何分配它?我会在反应脚本中创建一个公共游戏对象,就像在实例化脚本中一样,然后将预制件拖到它上面吗?所以我会让预制件同时附加反应脚本组件和实例化脚本组件?谢谢。只是想理解。
  • @Siggytron 我对您的项目仍然不完全熟悉,但是实例化脚本确实需要分配类似的值,因为 Unity 是基于组件的引擎。如果脚本不在场景中,这是正确的,那么您可以像评论中提到的那样做,或者创建一个单例类、资源文件夹等...取决于数量和使用频率。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多