¿Cómo crear un nuevo GameObject, sin agregarlo a la escena?

10

Estoy creando lo que es esencialmente mi propio sistema prefabricado. Los objetos del juego están definidos por un archivo de datos legibles por humanos. Me gustaría crear un GameObject vacío, cargarlo con los componentes definidos en el archivo de datos y tenerlo listo y esperando una Instantiate()llamada. Sin embargo, cada vez que uso GameObject go = new GameObject()un nuevo objeto de juego se agrega a la escena.

Utilizando Unity integrado en prefabricados, puedo cargar un prefabricado como GameObject, y no se agrega a la escena. (Ver ejemplo a continuación)

La razón detrás de esto es que me gustaría tener una lista que contenga GameObjects, algunos generados al cargar prefabricados de Unity y otros creados por mi sistema de prefabricados personalizado. Esto debe suceder en tiempo de ejecución y no puede involucrar al Editor de Unity (ya que, idealmente, los usuarios finales podrían definir sus propios archivos de datos).

¿Cómo puedo crear un nuevo GameObject, sin que Unity lo instale automáticamente?


Por ejemplo, puedo hacer una llamada como esta:

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

Y obtendré una lista de GameObjects, ninguno de los cuales se agrega a la escena cuando se realiza la llamada. Esencialmente, estoy creando un LoadAllmétodo para mis propios prefabricados, y del mismo modo, no quiero instanciar los GameObjects cuando se realiza la llamada.

MichaelHouse
fuente
1
Me temo que no puedes. Creo que tendrás que retrasar la creación de instancias de tu clase.
Roberto
Ha pasado un tiempo desde que toqué Unity, pero si resulta que no hay forma de evitar esto, ¿podrías eliminar el objeto de la escena inmediatamente después y obtener el resultado deseado, solo un poco ineficiente?
Kevin Reid
@KevinReid Creo que la única forma de hacerlo es llamar Destroyal GameObject. Lo que lo elimina de la escena y lo libera, haciéndolo inutilizable.
MichaelHouse
1
@PandaPajama tiene una buena idea. Llamar go.SetActive(false)es la mejor manera de crear algo así como un grupo de objetos. No es exactamente lo que desea, pero quizás podría tener un pequeño grupo de objetos inactivos que luego se clonarán para su instanciación personalizada.
AndrewEkeren
1
@ Byte56: ¿Por qué exactamente desea crear una instancia previa de sus prefabricados personalizados y no solo componer el GO con los componentes necesarios sobre la marcha mientras los instancia usando un patrón similar al de fábrica? Por lo que he entendido, desea permitir que los usuarios "serialicen" prefabricados utilizando "sus propios archivos de datos", por lo que debe leer esos archivos en tiempo de ejecución de todos modos e instanciar los componentes necesarios ... ¿Me estoy perdiendo algo?
Heisenbug

Respuestas:

6

¿Podrías cambiar las hideFlags de GameObject?

Acabo de intentar ejecutar esto:

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

myGameObject.hideFlags = HideFlags.HideInHierarchy;

... y está ahí, pero no está en la jerarquía. Técnicamente, está en la escena, pero no lo ves hasta que cambias sus banderas a HideFlags. Ninguno. No es la respuesta que está buscando, pero al menos en lo que respecta a lanzar esto a los desarrolladores, es más limpio que agrupar sus objetos.

derivado
fuente
1
Esto, junto con deshabilitarlo (para que ninguno de los scripts se ejecute), podría funcionar. Lo intentaré y te lo haré saber. Todavía es una solución, pero creo que eso es lo que me queda en este momento. Y, por lo que sabemos, esto podría ser lo que se hace internamente, aunque lo dudo.
MichaelHouse
1
@ Byte56: Pensé que también era una solución alternativa, pero en realidad descubrí en estos días que Unity hace exactamente lo mismo al previsualizar animaciones: crea una instancia de un objeto de juego oculto en la escena y los muestra en el marco de vista previa con una cámara dedicada. Entonces, tal vez no suene tan limpio, pero en realidad esta solución parece usarse también internamente.
Heisenbug
1
Perdón por el retraso aceptar. Acabo de implementar esto y funciona muy bien. Gracias.
MichaelHouse
0

No puedes hacer eso exactamente, desafortunadamente. Sin embargo, puede lograr el mismo patrón de diseño (es decir, abstraer la construcción de sus objetos y luego simplemente llamarlos con un solo comando más adelante) a través de un patrón Factory .

Cuando desee un objeto, llame a algo así Factory.CreateGameEntity(), y ese método manejará todo detrás de escena.

jhocking
fuente
Sin embargo, es más complejo de lo que piensas, por lo que no es tan limpio. Publicaré una respuesta con todos los detalles, pero esencialmente el analizador debe ser bastante complejo. Por ejemplo, si quiero probar si un prefab tiene un componente, antes de crear una instancia, es tan simple como GetComponent<>() != null. Con mis archivos de datos, el analizador tiene que buscar el componente correcto en los datos. Lo mismo para obtener un valor desde el interior de un componente, y así sucesivamente. La GameObjectclase proporciona una gran cantidad de funcionalidades que el analizador debe duplicar.
MichaelHouse
Si puede proporcionar evidencia o incluso alguna razón de por qué esto no se puede hacer, esta respuesta sería completa.
MichaelHouse
Veré más adelante si puedo encontrar alguna documentación definitiva sobre esto, por ahora todo lo que puedo encontrar son estos hilos del foro forum.unity3d.com/threads/… - answers.unity3d.com/questions/366273/… - answers.unity3d .com / preguntas / 19736 / ...
jhocking
0

No hay forma de hacerlo go = new GameObject();sin agregarlo a la escena.

Estoy trabajando en un RTS donde la base de jugadores debe ser persistente, y esencialmente, serializamos todo lo que han hecho y lo cargamos nuevamente en tiempo de ejecución utilizando activos modificados de la tienda.

La mayoría sale a XML o JSON, por lo que es bastante sencillo cargar el archivo y manipularlo como desee.

Mrk Fldig
fuente
Gracias Marc ¿Puede proporcionar evidencia o justificación para no poder crear un nuevo GameObject sin agregarlo a la escena? Tengo mi propio código de serialización, así que no es un problema, gracias por la sugerencia.
MichaelHouse
-1

La forma correcta es hacer un prefab, asigna ese prefab como un Objeto, luego, cuando quieras crear una instancia, solo usa la referencia de este Objeto y vuélvelo como un GameObject.

ex:

private Object prefab;


public static GameObject Create(void)
{
   return (Instantiate(prefab , position , rotation) as GameObject);
}
Ericool
fuente
1
Eso está usando el sistema prefabricado existente. Como dice mi pregunta, esencialmente estoy creando mi propio sistema prefabricado. Parte de los requisitos son "no puede involucrar al Editor de Unity". Crear un prefabricado usa el Editor de Unity.
MichaelHouse
Si no puede hacerlo, necesitaría una licencia para que el desarrollador utilice su SDK para poder crear sus propios datos. A menos que me equivoque, no compartirán su código sin ningún bling bling. Pero sé que algunas personas han podido exportar escenas de Unity a su propio motor de juego
Ericool,
Bueno, es claramente posible ya que creé mi propio sistema prefabricado usando la respuesta seleccionada. Puedes aprender cómo hacerlo en el curso que creé, que se encuentra en mi perfil.
MichaelHouse
no gracias Soy un programador de juegos graduado :) Bueno, si tienes éxito así de genial para ti, no lo necesitas para hacer juegos
Ericool
Es un sistema que esencialmente permite a los usuarios finales hacer prefabricados. Esto es bastante útil en juegos para modificaciones y otros contenidos creados por el usuario final. (Entonces sí, creo que es bastante útil para hacer juegos).
MichaelHouse
-1

Para cargar un prefab en una variable para poder instanciarlo más tarde, usaría el siguiente código:

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

Lo hice en un proyecto con Unity 5.5. Estará disponible para crear instancias, pero no en la escena o parte de la jerarquía hasta que se cree una instancia normal.

Darthhawk
fuente
Siento que has leído mal la pregunta. Esta respuesta implica el uso del sistema prefabricado predeterminado . Esta pregunta se hace en el contexto de la creación de un sistema prefabricado personalizado , donde esto no es accesible. El ejemplo en la parte inferior sirve para resaltar aún más esto.
Gnemlock
"¿Cómo puedo crear un nuevo GameObject, sin que Unity lo instale automáticamente?" Es la pregunta que se hizo y este código la respondió. El código puede modificarse para obtener los resultados deseados con sistemas de carga personalizados.
Darthhawk
Esto es esencialmente lo que describo en el ejemplo incluido en la pregunta. Y funciona bien para prefabricados, pero no para crear nuevos objetos de juego a partir de archivos de datos.
MichaelHouse