Como criar um novo GameObject, sem adicioná-lo à cena?

10

Estou criando o que é essencialmente meu próprio sistema pré-fabricado. Objetos de jogo são definidos por um arquivo de dados legível por humanos. Gostaria de criar um GameObject vazio, carregá-lo com os componentes definidos no arquivo de dados e tê-lo pronto e aguardando uma Instantiate()chamada. No entanto, sempre que eu uso GameObject go = new GameObject()um novo objeto de jogo é adicionado à cena.

Usando o Unity pré-fabricado, eu posso carregar um pré-fabricado como um GameObject, e ele não é adicionado à cena. (Veja o exemplo abaixo)

A lógica por trás disso é que eu gostaria de ter uma lista que contenha GameObjects, alguns gerados pelo carregamento de prefabs do Unity e outros criados pelo meu sistema de prefab personalizado. Isso precisa acontecer em tempo de execução e não pode envolver o Unity Editor (já que o ideal é que os usuários finais possam definir seus próprios arquivos de dados).

Como posso criar um novo GameObject, sem o Unity instanciando-o automaticamente para mim?


Por exemplo, eu posso fazer uma ligação assim:

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

E receberei uma lista de GameObjects, nenhum dos quais é adicionado à cena quando a chamada é feita. Essencialmente, estou criando um LoadAllmétodo para meus próprios prefabs e, da mesma forma, não quero instanciar os GameObjects quando a chamada é feita.

MichaelHouse
fonte
11
Receio que você não possa. Acho que você terá que adiar a instanciação da sua turma.
Roberto
Já faz um tempo desde que toquei no Unity, mas, se não houver uma maneira de contornar isso, você poderia remover o objeto da cena imediatamente depois e obter o resultado desejado, apenas um pouco ineficientemente?
Kevin Reid
@ KevinReid Eu acredito que a única maneira de fazer isso é chamar Destroyo GameObject. O que o remove da cena e o libera, tornando-o inutilizável.
MichaelHouse
11
@PandaPajama tem uma boa ideia. Ligar go.SetActive(false)é a melhor maneira de criar algo como um pool de objetos. Não é exatamente o que você deseja, mas talvez você possa ter um pequeno grupo de objetos inativos que são posteriormente clonados para sua instanciação personalizada.
AndrewEkeren
11
@ Byte56: Por que exatamente você deseja pré-instanciar suas pré-fabricadas personalizadas e não apenas compor o GO com os componentes necessários em tempo real enquanto os instancia usando um padrão de fábrica? Pelo que entendi, você deseja permitir que os usuários "serializem" prefabs usando "seus próprios arquivos de dados", para que você precise ler esses arquivos em tempo de execução e instanciar os componentes necessários. Estou perdendo alguma coisa?
Heisenbug

Respostas:

6

Você pode alterar o hideFlags do GameObject?

Eu apenas tentei executar isso:

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

myGameObject.hideFlags = HideFlags.HideInHierarchy;

... e está lá, mas não está na hierarquia. Tecnicamente, ele está em cena, mas você não o vê até mudar os sinalizadores de volta para HideFlags.None. Não é a resposta que você está procurando, mas pelo menos no que diz respeito a liberar isso para os desenvolvedores, é mais limpo do que agrupar seus objetos.

derivado
fonte
11
Isso, associado à desativação (para que nenhum dos scripts seja executado), poderia funcionar. Vou tentar e informá-lo. Ainda é uma solução, mas acho que é o que me resta neste momento. E, pelo que sabemos, isso pode ser o que é feito internamente, embora eu duvide.
MichaelHouse
11
@ Byte56: Pensei que fosse uma solução alternativa também, mas na verdade descobri atualmente que o Unity faz exatamente a mesma coisa ao visualizar animações: instancia o objeto oculto do jogo na cena e as exibe no quadro de visualização com uma câmera dedicada. Talvez não pareça tão limpo, mas na verdade essa solução parece ser usada também internamente.
precisa saber é o seguinte
11
Desculpe pela aceitação tardia. Acabei de implementar isso e funciona muito bem. Obrigado.
MichaelHouse
0

Você não pode fazer exatamente isso, infelizmente. No entanto, você pode realizar o mesmo padrão de design (ou seja, abstrair a construção de seus objetos e simplesmente chamá-los com um único comando posteriormente) através de um padrão de Fábrica .

Quando você quiser um objeto, chame algo como Factory.CreateGameEntity(), e esse método tratará de tudo nos bastidores.

jhocking
fonte
É mais complexo do que você imagina, porém não é tão limpo. Vou postar uma resposta com todos os detalhes, mas essencialmente o analisador deve ser bastante complexo. Por exemplo, se eu quiser testar se uma pré-fabricada possui um componente, antes de instanciar, é tão simples quanto GetComponent<>() != null. Com meus arquivos de dados, o analisador precisa procurar o componente correto nos dados. O mesmo para obter um valor de dentro de um componente e assim por diante. A GameObjectclasse fornece muitas funcionalidades que precisam ser duplicadas pelo analisador.
Michaelhouse
Se você puder fornecer evidências ou até mesmo algumas razões pelas quais isso não pode ser feito, isso tornaria a resposta completa.
Michaelhouse
Veremos mais adiante se posso encontrar alguma documentação definitiva sobre isso, por enquanto tudo o que posso encontrar são os tópicos do fórum forum.unity3d.com/threads/… - answers.unity3d.com/questions/366273/… - answers.unity3d .com / questions / 19736 /…
jhocking 22/03
0

Não há como fazê-lo go = new GameObject();sem adicioná-lo à cena.

Estou trabalhando em um RTS em que a base de jogadores precisa ser persistente e, essencialmente, serializamos tudo o que eles fizeram e carregamos de volta em tempo de execução usando ativos modificados da loja.

A maioria é impressa em XML ou JSON, por isso é bastante simples carregar o arquivo e manipulá-lo como desejar.

Mrk Fldig
fonte
Obrigado Marc. Você pode fornecer evidências ou justificativa para não conseguir criar um novo GameObject sem adicioná-lo à cena? Eu tenho meu próprio código de serialização, então isso não é problema, obrigado pela sugestão.
Michaelhouse
-1

O caminho certo é fazer uma pré-fabricada, você a aloca como um Objeto; então, sempre que quiser instanciar, use a referência desse Objeto e a projete como um GameObject.

ex:

private Object prefab;


public static GameObject Create(void)
{
   return (Instantiate(prefab , position , rotation) as GameObject);
}
Ericool
fonte
11
Isso está usando o sistema pré-fabricado existente. Como minha pergunta afirma, eu estou essencialmente criando meu próprio sistema pré-fabricado. Parte dos requisitos é "não pode envolver o Unity Editor". Criar uma casa pré-fabricada usa o Unity Editor.
MichaelHouse
Isso não é possível, você precisaria de uma licença para o desenvolvedor usar o SDK deles para poder criar seus próprios dados. A menos que eu esteja errado, eles não compartilharão seu código sem nenhum bling bling. Mas eu sei que algumas pessoas têm sido capazes de exportar cenas de Unidade para o seu próprio motor de jogo
Ericool
Bem, é claramente possível, pois eu criei meu próprio sistema de pré-fabricação usando a resposta selecionada. Você pode aprender como fazer isso no curso que criei, encontrado no meu perfil.
MichaelHouse
não, obrigado Eu sou um programador de jogos formou :) Bem, se você tiver sucesso tão grande para você, necessidade não faça isso para fazer jogos
Ericool
É um sistema que essencialmente permite que os usuários finais façam prefabs. Isso é bastante útil em jogos para mods e outros conteúdos criados pelo usuário final. (Então, sim, acho que é bastante útil na criação de jogos).
MichaelHouse
-1

Para carregar uma pré-fabricada em uma variável para instanciar mais tarde, você usaria o seguinte código:

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

Eu fiz isso em um projeto com o Unity 5.5. Ele estará disponível para instanciar, mas não na cena ou parte da hierarquia, até ser instanciado normalmente.

darthhawk
fonte
Eu sinto que você leu a pergunta errado. Esta resposta envolve o uso do sistema pré-fabricado padrão . Esta pergunta é feita no contexto da criação de um sistema pré-fabricado personalizado , onde isso não está acessível. O exemplo na parte inferior serve para destacar ainda mais isso.
Gnemlock
"Como posso criar um novo GameObject, sem o Unity instanciando-o automaticamente para mim?" É a pergunta que foi feita e este código respondeu. O código pode ser alterado para obter os resultados desejados com sistemas de carregamento personalizados.
precisa saber é o seguinte
Isso é essencialmente o que descrevo no exemplo incluído na pergunta. E funciona bem para prefabs, mas não para criar novos objetos de jogo a partir de arquivos de dados.
MichaelHouse