Come creare un nuovo GameObject, senza aggiungerlo alla scena?


10

Sto creando quello che è essenzialmente il mio sistema prefabbricato. Gli oggetti di gioco sono definiti da un file di dati leggibile dall'uomo. Vorrei creare un GameObject vuoto, caricarlo con i componenti definiti nel file di dati e averlo pronto e in attesa di una Instantiate()chiamata. Tuttavia, ogni volta che uso GameObject go = new GameObject()un nuovo oggetto di gioco viene aggiunto alla scena.

Utilizzando i prefabbricati integrati di Unity, posso caricare un prefabbricato come GameObject e non viene aggiunto alla scena. (Vedi esempio sotto)

La logica alla base di questo è che vorrei avere un elenco che contiene GameObjects, alcuni generati caricando i prefabbricati Unity e altri creati dal mio sistema prefabbricato personalizzato. Questo deve avvenire in fase di esecuzione e non può coinvolgere l'Editor Unity (poiché idealmente gli utenti finali sarebbero in grado di definire i propri file di dati).

Come posso creare un nuovo GameObject, senza che Unity lo installi automaticamente per me?


Ad esempio, posso effettuare una chiamata in questo modo:

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

E otterrò un elenco di GameObjects, nessuno dei quali viene aggiunto alla scena quando viene effettuata la chiamata. In sostanza, sto creando un LoadAllmetodo per i miei prefabbricati e allo stesso modo, non voglio creare un'istanza di GameObjects quando viene effettuata la chiamata.


1
Ho paura che non puoi. Penso che dovrai ritardare l'istanza della tua classe.
Roberto

È passato un po 'di tempo da quando ho toccato Unity, ma se si scopre che non c'è un modo per aggirare questo, potresti semplicemente rimuovere l'oggetto dalla scena immediatamente dopo e avere il risultato desiderato, solo leggermente inefficiente?
Kevin Reid,

@KevinReid Credo che l'unico modo per farlo sia chiamare DestroyGameObject. Il che lo rimuove dalla scena e lo rilascia, rendendolo inutilizzabile.
MichaelHouse

1
@PandaPajama ha una buona idea. La chiamata go.SetActive(false)è il modo migliore per creare qualcosa come un pool di oggetti. Non è esattamente quello che vuoi, ma forse potresti avere un piccolo gruppo di oggetti inattivi che verranno successivamente clonati per la tua istanza personalizzata.
AndrewEkeren,

1
@ Byte56: Perché esattamente vuoi pre-istanziare i tuoi prefabbricati personalizzati e non comporre semplicemente il GO con i componenti richiesti al volo mentre li crei un'istanza usando un modello di fabbrica? Per quello che ho capito, vuoi consentire agli utenti di "serializzare" i prefabbricati usando "i propri file di dati", quindi devi comunque leggere quei file in fase di esecuzione e creare un'istanza dei componenti richiesti. Mi sto perdendo qualcosa?
Heisenbug

Risposte:


6

Potresti cambiare il hideFlags di GameObject?

Ho appena provato a eseguire questo:

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

myGameObject.hideFlags = HideFlags.HideInHierarchy;

... ed è lì, ma non è nella gerarchia. Tecnicamente, è nella scena, ma non lo vedi fino a quando non cambi le sue bandiere in HideFlags.Nessuno. Non è la risposta che stai cercando, ma almeno per quanto riguarda il rilascio di questo agli sviluppatori, è più pulito del raggruppamento dei tuoi oggetti.


1
Questo, associato alla disabilitazione (quindi nessuno degli script eseguiti), potrebbe funzionare. Ci proverò e ti farò sapere. È ancora un lavoro in giro, ma penso che sia quello che mi rimane a questo punto. E, per quanto ne sappiamo, questo potrebbe essere ciò che viene fatto internamente, anche se ne dubito.
MichaelHouse

1
@ Byte56: ho pensato che fosse anche una soluzione alternativa, ma in realtà ho scoperto in questi giorni che Unity fa esattamente la stessa cosa durante l'anteprima delle animazioni: crea un'istanza di oggetto di gioco nascosto nella scena e li rende nel riquadro di anteprima con una fotocamera dedicata. Quindi forse non sembra così pulito, ma in realtà questa soluzione sembra essere utilizzata anche internamente.
Heisenbug,

1
Ci scusiamo per il ritardo accettare. Ho appena iniziato a implementarlo e funziona benissimo. Grazie.
MichaelHouse

0

Sfortunatamente non puoi fare quella cosa esatta. Tuttavia, puoi realizzare lo stesso modello di progettazione (ad es. Allontanare la costruzione dei tuoi oggetti, e poi semplicemente chiamarli con un singolo comando in seguito) attraverso un modello di Fabbrica .

Quando vuoi un oggetto, chiama qualcosa del genere Factory.CreateGameEntity()e quel metodo gestirà tutto dietro le quinte.


È più complesso di quanto si possa pensare, rendendolo non così pulito. Pubblicherò una risposta con tutti i dettagli, ma essenzialmente il parser deve essere piuttosto complesso. Ad esempio, se voglio verificare se un prefabbricato ha un componente, prima di creare un'istanza, è semplice come GetComponent<>() != null. Con i miei file di dati, il parser deve cercare il componente corretto nei dati. Lo stesso vale per ottenere un valore dall'interno di un componente e così via. La GameObjectclasse fornisce molte funzionalità che devono essere duplicate dal parser.
MichaelHouse

Se sei in grado di fornire prove o anche alcune motivazioni del perché ciò non può essere fatto, renderebbe completa questa risposta.
MichaelHouse

Vedrò poi se riesco a trovare alcuna documentazione definitiva su questo, per ora tutto quello che posso trovare sono queste discussioni nel forum forum.unity3d.com/threads/... - answers.unity3d.com/questions/366273/... - answers.unity3d .com / questions / 19736 /…
jhocking

0

Non c'è modo di fare go = new GameObject();senza aggiungerlo alla scena.

Sto lavorando su un RTS in cui la base del giocatore deve essere persistente e, essenzialmente, serializziamo tutto ciò che hanno fatto e lo ricarichiamo in fase di esecuzione utilizzando le risorse modificate dal negozio.

La maggior parte dell'output in XML o JSON è quindi abbastanza semplice caricare il file e manipolarlo come desideri.


Grazie Marc. Potete fornire prove o motivazioni per non essere in grado di creare un nuovo GameObject senza aggiungerlo alla scena? Ho il mio codice di serializzazione, quindi non è un problema, grazie per il suggerimento.
MichaelHouse

-1

Il modo giusto è realizzare un prefabbricato, allocare quel prefabbricato come un oggetto, quindi ogni volta che si desidera creare un'istanza basta usare il riferimento di questo oggetto e lanciarlo come GameObject.

es:

private Object prefab;


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

1
Sta usando il sistema prefabbricato esistente. Come afferma la mia domanda, sto essenzialmente creando il mio sistema prefabbricato. Parte dei requisiti sono "impossibile coinvolgere l'Editor Unity". La creazione di un prefabbricato utilizza Unity Editor.
MichaelHouse

Ciò che non puoi fare, avrai bisogno di una licenza per lo sviluppo tramite SDK per poter creare i tuoi dati. A meno che non mi sbagli, non condivideranno il loro codice senza alcun bling bling. Ma so che alcune persone sono state in grado di esportare scene da Unity sul proprio motore di gioco
Ericool,

Bene, è chiaramente possibile da quando ho creato il mio sistema prefabbricato usando la risposta selezionata. Puoi imparare come farlo nel corso che ho creato, trovato nel mio profilo.
MichaelHouse

no grazie sono un programmatore di giochi laureato :) Beh, se riesci così bene per te, non ne ho bisogno per fare giochi
Ericool

È un sistema che essenzialmente consente agli utenti finali di realizzare prefabbricati. Questo è piuttosto utile nei giochi per mod e altri contenuti creati dagli utenti finali. (Quindi sì, penso che sia abbastanza utile nel creare giochi).
MichaelHouse

-1

Per caricare un prefabbricato in una variabile in modo da poterlo istanziare in un secondo momento, utilizzare il seguente codice:

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

L'ho fatto in un progetto con Unity 5.5. Sarà disponibile per istanziare ma non nella scena o parte della gerarchia fino a quando non viene istanziato normalmente.


Sento che hai letto la domanda in modo sbagliato. Questa risposta implica l'utilizzo del sistema prefabbricato predefinito . Questa domanda pone nel contesto della creazione di un sistema prefabbricato personalizzato , dove questo non è accessibile. L'esempio in basso serve a evidenziarlo ulteriormente.
Gnemlock

"Come posso creare un nuovo GameObject, senza che Unity lo installi automaticamente per me?" È la domanda che è stata posta e questo codice ha risposto. Il codice può essere modificato per ottenere i risultati desiderati con i sistemi di caricamento personalizzati.
Darthhawk,

Questo è essenzialmente ciò che descrivo nell'esempio incluso nella domanda. E funziona benissimo per i prefabbricati, ma non per creare nuovi oggetti di gioco da file di dati.
MichaelHouse
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.