如何创建一个新的GameObject,而不将其添加到场景中?


10

我正在创建本质上是我自己的预制系统。游戏对象是由人类可读的数据文件定义的。我想创建一个空的GameObject,将其加载到数据文件中定义的组件中,并准备好等待Instantiate()调用。但是,每当我使用GameObject go = new GameObject()新游戏对象时,都会将其添加到场景中。

使用内置在预制件中的Unity,我可以将预制件作为GameObject加载,并且不会将其添加到场景中。(请参见下面的示例)

这背后的基本原理是我希望有一个包含GameObjects的列表,其中一些是通过加载Unity预制件生成的,而另一些是由我的自定义预制系统创建的。这需要在运行时发生,并且不能涉及Unity编辑器(因为理想情况下,最终用户将能够定义自己的数据文件)。

如何创建一个新的GameObject,而Unity却没有自动为我实例化它?


例如,我可以这样拨打电话:

Resources.LoadAll("PrefabsDirectory", typeof(GameObject))

然后,我将获得一个GameObjects列表,在进行调用时,这些列表都不会添加到场景中。本质上,我正在LoadAll为自己的预制件创建方法,同样,我不想在调用时实例化GameObjects。


1
恐怕你做不到。我认为您必须延迟类的实例化。
罗伯托

自从我接触Unity以来已经有一段时间了,但是如果事实证明没有办法解决,您可以在此之后立即将对象从场景中移除并获得所需的结果吗?
凯文·里德

@KevinReid我相信唯一的方法就是调用DestroyGameObject。它将其从场景中删除并释放,使其无法使用。
MichaelHouse

1
@PandaPajama有一个好主意。调用go.SetActive(false)是创建对象池之类的最佳方法。这并不是您想要的,但是也许您可以有一小部分不活动的对象,这些对象随后将被克隆以进行自定义实例化。
AndrewEkeren 2014年

1
@ Byte56:为什么您确实想预先实例化您的定制预制件,而不仅仅是在运行时将所需的组件与GO一起组成,同时使用类似工厂的模式实例化它们?据我了解,您希望允许用户使用“他们自己的数据文件”对预制件进行“序列化”,因此无论如何您都必须在运行时读取这些文件并实例化所需的组件。
Heisenbug 2014年

Answers:


6

您可以更改GameObject的hideFlags吗?

我只是尝试运行此:

GameObject myGameObject = new GameObject ();
myGameObject.name = "Obvious Name";

myGameObject.hideFlags = HideFlags.HideInHierarchy;

...并且在那里,但是它不在层次结构中。从技术上讲,它在场景中,但是直到将其标志更改回HideFlags.None时您才看到它。这不是您要寻找的答案,但至少就将其发布给开发人员而言,它比对您的对象进行分组更清洁。


1
这与禁用它(因此没有脚本执行)配合使用,可以起作用。我会尝试的,并让您知道。仍然需要解决,但是我认为这就是我剩下的。而且,就我们所知,这可能是内部完成的工作,尽管我对此表示怀疑。
MichaelHouse

1
@ Byte56:我也坚信这也是一种解决方法,但实际上我最近发现,Unity在预览动画时做的事情完全相同:它实例化场景中隐藏的游戏对象,并使用专用摄像机将其渲染到预览帧中。因此,听起来可能不太干净,但实际上,该解决方案似乎也在内部使用。
Heisenbug

1
对不起,迟到了。我刚刚开始实施它,效果很好。谢谢。
MichaelHouse

0

不幸的是,您无法做到这一点。但是,您可以通过Factory模式完成相同的设计模式(即,抽象出对象的构造,然后稍后再用单个命令调用它们)。

当您需要一个对象时,调用,如Factory.CreateGameEntity(),该方法将处理所有幕后操作。


它比您想像的还要复杂,使其不那么干净。我将发布一个包含所有细节的答案,但从本质上讲,解析器必须非常复杂。例如,如果我要测试预制件是否具有组件,则在实例化之前,它就像一样简单GetComponent<>() != null。对于我的数据文件,解析器必须在数据中搜索正确的组件。从组件内部获取值等相同。本GameObject类提供了很多的功能,需要由解析器被复制。
MichaelHouse

如果您可以提供证据甚至无法解释为什么无法做到这一点,那么它将使此答案完整。
MichaelHouse

后来我去看看我能找到这方面有任何明确的文档中,现在我能看到的是这些论坛主题forum.unity3d.com/threads/... - answers.unity3d.com/questions/366273/... - answers.unity3d .com / questions / 19736 /…
凌晨16

0

go = new GameObject();不将其添加到场景中是没有办法的。

我正在开发一个RTS,玩家需要保持持久性,实质上,我们序列化他们所做的一切,并使用商店中的修改资产在运行时将其重新加载。

大多数输出​​为XML或JSON,因此很容易直接加载文件并根据需要进行操作。


谢谢马克。您能否提供证据或理由说明如果不将其添加到场景中就无法创建新的GameObject?我有自己的序列化代码,因此这不是问题,感谢您的建议。
MichaelHouse

-1

正确的方法是制作一个预制件,将该预制件分配为一个Object,然后每当要实例化时,只需使用此Object的引用并将其转换为GameObject即可。

例如:

private Object prefab;


public static GameObject Create(void)
{
   return (Instantiate(prefab , position , rotation) as GameObject);
}

1
那是使用现有的预制系统。正如我的问题所述,我实际上是在创建自己的预制系统。部分要求是“不能涉及Unity编辑器”。使用Unity编辑器创建预制件。
MichaelHouse

您不能做的是,您需要使用他们的SDK的开发人员许可证,然后才能制作自己的数据。除非我错了,否则他们不会共享自己的代码。但是我知道有些人已经能够将场景从Unity导出到他们自己的游戏引擎
Ericool

好吧,因为我确实使用所选答案创建了自己的预制系统,所以这很可能。您可以在个人资料中找到的我创建的课程中学习如何做。
MichaelHouse

不用了,谢谢,我是一位毕业于游戏的程序员:)好吧,如果您成功了,那么就不需要它来制作游戏了
Ericool 2015年

这是一个基本上允许最终用户制造预制件的系统。这在Mod和其他最终用户创建的内容的游戏中非常有用。(所以,我认为这在制作游戏中非常有用)。
MichaelHouse

-1

要将预制件加载到变量中,以便以后可以实例化,请使用以下代码:

 GameObject ball = (GameObject)(Resources.Load ("myPrefab"));

我已经在Unity 5.5的项目中做到了这一点。可以实例化,但不能在场景或层次结构的一部分中实例化,直到正常实例化为止。


我觉得您读错了这个问题。该答案涉及使用默认的预制系统。这个问题是在创建定制的预制系统的环境中提出的,在该系统中无法访问。底部的示例进一步突出了这一点。
Gnemlock

“如何创建一个新的GameObject,而Unity不会自动为我实例化它?” 是被问到的问题,此代码已回答它。可以更改代码以获得定制加载系统所需的结果。
darthhawk

这本质上就是我在问题中包含的示例中描述的内容。对于预制件来说,它很好用,但是对于从数据文件中创建新的游戏对象而言,它却不是。
MichaelHouse
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.