Как создать новый 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

1
@ Byte56: Почему именно вы хотите предварительно создавать экземпляры своих пользовательских префабов, а не просто создавать GO с необходимыми компонентами на лету, создавая их с использованием фабричного шаблона? Насколько я понял, вы хотите разрешить пользователям «сериализовать» префабы, используя «их собственные файлы данных», так что вы все равно должны читать эти файлы во время выполнения и создавать экземпляры необходимых компонентов… Я что-то упустил?
Heisenbug

Ответы:


6

Вы могли бы изменить hideFlags GameObject?

Я просто попытался запустить это:

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 /…
jhocking

0

Нет способа обойтись go = new GameObject();без добавления этого на сцену.

Я работаю над RTS, где база игроков должна быть постоянной, и, по сути, мы сериализуем все, что они сделали, и загружаем его обратно во время выполнения, используя измененные ресурсы из магазина.

Большая часть выводится в XML или JSON, поэтому довольно просто загрузить файл и манипулировать им, как вы хотите.


Спасибо Марк. Можете ли вы предоставить доказательства или обоснование невозможности создания нового GameObject без добавления его на сцену? У меня есть собственный код сериализации, так что это не проблема, спасибо за предложение.
MichaelHouse

-1

Правильный способ состоит в том, чтобы создать префаб, вы выделяете этот префаб как объект, а затем, когда хотите создать экземпляр, просто используйте ссылку на этот объект и приводите его в качестве GameObject.

пример:

private Object prefab;


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

1
Это с использованием существующей сборной системы. Как говорится в моем вопросе, я по сути создаю свою собственную сборную систему. Часть требований «не может включать Unity Editor». Для создания префаба используется редактор Unity.
MichaelHouse

Что вы не можете сделать, вам понадобится лицензия для разработчика, использующего их SDK, чтобы затем иметь возможность создавать свои собственные данные. Если я не ошибаюсь, они не будут делиться своим кодом без всяких проблем. Но я знаю, что некоторые люди смогли экспортировать сцены из Unity в собственный игровой движок
Ericool

Ну, это вполне возможно, так как я создал свою собственную сборную систему, используя выбранный ответ. Вы можете узнать, как это сделать, в курсе, который я создал, в моем профиле.
MichaelHouse

нет, спасибо, я дипломированный программист игр :) Что ж, если вам это удастся, вам не нужно делать игры
Ericool

Это система, которая, по сути, позволяет конечным пользователям создавать префабы. Это очень полезно в играх для модов и другого контента, созданного конечным пользователем. (Так что да, я думаю, что это довольно полезно при создании игр).
MichaelHouse

-1

Чтобы загрузить префаб в переменную, чтобы вы могли создать его экземпляр позже, вы должны использовать следующий код:

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

Я сделал это в проекте с Unity 5.5. Он будет доступен для создания экземпляра, но не в сцене или части иерархии, пока не будет создан как обычно.


Я чувствую, что вы прочитали вопрос неправильно. Этот ответ предполагает использование стандартной сборной системы. Этот вопрос задается в контексте создания пользовательской сборной системы, где это недоступно. Пример внизу служит для дальнейшего выделения этого.
Гнемлок

«Как я могу создать новый GameObject, без Unity, автоматически создающего его для меня?» Является ли вопрос, который был задан, и этот код ответил на него. Код может быть изменен для получения желаемых результатов с помощью пользовательских систем загрузки.
Дартхок

По сути, это то, что я описываю в примере, включенном в вопрос. И это прекрасно работает для сборных конструкций, но не для создания новых игровых объектов из файлов данных.
MichaelHouse
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.