Jak stworzyć nowy GameObject bez dodawania go do sceny?

10

Tworzę, co w zasadzie jest moim własnym systemem prefabrykowanym. Obiekty gry są definiowane przez plik danych czytelny dla człowieka. Chciałbym utworzyć pusty GameObject, załadować go ze składnikami zdefiniowanymi w pliku danych i przygotować go i czekać na Instantiate()połączenie. Jednak za każdym razem, gdy używam GameObject go = new GameObject()nowego obiektu, do sceny jest dodawany obiekt.

Korzystając z wbudowanych prefabrykatów Unity, mogę załadować prefabrykat jako GameObject i nie jest on dodawany do sceny. (Patrz przykład poniżej)

Uzasadnieniem tego jest chęć posiadania jednej listy zawierającej obiekty GameObject, niektóre generowane przez ładowanie prefabrykatów Unity, a inne tworzone przez mój własny system prefabrykatów. Musi się to zdarzyć w czasie wykonywania i nie może obejmować edytora Unity (ponieważ idealnie użytkownicy końcowi mogliby definiować własne pliki danych).

Jak mogę stworzyć nowy GameObject, bez Unity, który automatycznie utworzy go dla mnie?


Na przykład mogę wykonać takie połączenie:

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

I dostanę listę GameObjects, z których żaden nie jest dodawany do sceny, kiedy jest wykonywane połączenie. Zasadniczo tworzę LoadAllmetodę dla moich własnych prefabrykatów i podobnie nie chcę tworzyć instancji GameObjects podczas wykonywania połączenia.

MichaelHouse
źródło
1
Obawiam się, że nie możesz. Myślę, że będziesz musiał opóźnić instancję swojej klasy.
Roberto
Minęło trochę czasu, odkąd dotknąłem Unity, ale jeśli okaże się, że nie ma sposobu na obejście tego, czy mógłbyś po prostu usunąć obiekt ze sceny natychmiast i uzyskać pożądany efekt, tylko nieco nieefektywnie?
Kevin Reid
@KevinReid Uważam, że jedynym sposobem na to jest wywołanie DestroyGameObject. Co usuwa go ze sceny i uwalnia, co czyni go bezużytecznym.
MichaelHouse
1
@PandaPajama ma dobry pomysł. Wywołanie go.SetActive(false)jest najlepszym sposobem na utworzenie czegoś takiego jak pula obiektów. Nie jest to dokładnie to, czego chcesz, ale być może możesz mieć małą grupę nieaktywnych obiektów, które później zostaną sklonowane w celu utworzenia niestandardowej instancji.
AndrewEkeren
1
@ Byte56: Dlaczego dokładnie chcesz wstępnie utworzyć niestandardowe prefabrykaty, a nie tylko komponować system GO z wymaganymi komponentami w locie, tworząc je przy użyciu wzoru fabrycznego? Rozumiem, że chcesz pozwolić użytkownikom na serializację prefabrykatów przy użyciu „własnych plików danych”, więc i tak musisz czytać te pliki w czasie wykonywania i tworzyć wymagane komponenty. Czy czegoś brakuje?
Heisenbug

Odpowiedzi:

6

Mógłbyś zmienić hideFlags GameObject?

Właśnie próbowałem uruchomić to:

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

myGameObject.hideFlags = HideFlags.HideInHierarchy;

... i tam jest, ale nie ma go w hierarchii. Technicznie rzecz biorąc, jest na scenie, ale nie widzisz go, dopóki nie zmienisz jego flag z powrotem na HideFlags.None. Nie jest to odpowiedź, której szukasz, ale przynajmniej jeśli chodzi o udostępnienie tego programistom, jest czystsza niż grupowanie obiektów.

pochodna
źródło
1
To, w połączeniu z wyłączeniem go (aby żaden skrypt nie został wykonany), mogło działać. Spróbuję i dam ci znać. Wciąż jest to do obejrzenia, ale myślę, że na tym właśnie mi zostało. I, z tego co wiemy, może to być to, co zrobiono wewnętrznie, choć wątpię w to.
MichaelHouse
1
@ Byte56: Myślałem, że to też obejście, ale w rzeczywistości odkryłem, że Unity robi dokładnie to samo podczas podglądu animacji: tworzy instancję ukrytego obiektu gry w scenie i renderuje go w ramce podglądu za pomocą dedykowanej kamery. Może więc nie brzmi to tak czysto, ale tak naprawdę wydaje się, że to rozwiązanie jest również używane wewnętrznie.
Heisenbug
1
Przepraszam za spóźnione przyjęcie. Właśnie wdrożyłem tę implementację i działa świetnie. Dzięki.
MichaelHouse
0

Niestety nie możesz tego dokładnie zrobić. Można jednak wykonać ten sam wzorzec projektowy (tj. Wyodrębnić budynek swoich obiektów, a następnie po prostu wywołać je za pomocą jednego polecenia później) za pomocą wzorca fabrycznego .

Kiedy chcesz obiekt, zadzwoń jakoś Factory.CreateGameEntity() , a ta metoda obsłuży wszystko za kulisami.

jhocking
źródło
Jest bardziej złożony, niż mogłoby się wydawać, przez co nie jest tak czysty. Zamieszczę odpowiedź z pełnymi szczegółami, ale zasadniczo parser musi być dość złożony. Na przykład, jeśli chcę sprawdzić, czy prefabrykat ma element, przed utworzeniem instancji jest to tak proste, jak GetComponent<>() != null. W przypadku moich plików danych analizator składni musi wyszukać odpowiedni składnik w danych. To samo dotyczy uzyskiwania wartości z wnętrza komponentu i tak dalej. GameObjectKlasa udostępnia wiele funkcji, które muszą być powielane przez parser.
MichaelHouse
Jeśli możesz przedstawić dowody, a nawet uzasadnienie, dlaczego nie można tego zrobić, wypełniłbyś tę odpowiedź.
MichaelHouse
Zobaczymy później, jeśli mogę znaleźć żadnej ostatecznej dokumentacji na ten temat, na razie wszystko, co mogę znaleźć są te wątki z forum forum.unity3d.com/threads/... - answers.unity3d.com/questions/366273/... - answers.unity3d .pl / pytania / 19736 /…
jhocking
0

Nie można tego zrobić go = new GameObject();bez dodania go do sceny.

Pracuję nad RTS, w którym baza graczy musi być trwała i zasadniczo serializujemy wszystko, co zrobili, i ładujemy ją z powrotem w czasie wykonywania, używając zmodyfikowanych zasobów ze sklepu.

Większość danych wyjściowych do XML lub JSON, więc ładowanie pliku i manipulowanie nim jest dowolne.

Mrk Fldig
źródło
Dzięki Marc. Czy możesz przedstawić dowody lub uzasadnienie, że nie możesz utworzyć nowego GameObject bez dodania go do sceny? Mam własny kod serializacji, więc to nie problem, dzięki za sugestię.
MichaelHouse
-1

Właściwym sposobem jest utworzenie prefabrykatu, przydzielenie go jako obiektu, a następnie za każdym razem, gdy chcesz utworzyć instancję, po prostu użyj odwołania do tego obiektu i rzuć go jako obiekt GameObject.

np .:

private Object prefab;


public static GameObject Create(void)
{
   return (Instantiate(prefab , position , rotation) as GameObject);
}
Ericool
źródło
1
To wykorzystuje istniejący system prefabrykatów. Jak mówi moje pytanie, zasadniczo tworzę własny system prefabrykatów. Część wymagań to „nie może obejmować edytora Unity”. Do tworzenia prefabrykatów używa edytora Unity.
MichaelHouse
Nie możesz tego zrobić, musisz mieć licencję dla programisty używającego ich SDK, aby móc tworzyć własne dane. O ile się nie mylę, nie udostępnią swojego kodu bez żadnego blingowania. Ale wiem, że niektórzy ludzie byli w stanie eksportować sceny z Unity do własnego silnika gry
Ericool
Cóż, jest to wyraźnie możliwe, ponieważ stworzyłem własny system prefabrykatów, korzystając z wybranej odpowiedzi. Możesz dowiedzieć się, jak to zrobić w kursie, który utworzyłem w moim profilu.
MichaelHouse
nie, dziękuję. Jestem
dyplomowanym
Jest to system, który zasadniczo umożliwia użytkownikom końcowym wykonywanie prefabrykatów. Jest to bardzo przydatne w grach dla modów i innych treści tworzonych przez użytkowników końcowych. (Więc tak, myślę, że jest to bardzo przydatne w tworzeniu gier).
MichaelHouse
-1

Aby załadować prefabrykat do zmiennej, aby można było utworzyć go później, należy użyć następującego kodu:

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

Zrobiłem to w projekcie z Unity 5.5. Będzie dostępna do tworzenia instancji, ale nie będzie w scenie lub części hierarchii, dopóki nie zostanie utworzona w normalny sposób.

darthhawk
źródło
Czuję, że źle przeczytałeś pytanie. Ta odpowiedź wymaga użycia domyślnego systemu prefabrykatów. To pytanie dotyczy kontekstu tworzenia niestandardowego systemu prefabrykatów, w którym nie jest on dostępny. Przykład na dole służy dalszemu podkreśleniu tego.
Gnemlock,
„Jak mogę stworzyć nowy GameObject, bez Unity, który automatycznie utworzy go dla mnie?” Jest to pytanie, które zostało zadane i ten kod odpowiedział na nie. Kod można zmienić, aby uzyskać pożądane wyniki w niestandardowych systemach ładowania.
darthhawk
Zasadniczo to opisuję w przykładzie zawartym w pytaniu. I działa dobrze dla prefabrykatów, ale nie do tworzenia nowych obiektów gry z plików danych.
MichaelHouse