Estou criando um pequeno jogo de defesa de torre para me familiarizar com a unidade.
No começo, eu ia imitar um sistema de grade capturando toques / cliques do mouse e arredondando as coordenadas para o número inteiro mais próximo. Isso tem um custo muito baixo e funciona bem para colocar as coisas, no entanto, eu sou um pouco nerd de IA e decidi criar uma grade mais tangível para que os agentes possam executar pesquisas nela para encontrar o caminho.
Para isso, precisarei de uma grade de nós e para que esses nós tenham um pouco de informação anexada. Seria uma ideia muito melhor fazer isso inteiramente em código? Ou eu poderia me safar colocando cubos reais em uma grande grade no mapa?
Isso certamente seria fácil, pois então eu poderia lançar raios contra eles - mas eu tentei isso e tornei muitos cubos atrasando muito o jogo!
Suponho que minha pergunta é - é desnecessariamente caro ter uma carga de cubos configurados assim, mas não renderizados? Ou o custo de ter uma carga de volumes de colisão em forma de cubo deve ser apenas marginalmente mais caro do que imitar isso no código? (se houver ...)
Também como uma questão paralela - eu deveria ser capaz de render, digamos, 200 cubos e ter um jogo tranquilo? Estou faltando algumas opções de instanciamento? Eu presumi que as coisas seriam instanciadas automaticamente.
Respostas:
Vou atacar sua pergunta fora de ordem, em parte porque estou tendo problemas com a maneira como acho que você está atacando o problema.
Não sei por que isso seria lento, a menos que você esteja constantemente criando, alterando e destruindo esses cubos em tempo de execução, mas mesmo assim 200 cubos são brincadeira de criança em unidade (quando você começa a dizer 10.000 itens de interação simultânea, A unidade pode começar a ter problemas.
Você não precisa ter "objetos" físicos em seu mundo para transmitir raios entre eles. você simplesmente precisa ter objetos no seu mundo (Empty GameObjects)
200 cubos (até 200 RigidBodies) não são tanto no Unity. a parte sobre a emulação de código depende do que você absolutamente precisa que seus nós saibam.
instanciar no Unity é baseado no sistema pré-fabricado (basicamente faça suas coisas, crie uma pré-fabricada e use-a novamente e novamente em seus jogos / cenas)
se você pode mascarar todo o seu nível / cena do jogo em uma grade fixa, você deve, em teoria, usar a travessia padrão da grade, mas toda a sua contabilidade provavelmente precisará ser centrada especificamente em valores, e no final, isso não vai dar certo ser muito limpo / eficiente.
sim, não, talvez dependa de quais informações você absolutamente precisa de seus nós (o nó mais simples que consigo pensar em um jogo de defesa de torre é um ponto, um bool ocupado e um bool acessível)
Por que você faria isso? Não vejo nenhum valor além de ter algo que você pode ver fisicamente no editor e, quando chegar a hora de executar o jogo, você não fará nada com esses truques como cubos; então, por que tê-los em primeiro lugar, se você apenas precisa afastar sua colisão e renderização. Tudo o que resta é uma transformação que você poderia ter imediatamente ao ter gameObjects vazios.
a maneira mais fácil de criar nós no Unity é criar gameObjects vazios (principalmente para a posição) e, em seguida, fornecer a eles um script para todas as variáveis necessárias e, em seguida, colocar todos esses nós em sua própria camada.
EDIT (Em resposta ao pedido de mais detalhes no comentário):
sim e não. sim, é o mesmo em termos de física e renderização, mas não em termos de contabilidade. a cada FixedUpdate (especialmente no modo sem liberação), o sistema pega todos os componentes que um objeto possui, e o mesmo para seus filhos, e os coloca a serem calculados; se algum deles não estiver ativo, o joga fora. então ainda está tentando fazer coisas com os componentes inativos, não é tanto assim. se você multiplicar isso o suficiente, pode chegar a meio segundo extra por quadro, mas isso provavelmente está lá em cima.
Não. Do ponto de vista do aplicativo, pense em um gameObject vazio como um modificador que está modificando algo ou nada. Posso criar um gameObject vazio e, em seguida, movê-lo pelo mundo / cena, e depois girá-lo e escalá-lo, mas se ele não tiver filhos, nada acontece, mas as alterações são registradas. então, se eu pegar e criar uma esfera, e torná-lo filho desse gameObject vazio, esse filho aceitará essas modificações e terá seus próprios valores armazenados em relação ao pai, mas na essência da lógica física esse gameObject vazio é nada (sem tamanho, forma ou qualquer coisa), mas tem uma transformação e pode receber componentes.
seu direito a um ponto. quando digo a palavra grade, a maioria das pessoas pensa em desenhar caixas e ter todas essas caixas com dimensões uniformes, mas quando colocamos coisas nessas caixas, tudo o que realmente importa é um ponto no espaço (geralmente o centro de 3D, mas para sprites 2D no canto superior esquerdo), se tirarmos as caixas e, em vez disso, apenas mantermos esses pontos no espaço, ainda temos uma grade, simplesmente não temos caixas.
Você ainda pode usar todos os seus algoritmos de busca de caminho favoritos com pontos / nós que fez com uma grade e muito mais. Calcule a distância entre eles e aplique um peso a essa distância (dijoksra e A *), permita que o agente considere a multiplicação de nós de uma só vez (lógica nebulosa), rastreie os movimentos dos jogadores através de um padrão de grade definido e depois dê um peso a um conjunto de regras que correspondem e, em seguida, peça ao agente que escolha uma resposta com base no peso mais alto (exercer sistemas).
Uma grade é apenas uma representação visual que o player nunca pode ver (a menos que você realmente queira desenhar essas caixas na tela, em 2D, ok, mas se você estiver em uma perspectiva 3D, isso pode ficar confuso rapidamente, especialmente se a câmera puder girar).
Eu quis dizer que cada agente tenha que fazer o mesmo arredondamento que você faz para os cliques do mouse, que é muito centrado em valor, e você acaba tendo que fazer o mesmo trabalho de limpeza de valores codificados, e você obtém o mesmo fim executar verificações como ao fazer
if(X>300){//do something}
. mas se você encontrar apenas os nós mais próximos daqui (depende de você se desejar diagonais), e se você realmente quiser, poderá usar a mesma lógica para cliques do mouse, em vez de arredondar valores, apenas transmitir raios para encontrar o nó mais próximo .fonte