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