Transcrições
1. Introdução ao curso: Ei, pessoal, Chris, aqui. E neste vídeo, eu
tenho algo muito legal. Estou animado para
compartilhar com todos vocês. É meu novo curso de
desenvolvimento do GidoGame para criar um jogo semelhante ao de um
sobrevivente Então, temos muito
conteúdo lá dentro. Quer dizer, são mais de 60 aulas e quase 12 horas de vídeo. De longe, é o
curso de desenvolvimento de jogos
mais longo e completo que eu já lancei. Então, se você já pensou criar seu próprio jogo divertido
Survivors Light, é exatamente
isso que
vamos fazer Vamos construí-lo passo a
passo, do zero. Usaremos a versão 4.4 do
GidoEngine, que você provavelmente já
sabe que é gratuita e de código aberto Então, vamos codificar tudo
no script GD. Que é a linguagem
criada especificamente para o editor Gadot É amigável para iniciantes,
fácil de ler e totalmente
integrado ao motor ado Então, funciona de forma fantástica para fazer
protótipos de jogos como esse Então, se você é novato desenvolvimento de
jogos ou
já programou um pouco e quer realmente solidificar suas habilidades com um novo projeto
interessante, acho que este curso
será para Começaremos de forma simples, nos
familiarizando com o essencial, como a movimentação de personagens de cima
para baixo Então, vamos realmente
começar a aprimorá-lo, desenvolvendo alguns conceitos
genuinamente complexos Você adicionará estatísticas
de personagens, sistemas de
nivelamento, coleta de itens e até criaremos
um sistema de desova que posicionará todos os
seus inimigos fora da tela para que eles
possam atacar o jogador por todos os lados Então, em poucas palavras,
vamos
realmente experimentar o sistema de cena
Godos two D. Isso abrangerá todo o
resto, desde projéteis até a criação de interfaces de usuário
sofisticadas Ao final do
curso, você terá sobreviventes totalmente jogáveis, como
um protótipo de
jogo visto
em segundo plano e
todo o conhecimento necessário para transformá-lo em Então, o que você diz?
Você está pronto para transformar essas ideias de jogo
em algo real? Venha se juntar a mim no
curso e vamos construir algo
incrível juntos.
2. Configuração do projeto no Godot: Olá pessoal, Chris
aqui, neste vídeo, começaremos
com a primeira etapa
do nosso projeto Survivors Like e GD Script
baixando o GDOEngine Se você ainda não
sabe, o Gadot é um mecanismo de
jogo gratuito de código aberto que tem sua própria linguagem principal, GD Script, escrito
especificamente para o Gdo, que é o que vamos usar para
codificar É uma linguagem de script. Você pode, é claro,
usar outras linguagens em Deus, como C Sharp, que tem um forte
suporte embutido com uma
conversão do A maioria dos tutoriais que você
encontrará estará em
GDScript porque o GD Script é
rápido para começar GDScript porque o GD Script é
rápido Tem uma integração muito boa
com o Editor EUI. É fácil de usar e
você não precisa
compilar seus scripts toda vez que quiser
fazer alterações nele Então, no que diz respeito à simplicidade, especialmente para pequenos projetos, GD Script tem
muito a seu favor Então, olhando para o site do Gado, vou usar a versão
atual do Gado 4.4 0.1. Especificamente, vou
baixar a versão não mono, que significa que não tem suporte para
C Sharp porque
a versão exclusiva do GD Script permite
que você exporte para a web Mas se você usa o Gado Mono, esse recurso não é suportado Então, o Gadot 4.5 já está
sendo lançado, e há alguns recursos que eu acho muito
legais sendo lançados Mas como estamos
tentando manter esse curso
para iniciantes de
nível intermediário, não
quero sobrecarregar ninguém com todos esses conceitos Então, vamos clicar em
Baixar e pegar o 4.4 0.1, e queremos a versão azul
aqui. Não é Mono. Isso será apenas
para GD Script. Se você quiser C sharp,
você pode pegar o.net. Não precisaremos disso para esta
versão do projeto. Eu poderia criar uma
versão C Sharp do curso mais tarde, se fizer sentido.
Vamos ver como as coisas vão. Então você vai
querer salvar isso instalá-lo e depois
abrir o GADOEditor Então, depois de abri-lo, você
deve entrar em contato com o gerente de projeto, que lhe dará uma lista
dos seus projetos atuais. Você provavelmente não
tem muita coisa aqui. Talvez haja algumas demonstrações. Mas o que vamos
querer fazer é criar nosso novo projeto. Então, vamos criar um novo projeto, e você pode dar a
ele o nome que quiser. Eu vou chamá-lo de script de nome sutil de
Survivors, eu sei, porque é um roteiro GD e é um estilo de Então, vou colocar isso no meu diretório de
tutoriais, que eu configurei
especificamente para esses tipos de tutoriais
longos Então, vamos definir isso como
a pasta atual, e devemos ver algo
como o nome do projeto aqui e o caminho para
o projeto completo. Porque eu fiz Script
survivors A de uma palavra, na verdade, ele não colocou
um separador Então, vou usar apenas um traço como separador padrão
para espaços E vamos querer o
renderizador no modo móvel. Este é um curso de pixel art, então realmente não precisamos do renderizador
Ford por nenhum motivo, e vamos continuar
criando com ele Então, depois que seu
projeto for inicializado, você deverá ver as
três portas de visualização D aqui Uma das coisas legais
sobre o Gadot é que ele tem dois
fluxos de trabalho completamente separados para dois D e três D, mas suporta
os dois Ao contrário do Unity, eles são entidades
completamente separadas. Portanto, não é fingir dois
D em um sistema de três D. Na verdade, são completamente
dois D. E se você olhar para a esquerda
nesta janela de cena, você verá que há, na
verdade, quatro tipos de nós aqui, duas cenas D, três
cenas D, interface de usuário. E então, se clicarmos em outro nó, há a
classe base aqui node, que não tem
componentes 2d3d Portanto, não é uma posição em nenhum lugar, você a usaria para
coisas como sistemas, processamento de informações
básicas, não para objetos realmente
no mundo do jogo. Para tudo o que
está no mundo do jogo, geralmente,
usaremos uma cena em dois D. Então, esse
será um ícone de nó azul aqui, assim como
a diferença. E então a interface do usuário
são os nós de controle. Então, isso é marcado em verde, qualquer coisa que seja
um botão na tela, texto de combate
flutuante, janelas pop-up da
interface do usuário, como quando estamos
selecionando recompensas pelo que você pode obter
ao subir de nível Todos esses são nós de
interface de usuário. Então, é claro, à medida que
avançamos, explicarei mais sobre o que realmente é um nó. Por enquanto, vamos abordar
um pouco mais a interface. Portanto, temos o sistema de arquivos
no canto inferior esquerdo. É aí que você
terá todos os
seus arquivos no Gdo , incluindo todos os ativos importados,
seus arquivos SEN, que é onde você pega
um ou mais nós e os salva em uma cena, da
qual você pode criar cópias
de qualquer lugar do jogo Portanto, é basicamente um
modelo que você pode reutilizar. E depois outros arquivos Gdo
e não Gudo como recursos Então, na janela de exibição aqui, você
tem seu acesso X, Y aqui. Um
ponto distintivo abaixo é na verdade, a
direção positiva do eixo Y. Então, se você está falando
sobre subir, você quer ir para Y negativo, e se você quiser se mover para
baixo na tela, você estaria falando sobre
um valor Y positivo. A direita é X positivo
e, em seguida, a esquerda é X negativo. Então, isso será
muito relevante quando estivermos movendo nossos personagens
pela tela Você quer ter certeza de que eles se movem na direção certa e que você também está recebendo informações para a direção certa. Se você olhar bem de
perto o ponto de 1.200 pixels, pelo
menos para mim, haverá os limites da nossa interface de
usuário Portanto, a interface do usuário
geralmente está em sua própria camada de tela
separada. Portanto, é uma coisa completamente
separada do próprio mundo dos dois
jogos D. Você pode pensar na interface de usuário da interface
do usuário como uma espécie
de camada na parte superior da câmera enquanto
visualiza os dois mundos D. Então, sempre que a câmera se move, todos os elementos da interface do usuário também
se movem. Mas os
objetos do mundo do jogo geralmente não se movem com
a câmera. Então, se você mover a câmera, a interface do usuário permanecerá no lugar
e tudo abaixo dela, os personagens, os inimigos, aqueles não se moverão
com a câmera. E esse é um
dos maiores
fatores distintivos entre os dois nós D e os nós de controle da
interface do usuário Qualquer coisa que seja um elemento de interface do usuário
é um nó de controle em Gadot. À direita,
temos o inspetor que é usado para definir quaisquer propriedades sobre seus nós Ao escrever scripts, você pode atribuir a ele uma tag at export, que o marca como editável dentro
do inspetor Isso é muito importante. Vamos fazer muito disso. Então você vai editar isso aqui. Obviamente, existem outras janelas que têm importância variável Também abordarei isso nos vídeos
posteriores. Então, no próximo vídeo,
vamos configurar nosso projeto. Importaremos todos os recursos
artísticos de que precisamos, incluindo áudio,
música, arte e fontes. E também há
alguns plug-ins
que acho que seriam extremamente
úteis para o projeto, os gratuitos para baixar e usar. Então, abordaremos tudo isso
no segundo vídeo.
3. Arte, som e plugins ~ Importação e instalação: Então, neste vídeo,
continuaremos com a configuração do
nosso projeto,
configurando todos os ativos,
áudio e plug-ins nos projetos que estamos
prontos para começar a trabalhar. Então, no PaySpn, tenho todos os links para
os recursos de que
precisamos para o curso,
tudo o que usei no projeto de
pré-gravação
para sobreviventes do roteiro Então, se você seguir
o link aqui no topo,
eu vou ampliar isso. Basicamente, você pode
acessar cada um desses links e só precisa das
versões gratuitas de cada ativo. Eu tenho que compartilhá-lo dessa
forma para respeitar a regra de
não redistribuição que
muitos desses ativos têm, mas você basicamente só
precisa seguir os links para cada página da loja e
pegar a versão gratuita Então, primeiro, Pixel Crawler tem nosso modelo baseado em personagens que
usaremos para configurar algumas
armas e inimigos É realmente fundamental
para este tutorial, então é nisso que, na verdade,
baseamos grande parte do Alpha. Então, a seguir, os ícones da fantasia de Raven. Para elementos de interface do usuário, interface de usuário Crimson
Fantasy. A fonte, eu vou
usar m5x7. Mas, honestamente, você pode
simplesmente escolher qualquer fonte de
pixel art
que achar boa Também há muita coisa sobre
itch dot IO. Para alguns efeitos sonoros básicos
de áudio do jogo, Leo oferece RPG
Essentials SFX gratuitamente. E então, para a
música, The Red Hearts
prepared to Dev by Tall Beard é uma música de
chip tune
absolutamente perfeita para o estilo do jogo
Survivors Light. Na verdade, funciona
muito, muito bem. Ok, então você baixa
todos os arquivos zip
e, em seguida, o que você pode fazer é clicar com o botão
direito do mouse no sistema de arquivos criar uma nova pasta para arte. Vou colocar todas
as imagens aqui. E então clique com o botão direito, crie
uma nova pasta para áudio, qualquer coisa que esteja em Efeitos sonoros ou música, eu vou colocar
lá. E então, para abri-lo rapidamente
no Explorador de Arquivos do Windows, ou o equivalente, se
você estiver no Mac ou no Linux, é clicar com o botão direito do mouse e clicar em
Abrir e Gerenciador de Arquivos. OK. E então você só
quer extrair todos os arquivos para
essa pasta de arte. Então, aqui temos a GUI
Crimson fantasy,
temos os ícones de fantasia
e, em seguida, o pacote gratuito Pixel
crawler A única exceção é que,
para os ícones de fantasia, existem três ou quatro versões
diferentes. Eu estava apenas usando as planilhas de sprites
completas. É mais fácil trabalhar
com eles no Gadot porque você pode criar um recurso de
textura de atlas
e, em seguida, basta escolher o ícone
que deseja selecionar para Para cada um dos itens aos quais
você
atribuirá um ícone, acho muito
mais fácil trabalhar dessa forma Além disso, para Gadot, se estiver importando
cada ícone separadamente, o que é uma opção
desse pacote, leva muito tempo para
realmente ser carregado no motor Então, quando você tem suas imagens compactadas em um arquivo como esse, é muito mais eficiente. Eu acho que é o caminho a
percorrer. Além disso, acho que estava apenas
trazendo o diretório inteiro. Eu não mudo os
nomes dos arquivos nem nada parecido. Normalmente, em Gadot,
você usaria letras maiúsculas e minúsculas para os nomes das pastas do seu
diretório, mas acho que é
mais simples
usar o que os artistas forneceram
aqui e seguir em frente Portanto, não deve causar
problemas nem nada. Talvez um pouco
otimizado, mas está tudo bem. E então, para o áudio
dos efeitos sonoros, se você abrir o zíper, viremos
assim. E a música, eu estava apenas fazendo o box jump de três Red
Hearts, que é a primeira faixa musical Na verdade, você pode simplesmente selecionar faixa de música
que
deseja usar para o seu nível de jogo, mas acho que essa funciona
muito, muito bem Sabe, vamos dar uma prévia por um minuto. Sim, então acho que é uma
faixa absolutamente matadora para jogos
no estilo Survivor Então, depois de importar tudo,
você o coloca em seus arquivos. Se você reabrir a janela do Gado, deverá ver tudo o que foi
importado para essas pastas corretamente
e, em seguida, deverá ser exibido
aqui à esquerda Portanto, você pode receber algumas mensagens de
erro ao importar coisas
pela primeira vez Você pode simplesmente confirmar que
os arquivos estão lá, e isso é o
mais importante aqui. Acho que essas mensagens podem ser
meio que ignoradas. Drop Stable nem tem nada a ver
com esse projeto. Pode estar relacionado ao
armazenamento em cache no meu computador. Mas o importante
é que temos os arquivos aqui. Você pode
clicar duas vezes neles. Você pode ver que está
sendo reconhecido, como a música lá e os efeitos
sonoros aqui. Então parece que estamos bem. Então vá em frente e limpe esse logotipo. Portanto, precisamos de dois plug-ins
para o curso. Primeiro, acho que é
uma grande qualidade de vida quando você está navegando
pelo sistema de arquivos por aqui É chamado de recolher
pastas porque você pode perceber que, ao abrir
várias pastas como essa, não
há uma maneira fácil de
recolher ou dobrar todas elas
para que você possa ver todo
o sistema de arquivos
aqui em uma janela. Então, o que você quer fazer é
ir até a Asset Lib aqui no topo e depois
procurar por colapso Então, clique na
barra de pesquisa e digite fechar. E então o que
queremos aqui é recolher pastas.
Então baixe isso. Instale-o Ok, direi que foi
instalado com sucesso. Agora, queremos ir para
Projeto no canto superior esquerdo, configurações
do projeto e ir
para a guia de plug-ins aqui. Marque a opção ativada, clique em Fechar. E o que isso faz é criar esse pequeno ícone aqui,
onde você pode recolher tudo e fazer com que
todas as pastas
voltem para a raiz. Nada foi expandido e é muito mais fácil navegar
pelo sistema de arquivos com isso. Acho que é um botão
muito útil. Deveria estar lá no básico de
Gadot, honestamente. Então, o outro é um plug-in muito
mais complexo, e vamos
usá-lo para máquinas de estado em Gadot. Também é usado
para árvores de comportamento, mas como a IA é muito
simples e um jogo de sobrevivência, vamos usar apenas máquinas de
estado Não há necessidade de tornar isso mais complexo com uma árvore de comportamento. Então, estamos procurando o Limbo AI
e, como estou no 4.4, vou usar o
Limbo AI 4.4, é claro Você pode notar que
atualmente aqui, pelo menos, ainda não
há 4.5 lançado
porque, bem, quero dizer, 4.5 ainda está em Dev, então pode funcionar se você decidir usar a versão Dv ou pode ter alguns problemas Provavelmente funcionará, mas, você sabe, pode
haver um bug aqui ou ali. Então, você sabe, outro motivo para ficar com a versão
estável do Gado. Então, vamos fazer o download disso, e esse será o
nosso
plug-in de máquina de estado . Nós podemos instalá-lo. Vai demorar um pouco
mais porque esse é um plugue bem grande. Vou ignorar
essas mensagens mais uma vez. Na verdade, isso pode estar acontecendo porque o
nome do projeto é o
mesmo, mesmo que o
diretório seja diferente, então vou mudar o nome do projeto para que
essas coisas parem de aparecer. Espero que isso
resolva. Então, vou mudar o nome e dar a ele o nome GD script lá.
É uma etiqueta extra? Vamos encerrar que vou
limpar as mensagens e recarregar o
projeto enquanto estou avançando e vou ver se
há algum problema ao recarregar o Não, ok, parece bom. OK. Então, se verificarmos as configurações do
projeto
e você acessar Plugins, você notará que o Limbo AI
não aparece aqui Limbo AI é, na verdade,
escrito em C plus plus, então pode ser por
isso que ele não aparece especificamente como um plug-in do cado Imagino que ele tenha feito
isso para maximizar a eficiência
do código,
já que o CPlusPlus é mais rápido que o script C Sharp
e Mas sim, é assim que é. Então, para confirmar que
o Limbo AI funciona, podemos criar rapidamente uma nova cena de TD aqui
no canto superior esquerdo E então clique com o botão direito
aqui no nó raiz, no nó dois D, adicione um nó filho e procure apenas digitar State. Você deve ver o estado do Limbo
aparecer e o estado BT. Desde que você veja essas classes
do Limbo AI aparecendo
, você sabe que o plug-in
está instalado corretamente Então, para recapitular, devemos ter um áudio com nossos efeitos sonoros em
cinco pastas aqui, pelo
menos uma faixa de áudio E na arte, deveríamos ter interface gráfica de fantasia
Crimson, ícones de fantasia de
Raven, e eu estou trazendo apenas a pasta
completa da planilha de sprites
e, em seguida, Pixel Crawler
para nosso personagem principal, nossos
adereços de fundo e inimigos, meio que o principal recurso artístico da série de cursos, na verdade E depois uma fonte. Então eu trouxe m5x7
como uma fonte TTF de pontos. Acho que outros tipos também
podem funcionar, mas provavelmente é melhor usar o mesmo para obter consistência. E então temos complementos, pastas de
recolher e Limbo AIA Então, esses devem ser todos
os arquivos externos que
precisamos trazer
para este curso. Todo o resto
será um script GD que escrevemos, cenas que configuramos
ou
outros arquivos Gadot que criamos, como recursos
que podem ser salvos em um Então, isso vai ser
o fim deste vídeo. Em seguida, vamos
começar a criar nossos dois personagens do
jogo D de cima para baixo e adicionar alguns
controles básicos de movimento ao personagem, que ele
possa se mover
na tela.
4. Movimento do jogador de cima para baixo: Então, neste tutorial,
vamos implementar o movimento do personagem de cima para
baixo cena do
nosso personagem principal. Mas logo antes de
entrarmos nisso, quero
ressaltar que podemos excluir a pasta demo do Limbo AI que
importa automaticamente com o próprio plug-in Se você quiser assistir
à demonstração ou mantê-la lá,
fique à vontade. Isso inclui exemplos
de como usar o Limbo AI, mas
mostrarei em vídeo essas etapas especificamente para a
máquina de estado Então, na verdade, não precisamos
disso para nosso projeto. Vou remover isso. Ok, e agora estamos prontos para começar. Então, queremos
começar com uma cena
em dois D no canto superior esquerdo, então vou clicar em
criar uma cena D do nó raiz dois. Então, isso nos dará
um nó base dois D. Agora, a raiz do nosso personagem, em
geral, queremos
ser um corpo de personagem dois D, que é um tipo de nó dois D. Então, podemos clicar com o botão direito do mouse no nosso nó dois D e
alterar o Tipo, e então
digitaremos o caractere. Encontraremos o
corpo dois do personagem D. Note que isso herda do corpo
físico dois D, que é um objeto de colisão Que é um tipo de nó dois D. Então, há
toda uma série de classes ou tipos de objetos o corpo do personagem
é herdado, e ele adquire todas
as características de todas as
classes anteriores Então isso significa que qualquer coisa que
um corpo físico dois D possa fazer, um corpo de personagem dois
D também pode fazer. Então, vamos clicar em mudar aqui para corpo do
personagem dois D. E
assim que você fizer isso, haverá um pequeno sinal de aviso triangular
amarelo dizendo que o
objeto de colisão não tem forma Então, precisamos clicar com o botão direito do mouse
e adicionar um nó secundário, que será uma
colisão em forma de dois D, e eu vou ampliar
o centro de 0,00 Você
ainda não verá nada porque, na verdade,
não adicionamos um sprite Mas vamos começar clicando
na forma e no inspetor do lado direito e
fazendo uma nova forma de círculo Então, podemos voltar para editar
isso e reduzir seu tamanho, mas primeiro precisamos do sprite para realmente ver com
o que estamos trabalhando Então, vamos pegar o nó raiz e também renomeá-lo
pressionando F dois E eu vou chamá-lo
apenas de player. Você também pode chamá-lo de personagem
do
jogador ou corpo do personagem do jogador dois D,
o que fizer sentido para você. E então vamos
salvar essa cena,
que é basicamente
a cena raiz e qualquer um dos
nós secundários em um arquivo,
um arquivo de cena
TACN com pontos em nosso projeto Então, se pressionarmos Control S para salvar e clicarmos no canto
superior direito, isso criará um novo botão de pasta. E vamos dar um nome a ele. Vou usar caracteres,
vou usar letras minúsculas, que normalmente é o nome
padrão do Gadol, maiúsculas e minúsculas. Então, se você precisar de
espaços, você colocaria sublinhado e outras
coisas, mais ou menos assim Então, vamos fazer personagens. E então, em personagens,
criarei uma pasta para o jogador só
porque sei de antemão que
haverá vários scripts
e, em de antemão que
haverá vários scripts
e, seguida, podemos
combiná-los todos no mesmo subdiretório Então, vou criar uma nova pasta. Jogador. E digamos Ok. Então, temos o player dot
TSC e vamos
salvá-lo nesse
diretório ou pasta Então salve a cena lá. Então, em Godot, seu projeto é essencialmente composto de
cenas dentro de cenas Então você pode ter uma cena de jogo
principal. Temos toda a configuração do sistema
e, abaixo dela, você pode
carregar a cena mundial do jogo, que é o mapa de dois D e
os objetos que devem ser preenchidos e, dentro
desses dois mundos D, você teria, é claro,
a cena do seu jogador, as cenas de seus inimigos, seus orcs, seus
esqueletos, etc Então, quando sua cena
é salva em um arquivo, é muito fácil instanciar
isso porque
basicamente será pegar os dados
salvos, carregar uma cópia deles e
colocá-la em sua Então, muito rapidamente, eu pude
realmente demonstrar isso. Se clicarmos nessa nova guia, crie um novo botão de cena. Podemos adicionar uma nova cena em
dois D aqui. Vamos chamar isso de mundo. Então, vou pressionar F dois para renomeá-lo, e isso será apenas um mundo Podemos mantê-lo como um
nó padrão dois D. Na verdade, não
precisamos que ele tenha
outra posição além uma posição na tela. Então, vamos pressionar Control
S para salvar essa cena. Vou até a raiz e
podemos salvar o World Dot
TSN dentro daqui Ok, agora queremos adicionar uma cópia do nosso player
ao mundo. Então, o que podemos fazer
é arrastar a cena do jogador para a hierarquia mundial na guia de cena
no canto superior esquerdo Então, basta arrastar o player dot
TSN até aqui em World. E agora há uma cópia
do jogador dentro
do mundo do jogo. Então você sabe que está lá porque
você pode passar o mouse sobre ele. Eu vou dizer jogador
aqui. Você pode ver o ícone do corpo do
personagem dois D e ver a
forma de colisão que definimos Agora, ainda não há nenhum sprite. Vamos adicionar isso
agora. Então, vou clicar em Controlar-nos para
salvar o mundo. Vamos até o jogador.
Vou clicar com o botão direito do mouse no player, adicionar um nó secundário que estamos
procurando por sprite Então Sprite two D. Há também um nó Sprite two D animado, e ambos podem ser
usados praticamente para os mesmos propósitos Eles configuraram as coisas de forma um
pouco diferente. Eu diria que, para personagens de
jogadores, é realmente mais fácil trabalhar
com Sprite two D e depois definir as propriedades
que você precisa para animar no reprodutor de animação Falaremos mais
sobre a animação de um sprite no próximo vídeo Então, vamos adicionar um nó
Sprite two D. E, por enquanto,
vamos
querer carregar uma textura. Quando estamos carregando
a textura aqui, não
vamos definir
uma única imagem de sprite Na verdade, vamos
definir uma folha de sprites. Então, obtemos nossa folha de sprites
do diretório de arte. No
pacote Pixel Crawler, creio que foram entidades,
personagens, corpo
A e animações Então, vamos começar
com o ídolo. Então, para esse personagem, você tem uma folha de sprite com o lado negativo e Quando você está jogando dois jogos D de cima
para baixo, você pode simplesmente virar a folha lateral
do sprite Da esquerda para a direita, o que
significa que você não precisa criar uma quarta
planilha de sprites para a esquerda e direita, pois você pode simplesmente
reutilizar a mesma planilha de sprites e ela também funciona Você economiza muito tempo
para animá-lo dessa forma. Então, queremos que o Idle down comece
apenas para que possamos realmente ver o personagem
que estamos vendo Então, vamos carregar isso aqui. Portanto, esse é um sprite de
personagem básico. Portanto, a ideia aqui é que
você possa
adicionar roupas como um
sprite adicional em cima delas,
fazer qualquer personalização, mas as animações
básicas permaneçam as mesmas, pois você
desenvolveria o personagem
final com estilos basicamente diferentes OK, então algumas coisas
provavelmente se destacam. Primeiramente, o personagem
obviamente não tem roupas. Portanto, esse é um sprite de
personagem básico. A ideia é que o que você
faria seria pegar sprites de roupas
adicionais e
adicioná-los à animação base
para o personagem final, talvez como um
chapéu de mago ou algo parecido E a ideia é que você
possa trocar sprites para
finalizar seu personagem
final Mas para as animações básicas, elas são fornecidas aqui
no pacote gratuito, e você simplesmente
criaria a partir daí Então, vamos trabalhar
com isso para o tutorial. Os outros dois
problemas óbvios são, bem, um temos quatro cópias
do personagem aparecendo na tela ao mesmo tempo. Então, queremos fazer com
que apenas um show. E a maneira de fazer isso é ir até a guia de animação aqui e alterar os
quadros H para o número de sprites que estão sendo exibidos
nessa folha de sprites horizontal Então, eu apenas mudo os quadros
H para quatro. E agora está mostrando apenas
a posição zero do quadro, que é o primeiro sprite
nessa animação inativa O terceiro problema é
que está muito embaçado
para a arte em pixels Portanto, podemos corrigir isso em todo o
nosso projeto
acessando as configurações do projeto e queremos rolar para baixo até, acredito que seja um renderizador Não, texturas. Portanto,
renderizar e depois texturizar o filtro de textura linear padrão aqui é mais apropriado
se você estiver fazendo, eu acho, coisas como arte vetorial Mas para pixel art,
que precisa ser Pixel Perfect, você deseja alterar
isso para o mais próximo. E assim que você fizer isso,
ele mostrará basicamente cada pixel renderizado de forma nítida, como seria de esperar
de um jogo de pixel art E basicamente para o projeto, isso é tudo que você precisará
fazer para
configurá-lo especificamente para
um formato de pixel art. Agora, o personagem e a forma da colisão estão um
pouco estranhos aqui agora Geralmente, para jogos de cima para baixo, você quer que a forma de colisão fique em algum
lugar ao redor
dos pés do personagem Então, eu gosto de manter
minhas cenas ainda centradas em 00 para que eu saiba basicamente a posição
exata em que o personagem está representado no mundo do jogo e o deslocamento não seja
estranho ou algo parecido Então, o que realmente
queremos fazer aqui é compensar, não a cena base Queremos manter isso em zero,
zero, mas no nó do sprite Então, se você selecionar o Sprite dois D e
pressionar W para ir para o modo de movimento, você pode clicar com o botão esquerdo,
segurar e arrastá-lo para cima Se você quiser encaixá-lo eixo Y, mantenha
a tecla Shift pressionada, que ajuda a evitar que ela vá para a esquerda, a
menos que você vá muito longe E só queremos
arrastar isso até que os pés do personagem estejam
basicamente ali. E então queremos que a forma de colisão
seja uma representação
da área dos pés do personagem,
porque é aqui o personagem poderia
colidir com outros objetos Portanto, faz sentido
que a posição seja onde os
personagens realmente estão no mundo dos
dois jogos D. Hum, para se acostumar com
a perspectiva de dois D leva um pouco
de tempo para se acostumar,
porque é um pouco menos óbvio, eu acho, do que três D, onde seria mais
parecido com a vida real. Então, aqui só temos que dar a ilusão de que nossos personagens realmente estão ali, mesmo que o personagem
vá daqui até aqui,
essa é a área em que
o personagem está o personagem está Então, podemos salvar isso aí. Isso deve ser bom. Apenas para referência, eram 4,12 pixels Na verdade,
vou arredondar isso para quatro, um
pouco de
preferência para
tentar manter tudo em tamanhos perfeitos em
pixels. Para um jogo de arte Pix, provavelmente não será um grande problema
e causará problemas,
mas, você sabe, por precaução Então, agora, se voltarmos
para nossa cena mundial, veremos que nosso personagem está realmente
no mundo do jogo. E se quisermos
jogar o mundo, apertaríamos este
botão play aqui, que reproduz a
cena atual do mundo. E poderemos
ver o personagem muito, muito pequeno no canto superior
esquerdo. Na verdade, é quase
impossível ver isso. Então, a próxima coisa
que provavelmente queremos é adicionar uma câmera. Então, vamos clicar com o botão direito do mouse no
mundo, adicionar um nó secundário, fazer duas câmeras D. E embora o mundo
crie automaticamente uma câmera padrão, mesmo quando você não
adicionou um nó de câmera, quando você
define corretamente uma câmera, você
pode definir o Zoom, que é muito útil para a Pixart porque estamos falando
sobre trabalhar com caracteres de
48 pixels por 32 pixels, algo assim assim. Então, queremos pegar o Zoom
e provavelmente aumentá-lo para
cerca de três ou quatro,
podemos ver que a câmera 2 D agora também está centralizada
no ponto zero, em vez de ser
mais uma caixa de tela padrão
aqui Na verdade, podemos ver que a
câmera é essa linha rosa. E se rodarmos a cena agora, nosso personagem deve estar centralizado muito maior
e mais visível Então, se você quiser, você pode
aumentar isso para quatro. Acho que três é
muito bom por enquanto. Vou mudá-lo mais tarde,
se precisarmos. Mas desde que você possa ver o personagem,
acho que você é bom. Outra coisa, quando
estamos jogando o jogo, acho que quero que isso
seja muito mais visível. Então, vamos aumentar o tamanho da
janela agora para que
possamos projetar uma tela
maior de forma
mais adequada para que, você sabe, quando estivermos
fazendo nossas visualizações, vocês possam realmente ver
o que está acontecendo melhor Então, vamos às configurações do projeto, e eu vou pegar
a vitrine e mudar isso para
algo muito maior. Então eu acho que algo como
1980 por 180 seria bom. Quero dizer, isso depende de qual é
a resolução da
tela. Para mim, isso vai
ser mais ou menos assim. Ok, vou tentar isso
na minha tela. Estou trabalhando em um monitor branco
extra bem grande aqui,
então, um pouco de
tentativa e erro. Acho que vai funcionar bem
porque ainda consigo ver o botão uh Of aqui. Então, reproduza a cena principal, pause e interrompa os botões atuais
do projeto em execução, a propósito Eu diria que,
desde
que você possa ver isso, tudo bem. Então, com nosso jogo Canvas, desse tamanho, eu provavelmente também
quero aumentar o Zoom. Na verdade, você pode editar as propriedades enquanto
os jogos são executados. Então, posso simplesmente pegar esse
Zoom e alterá-lo para quatro. Vamos tocar novamente
e você verá que o tamanho foi atualizado imediatamente. Então, se for grande o suficiente para
você, você pode ficar com isso ou
podemos ir até cinco. Você sabe, talvez eu realmente
faça um zoom 5.0 lá. Agora, no momento, vocês
estavam realmente esperando por isso. Vamos entrar no código real. Então, precisamos criar
um script que estenda o corpo do personagem em dois D e
anexá-lo ao jogador. Podemos fazer tudo isso de uma só vez clicando no botão
esquerdo do jogador e depois clicando em anexar um script novo ou existente
ao nó selecionado. E vamos chamar
isso de script player dot gd E, na verdade,
não vamos usar o script básico de movimento
D do corpo do personagem modelo. Ou seja, se eu me lembro mais sobre
jogos de plataforma, porque isso
adiciona salto e, honestamente, podemos escrevê-lo Então, vamos clicar em Criar, e isso nos
levará ao editor de scripts aqui. Então, por enquanto,
vou mantê-lo como editor
de script incorporado. Mas você também pode clicar nesse botão aqui e
fazê-lo flutuar se quiser usar o editor de scripts em tela cheia,
o que pode ser útil
se você realmente gosta de codificação em
GD Script Mas aqui, esse
script
será bem rápido e simples,
então não é necessário, na verdade. Então, vamos até o topo. Ok, então podemos ver que nosso script estende o corpo do
personagem dois D. Isso significa
que nosso script tem a classe base do corpo do
personagem dois D. Ok, então se passarmos o mouse sobre o corpo do personagem
estendido dois D, você pode ver a hierarquia de classes aqui descendo do corpo do
personagem dois D, até o objeto
base do Gadot Isso significa apenas que
, ao longo do caminho, ele herdará as habilidades de cada uma dessas classes
diferentes Então, um TD corporal de personagem
, na verdade, pode fazer muita coisa. Nós só vamos precisar de um
pouco disso, na verdade. Portanto, lembre-se de que
tudo o que está listado lá,
cada uma dessas classes, quais você pode
entrar clicando nas
quais você pode
entrar clicando nos nomes delas se
quiser ler sobre elas, é algo
que o personagem body two D também pode fazer. Então, ler tudo
isso seria muita documentação no momento, é
bom saber sobre ela. É bom ler à medida
que você avança, mas um pouco cansativo
por enquanto Então, vamos trabalhar em nossa aula. Queremos dar a ele um
nome de classe para que esse script possa ser facilmente referenciado a
partir de outros scripts pelo nome, indo até
o início da linha E, em seguida, pressione
Enter. Vamos até a primeira linha e digitar o nome
da classe player. E agora, definimos esse
script como o script dos jogadores. Então, este é basicamente
um símbolo global Agora, em nosso projeto,
podemos pesquisar e usar apenas referenciando player digitado exatamente
assim com À medida que
avançamos no curso, você verá
que isso é extremamente útil, especialmente para algo
como o script de um jogador, que muitas outras classes precisarão abordar. Então, vamos trabalhar
na função do processo físico do personagem. Então, vamos digitar FU NC para a
função e depois sublinhar. E você verá esse
menu ser preenchido automaticamente com os métodos
definidos dentro
das classes principais Essas são basicamente
funções que podemos substituir e adicionar no código para que ele realmente
faça alguma coisa ou mude o que a
classe base fez originalmente Então, queremos o processo de física aqui. Se você encontrar o
processo físico e pressionar Enter, ele nos dará a definição completa da
função aqui para o nome aqui, processo físico de
sublinhado Ok, então aqui temos o
nome da nossa função. O sublinhado aqui
indica que ele deve ser
privado e não acessado por outros
scripts e apenas ser
acessado por outros
scripts e apenas
contido ou encapsulado
de dentro desse O Delta aqui é o
nome do nosso parâmetro e float é o tipo
do nosso parâmetro No script GD, você não precisa realmente digitar suas funções Então, se você quiser,
pode remover essa flutuação do cólon e chamá-la de
Delta Agora, o que é Delta? Bem,
isso acabaria sendo o
que a coleira decidisse passar
para essa função,
que, nesse caso,
basicamente não tem nada que a impeça de ser
outra coisa senão uma bóia Você provavelmente
esperaria que fosse um carro alegórico. Portanto, nesse caso, é
muito melhor
declarar seu tipo com
dois pontos e depois flutuar Então, eu recomendo isso. E aqui também está um componente
opcional da declaração da função. Temos essa seta, que é
um traço ao lado da tecla zero. Ok, e
aqui à direita,
temos a seta de retorno apontando para o tipo de vazio de retorno Vazio significa que não tem retorno. Você não espera que ele
realmente retorne nada que você usaria
dentro de outras funções. Então, para digitar isso manualmente, você digitaria um hífen e
depois uma nota e assinaria E essa é sua seta de retorno
apontando para o tipo de retorno. Ok, então, é claro,
quando digitamos isso, nossa função na verdade não
tem nada nela. Você pode fazer com que uma
função não faça nada
digitando passe em minúsculas, então essa é uma palavra-chave reservada Mas sem isso,
se eu desfizer isso, você verá esse erro
aparecer na parte inferior aqui
dizendo bloco final esperado
após a declaração da função, significa que deve
haver algo aqui depois que a
função E você pode expandir
essa lista aqui para ver todos os erros dentro
do seu script atual, uma
pequena janela bem útil Ótimo, se você precisar
copiar e colar, basta selecionar
tudo e copiar. E você pode colar isso em qualquer outro aplicativo
que estiver usando. Talvez você esteja fazendo um
relatório de bug ou algo parecido. Ok, então, finalmente,
podemos realmente começar a escrever algum código de
função. Sei que estou indo um pouco devagar, tentar mantê-lo
acessível aqui, especialmente nos vídeos
anteriores, com
certeza ficará muito mais
intenso à medida que o curso avança. Então, primeiro, para
nosso processo de física, queremos que o personagem se mova, que significa que precisamos de
uma velocidade e uma direção na qual o personagem
se mova. Então, em algum lugar, precisamos declarar a rapidez com que nosso personagem se move Então, poderíamos declará-lo
diretamente na função. Mas, na verdade, o que eu quero
fazer agora é criar uma
variável de exportação em que possamos alterar a velocidade
no editor com muita facilidade simplesmente
indo até aqui à direita e digitando a velocidade
que quisermos. E também podemos mudar isso
durante o jogo. Então, vamos digitar na velocidade
Export var e definir o tipo de flutuação Então, vamos analisar
isso lentamente primeiro. Em Exportar, aqui está uma
palavra-chave
que a declara que pode ser
editada no inspetor Ok, e então var
aqui significa variável. Velocidade é o nome
da variável. Dois pontos aqui definem o tipo
e, em seguida, float é o Então, podemos pegar essa velocidade. Na verdade, vamos
escrever o passe aqui para o processo de
física e, em seguida,
pressionar Control para salvá-lo. E você verá a velocidade aparecer aqui e no canto superior direito
do script do player Certifique-se de ter
selecionado
o nó do jogador e você
poderá ver isso. Agora, você também pode ver que
o padrão é 0,0. Então esse é o
valor padrão para float. Você provavelmente quer agilizar,
na verdade, atribuir
um número real a isso. Então, vou pegar
isso e dizer igual,
vamos usar 100,0, pressione Control S. Agora o valor padrão é carregado aqui automaticamente porque
não definimos um Se você definir um
valor personalizado clicando aqui, digamos 150 e pressione Enter
agora, a velocidade é 150. Se alterarmos o padrão para 200 aqui e clicarmos em Salvar
dentro do script
, você verá que
o valor personalizado ainda substitui o
padrão de Eu posso apertar o botão de reset aqui para redefini-lo para o
padrão, então agora é 200. Agora eu quero que a
velocidade do script seja 100. Acredito que era isso que eu tinha
para o projeto padrão. Sempre podemos mudar
isso mais tarde e ficar à
vontade para realmente definir velocidade de
seus jogadores para qualquer coisa com a qual você se sinta confortável.
Isso é completamente. E é assim que podemos fazer com que nossa propriedade definida pelo editor
seja usada dentro do script. Portanto, as variáveis de exportação são realmente úteis para torná-las
mais acessíveis para editar os detalhes de
como nosso script seria editado sem precisar saber nada sobre como o
código realmente funciona Ok, então temos nossa velocidade. Podemos escrever o
processo de física agora. Ok, então vamos ver
aqui. Eu vou primeiro obter a direção de entrada. Ok, então, por
enquanto, queremos
declarar uma
variável de direção, então, var direction E você verá que estou digitando isso dentro
da função Então, isso a torna uma
variável local para a função,
ou seja, assim que as funções forem
concluídas, isso será apagado Ele só é usado dentro
da função, a menos que retornemos como nosso tipo de retorno. Então, é temporário, basicamente. E vamos definir
isso igual à entrada. Agora saiba que estou colocando
o I em maiúscula porque esse é um nome de classe ao
qual estamos referenciando Portanto, a classe de entrada é que você pode pensar
nela como uma classe global. Você pode acessá-los em qualquer lugar se precisar que eles
façam algo por você. E vamos usar
a classe Import
para obter um vetor. Então, um vetor
terá componentes X e Y, em vez disso, um vetor dois. Também há o vetor
três para três jogos D, que adiciona o eixo Z. Mas para dois jogos D, você só tem X e Y,
o que, ao remover
o terceiro eixo, torna dois jogos D um pouco mais simples de
entender e trabalhar Então, queremos obter
o X negativo aqui. Você pode ver os parâmetros que essa função está definindo
e, na verdade, há
alguns extras aqui, como zona morta, dos
quais não precisamos. Mas os quatro que precisamos
são X negativo, X
positivo,
Y negativo e Y positivo. Então, em um dos dois vídeos
anteriores, acredito que toquei nisso, mas o X negativo e Gadot
permanecem na Então, queremos entrada para a esquerda. Agora, você pode
vê-lo sendo preenchido com
alguns nomes de cadeia de
ação predefinidos Você sabe, é um
nome de string, a propósito, porque tem um e comercial
aqui na frente da string,
que são aspas, e então o nome
real aqui, terminando Mas todas essas são ações de interface de usuário
padrão, e não é uma boa ideia
realmente usá-las. No sentido de controlar
seu personagem,
porque ele já controla a interface
do usuário por padrão. Então, vamos até as configurações
do projeto. Então,
projete as configurações do projeto no canto superior esquerdo, no mapa de
entrada, e
digitamos uma nova ação. Vou digitar à
esquerda e clicar em Adicionar. Então, nossa ação à esquerda, vou clicar em Adicionar evento aqui
e gosto de usar as teclas WASD É bastante normal
para muitos jogos. Então, vou
apenas digitar A aqui onde diz ouvir
a entrada e uma regra. Atribua-o automaticamente à chave A, física ou Unicode Então, basicamente, A
no seu teclado. Você pode clicar em OK agora. E agora, mover para a esquerda
é atribuído a A. E queremos fazer isso para
cima para baixo e para a direita também. Então digite à direita, adicione
e, em seguida, clicamos
aqui para atribuir a tecla, adicionar evento e pressionar D para a direita. Clique em OK. Agora vamos colocar. Clique em adicionar evento, pressione W para cima, adicione uma ação, para baixo, clique em Adicionar evento, S para baixo e aí está nossa entrada de movimento. Portanto, o Kidob
manipulará automaticamente a conversão
dessas teclas pressionadas na ação real
que podemos usar
dentro
da coluna de função vetorial G da classe
de entrada Então, o que queremos fazer aqui é colocar os nomes das
ações que acabamos de digitar Então, podemos fazer a
cotação deixada aqui. E você verá que, na verdade, é preenchido
automaticamente, e você pode simplesmente pressionar Enter
aqui para confirmar que é negativo X para
X positivo, certo Você também pode ver aqui
que ele meio que apareceu, então podemos clicar duas vezes nele. Em seguida, o terceiro menos Y, podemos digitar ou
encontrá-lo na lista. Então, para baixo. E então, para Y positivo, oh, eu realmente misturei isso. O Y negativo está para cima, o
positivo Y está para baixo. Então, vou adicionar Y
positivo aqui embaixo, e depois aqui, vou simplesmente apagar
o valor para baixo e digitar para cima Então, tenho certeza de
que está aí. Definitivamente descobriremos em
um minuto quando jogarmos o teste. Queremos tomar a direção
de entrada
e, se não for zero,
queremos nos mover. Então, se for zero, só queremos parar de mover nosso
personagem por completo Então você pode fazer isso
dizendo se é direção. Então, isso basicamente
já verifica se a direção é igual
ao vetor zero ou não. Então, se a direção
significa que não é zero, então podemos pegar a
velocidade do nosso personagem Agora, onde obtivemos
a propriedade da velocidade? Bem, nosso clássico representa o corpo do
personagem dois D, e a velocidade é uma propriedade do corpo
do personagem
dois D. Então, se eu clicar com o botão
direito do mouse no corpo do personagem dois D e ir para o símbolo de pesquisa, posso rolar até aqui
e ver a velocidade aparecer aqui
na lista Portanto, quaisquer propriedades ou métodos, que são uma função dentro de
uma classe que pertence a uma classe mãe, serão herdados e utilizáveis por
essa classe herdeira Então, dentro de um jogador, podemos pegar a velocidade
e definir isso
para que queiramos a direção
multiplicada pela velocidade Agora, você verá esse componente
Delta aqui. Esse é o tempo entre os quadros. Não precisamos
atribuí-lo aqui ao
estilo de movimento específico que estamos usando, que é mover e deslizar. Há outro
movimento e colisão, onde você passaria e
o Delta ao chamar essa função, se bem me
lembro Portanto, é um pouco
estranho que, você sabe, o Delta seja automaticamente
contabilizado aqui, mas é assim que funciona Portanto, qualquer tecla pressionada para
movimento é pressionada. Vamos
atribuir a velocidade à direção
multiplicada pela velocidade Depois disso, aqui embaixo, podemos nos mover e deslizar. Agora, o que
aconteceria agora? Na verdade, seria
mais fácil mostrar. Vamos clicar em play e ainda não
selecionamos uma cena principal. Então, vamos selecionar a
cena mundial como nossa cena principal. Vou apenas subir os diretórios aqui
e escolher
o mundo. Clique duas vezes. Nós
temos um personagem. E se eu pressionar uma
tecla de movimento e soltar, você verá que isso não
impede nosso personagem. Ele meio que continuará deslizando, que poderia ser usado para algum
tipo de mecânico de iluminação Mas, para movimentos regulares, na verdade, queremos adicionar uma declaração se aqui como acompanhamento
do nosso I. Então, veja e, em seguida, certifique-se de
colocar o cólon no final Então, isso basicamente declara
o que vem a seguir como um bloco para a função
continuar executando E queremos
medir a velocidade. Queremos reduzir
isso para Serrel. A velocidade é igual ao vetor dois. Então, na verdade, estamos criando
um novo vetor dois aqui e colocamos parênteses Você pode ver que
o terceiro tipo de
construção de um vetor
tem um valor X e um Y. Então, dentro dos
parênteses, pressione Enter. Então, isso vai separar o primeiro parêntese
do segundo e
deixar bem claro digitar a lógica X
aqui e depois a
lógica Y logo abaixo dela Então, queremos nos mover em direção
ao ponto de velocidade x a zero. E vamos fazer
isso com a velocidade atual. Então, isso basicamente significa que,
assim que
soltarmos, baixaremos a velocidade
para zero imediatamente Há muitas
maneiras diferentes de fazer isso. Você pode fazer com que diminua
gradualmente com o tempo se usar uma função larp. Mas isso é provavelmente o mais simples.
Então, vamos continuar com isso. Vá em direção a. E então,
na segunda linha aqui, queremos obter o valor Y
para a nova velocidade Então, vá em direção ao ponto Y da velocidade
atual, estamos fazendo com que ele se aproxime de zero
na mudança ou Delta da velocidade Então, salvamos isso aí, e isso significa que isso vai
levar nossa velocidade atual, que pode ser, digamos, a direita em velocidade máxima, para a direita em velocidade máxima,
e vamos
reduzi-la na quantidade total de velocidade, o que
significa que ela
cairá imediatamente para zero. Estamos nos aproximando de zero Então, assim que
soltamos nossas teclas de entrada, nosso personagem para de se mover, é o resultado final de.
Na verdade, conte isso. Então, para declarar um comentário,
se você quiser fazer isso, coloque uma hashtag e
depois a descrição Assim, você pode manter seus comentários embutidos, se quiser, em geral Atualmente, eu
os puxo para o topo
da função desta forma, então Controle X e depois
Controle V para colá-los. E se você quiser que esse
texto apareça
na documentação gerada automaticamente para sua turma
, você pode fazer dois anúncios comerciais. E salve-o e, em seguida
,
ele será adicionado à documentação da
classe do jogador. E podemos acessar
essa documentação clicando em Pesquisar ajuda aqui Procuramos por player, nossa classe personalizada, clicamos em abrir e você pode ver o
nome de nossas propriedades, que neste caso
se refere apenas a uma variável que existe como parte
da classe local. Nesse caso, poderíamos nos referir
apenas a uma variável que é um estado local existente dentro da classe em vez de uma
variável local de uma função. Assim, você pode editá-los e
lê-los conforme necessário. Em outras linguagens de programação, coisas como campos ou propriedades são definidas com muito
mais clareza. Mas acho que geralmente para a maioria das funções
básicas do GD Script, sua propriedade e variável
acabam sendo a mesma coisa Você não declararia
algo como um campo privado de apoio,
como faria em C Eu diria que na maioria dos casos, porém, porque, você sabe, ainda
haveria
algumas razões para fazer
isso para ter um apoio privado
à sua propriedade pública Aqui você pode ver o método aqui e, se rolarmos para baixo,
as descrições do método. Então, processo de física. Assim que soltamos
nossas teclas de movimento, nosso personagem para de se mover. Então, essa é, na verdade, uma
das coisas mais legais sobre o script
GD é que ele é essencialmente gerador de
autodocumentação Contanto que você coloque os comentários onde eles deveriam estar
com os dois e comerciais, você pode comentar um
campo ou uma propriedade Você pode comentar um método. E isso é muito útil. Isso torna mais fácil
para outras pessoas entenderem
basicamente
seu código sem ler o script inteiro
de cima para baixo. Então, você pode realmente fazer a
mesma coisa com velocidade aqui. Então, dois e comerciais e
digamos o movimento básico, a base, a velocidade básica de
movimento
do personagem do jogador Controle S salve, e
então você pode ver nossa documentação ainda
está aberta aqui na janela do script. Então, se eu clicar no Player,
você pode ver, oh, agora, nossa propriedade de velocidade tem uma descrição que
pode ser facilmente lida. Então, isso é muito útil. Tenha isso em mente. E agora
podemos seguir em frente e clicar em Play. Então, vamos mover
nosso personagem WASD. Agora veremos que,
assim que pararmos de importar, o personagem para de se mover. que é mais o que você
esperaria de um personagem movendo-se em qualquer coisa padrão, como
grama, pedra ou qualquer outra coisa, coisas que deveriam ter
atrito, não gelo E esse é o movimento básico usaremos no resto
do jogo, basicamente. Agora, obviamente, os
personagens não são animados. Não temos as animações de
execução. Ainda não está voltado para a
direção que deveria. Essas são todas as coisas que
abordaremos em vídeos futuros. Uma última coisa que quero
acrescentar a uma última coisa que quero
acrescentar para esse personagem, bem, estamos à frente das coisas, é adicionar apenas mais uma propriedade de nome de
exibição. Então, na verdade, vou adicionar uma exportação para uma var,
um nome de exibição. E esse
será um nome de string de tipo. E vamos
definir isso como igual ao ampersan, seja qual for o
padrão que você quiser, basta torná-lo
player e apertar Portanto, para nosso player, podemos ver que agora a propriedade do
nome de exibição do nome da string é editável dentro
do inspetor Então, vou mudar
isso e configurá-lo para Jaco, porque vamos fazer com que
nosso personagem, por padrão, tenha uma arma de lança Então eu acho que isso funciona. Nos jogos Survivor Light, geralmente, você teria vários personagens
para escolher Portanto, fazer com que todos tenham um
nome de exibição distinto faz sentido. Agora, rápido,
também há uma propriedade de nome que
todos os nós têm. Isso se refere ao nome do
nó aqui em cima. Mas você pode ver coisas como a forma de
colisão em dois D. Você não
transfere espaços e nomes de nós Então, usar isso como
seu nome de exibição pode ser um pouco estranho exemplo, digamos que
você adicione uma subclasse como Fire Dragoon Mas você pode criar o nome do nó do
jogador aqui, Freragoon, sem esse espaço, para que você possa ter um nome de exibição distinto e
separado por ter uma
propriedade personalizada como Então, o que é isso para o dragão? Pressione Control S. E isso parece
aceitável no momento. Eventualmente,
pegaremos essa entrada e a moveremos
para um script separado. Usaremos estatísticas como a velocidade do
personagem e também faremos
disso um script separado. Mas isso é um bom começo. Então, isso vai ser
o fim deste vídeo. Eu tentei desacelerar aqui
intencionalmente para cobrir toda
a terminologia do script que vamos usar
para o script GD como, você sabe, a base
para o resto do curso Todas
essas são coisas
que
continuarão surgindo repetidamente Espero que não tenha sido
muito lento para ninguém, mas vamos
acelerar a partir daqui Então, até o próximo
vídeo, eu os verei.
5. Reproduzir animações a partir de Spritesheets: Então, do jeito que as coisas estão agora, nosso personagem pode se mover
tecnicamente, mas não há animação
alguma no sprite Então, queremos que nosso personagem anime quando ele dirige ídolos e, claro, a animação da morte também quando perdemos o jogo Ok, então a primeira coisa que
vamos fazer é realmente mudar
a planilha de sprites aqui Se você procurar no pacote
Pixel Crawler, podemos pegar o
lençol de sprites do Idol para a noite, ou você pode usar o ladino ou
o mago Então eu vou pegar isso e
trazê-lo aqui. E esses são basicamente sprites voltados para o
lado. Você notará que
esse personagem não tem altos nem baixos. No entanto, algumas vantagens
disso. Primeiro, se você está animando
apenas uma direção e
depois invertendo-a,
que é o que o
sobrevivente padrão realmente faz que é o que o
sobrevivente padrão realmente É muito mais fácil
criar personagens porque você só precisa
animar uma direção E em segundo lugar, você pode pular
completamente as árvores de
animação e se
concentrar apenas em um reprodutor de animação e uma máquina de estado que
controla a lógica seu personagem alternar
entre estados como Idle. Por esses motivos, na verdade, vamos passar para a planilha noturna de
sprites do Idol Você poderia usar o ídolo
praticamente de forma intercambiável. Posteriormente, você poderia usar, tipo,
a folha de sprites desonestos, como ali mesmo, ou a do
mago aqui também Então, qualquer um deles funcionará
perfeitamente bem, e já existe
a configuração para ter três
classes de personagens ali mesmo. Mas,
para começar, era mais um cavaleiro
empunhando uma lança cavaleiro
empunhando Então, como um personagem
chamado Agron, esse espírito meio que se encaixa, e
ele será capaz
de ele será capaz Ok, então temos nossa folha de
sprites definida aqui. Queremos
transformar isso em uma animação ociosa. Os quadros He
já foram configurados aqui, mas precisamos de um reprodutor
de
animação real para fazer isso. Então, clique com o botão direito do mouse no
nó do jogador e adicione um nó filho. Procure um
reprodutor de animação. Adicione isso. Então, quando você tiver o
reprodutor de animação, a janela de animação
estará aqui na parte inferior. Você pode clicar aqui
se ainda precisar. E queremos ir
para a animação e depois para Nu e digitar o
nome da animação. Então, estamos começando com
a animação ociosa, então vamos digitar Idle E podemos adicionar
uma trilha de propriedades. Então, vamos
pegar do Sprite two D algumas dessas propriedades,
ou seja, a textura.
Então, clique duas vezes nele. Vamos
clicar com o botão direito do mouse em Property Track, adicionar os quadros H
e, em seguida, na propriedade
Track, Sprite, dois quadros D. V. Por fim, por enquanto, pelo menos
precisamos do número do quadro em si. Portanto, adicione e enquadre como uma propriedade. Então, agora podemos pegar esse Zoom e ampliar um pouco
nossa planilha de sprites Primeiro, quero pegar o tempo de
captura aqui, onde
diz 0,033 3 segundos,
e alterá-lo para 0,1, que
significa que
trabalharemos em intervalos de
0,1 segundo ou
um décimo Em seguida, habilite esse encaixe no cursor
da linha do tempo. Agora você poderá
simplesmente clicar
aqui nos intervalos de 0,1
segundo, facilitando muito o trabalho com Você deve ter visto
nesta folha brilhante que há quatro
quadros de animação. Então, vamos
percorrê-los a cada 0,1 segundo, o que significa quatro vezes 0,1, queremos uma animação de
0,4 segundo. Então, aqui no lado direito, digite 0,4 e, em seguida, essa coisa que
parece flechas
se alimentando Loop de animação,
você quer clicar nele
para fazer
nosso loop de animação Agora, em nossa linha do tempo de animação, não
há quadros-chave.
Definitivamente, queremos definir um quadro-chave no início
da animação para todas essas propriedades Então clique com o botão direito do mouse na chave de inserção Se você clicar com o botão esquerdo aqui,
verá que o valor da textura já está predefinido para essa animação noturna
ociosa Se não
estiver, convém
alterá-la para a planilha de sprites
Idle A partir daqui, você pode arrastar e soltar assim e colocar isso lá. Então, o que esse quadro-chave significa
é que, no início de nossa animação, em 0,0 segundos, quando a
animação começar a ser reproduzida, ele definirá a textura
do nosso sprite com esse valor, o
que significa que, assim que a animação começar,
trocamos a planilha do sprite Agora, quadros H, também queremos clicar com o botão
direito do mouse e pressionar a tecla Serta. Agora, já predefinimos
nosso valor aqui como quatro
nesses dois brilhantes D. Então você pode ver que,
ao digitar a tecla Serta, ela adicionará qualquer valor
definido
atualmente como o ponto do quadro-chave
na linha do tempo da animação E sempre que esses
quadros-chave
aparecem, isso significa que o valor naquele
momento é esse valor Agora, para nosso jogo de arte Pix, quase sempre
usaremos o modo discreto
aqui na extrema direita Você pode ver esses três pontos. O que isso significa é
que o valor
não muda até atingir o ponto
do quadro-chave. Em algo mais
parecido com um jogo em três D, você pode fazer uma animação
contínua, o que significa que ela gradualmente
alternará entre
os valores dos quadros-chave Portanto, se você tivesse algo
como um quadro-chave de posição
, ele animaria
a posição
entre a posição inicial de zero e a
posição final de 100 ao longo
do tempo à medida que a
linha do tempo da animação progride Portanto, muitas animações em jogos
estão, na verdade, apenas alterando os valores das propriedades do
seu objeto com o passar do tempo. Ok, então continuando com os quadros em V, podemos clicar com o botão direito do mouse para inserir uma chave. Você verá que o valor aqui, se clicarmos com o botão esquerdo
no quadro-chave,
já está definido como um.
É isso que queremos. Mais uma vez, se olharmos para
a planilha de sprites do Idol, ela tem quatro quadros H, quadros
horizontais e um quadro vertical em
termos de linhas e colunas É por isso que temos quatro para quadros
H e um para quadro V. Não
precisamos fazer muita personalização aqui. Só precisamos
garantir que, no início, ele esteja definido com esses valores para
que nossa animação seja
reproduzida corretamente. Agora, o que realmente
precisamos fazer é colocar nossos quatro quadros
de animação aqui. Então, clique com o botão direito no primeiro
quadro e pressione a tecla Inserir. Você verá que, no quadro, ele realmente mostra uma
prévia do sprite Vai ser muito útil, mas você também pode clicar com o botão
esquerdo sobre ele e ver que está definido como
valor zero. Agora queremos passar para 0,1. Se você ainda não escolheu aplicar encaixe ao
cursor da linha do tempo, você pode fazer isso aqui Isso tornará muito
mais fácil ir para 0,1. Acho que você também pode digitar
manualmente o valor se quiser
entrar na linha do tempo No entanto, costumo tirar fotos com
o cursor do mouse. Em seguida, clique com
o botão direito na seção do quadro, na linha do quadro e insira a tecla. Agora você obterá uma linha
que vai entre eles. Essa linha significa que
não há mudança de valor
entre aqui e aqui. É apenas uma continuação
do mesmo valor. Então, queremos clicar aqui
e mudar isso para um, e isso significa que
agora ele
reproduzirá o segundo
quadro da animação. Como a folha Bright é
como uma matriz de valores, ela começa em zero, não em um. Geralmente, na programação, é assim
que funciona. Então, um é na verdade o segundo
quadro da animação e zero é, na verdade, o
primeiro quadro da animação. Vamos clicar com o botão direito do mouse em
0,2, inserir uma chave, clicar no ponto do quadro-chave
e, em seguida, alterar
o valor para dois
e, em seguida, ir aqui para 0,3. À direita, clique na tecla de inserção. Clique aqui, mude para três. Agora, você não deve mais ver
nenhuma linha entre nenhum
desses quadros. Podemos começar aqui, clicar em play e aí está nossa
animação para o personagem. Agora, mais uma
vez, como estamos
fazendo apenas animação à esquerda e à direita, precisaremos fazer apenas uma animação de ídolo, uma morte e uma
corrida aqui E então
controlaremos a inversão
do personagem de uma
maneira diferente . Eu vou te mostrar
isso mais tarde. Portanto, uma configuração muito mais simples e muito mais fácil de adicionar novos personagens, se você
quiser fazer isso Então, vamos realmente duplicar essa animação porque muito disso
vamos reutilizar Vamos apenas
alterar talvez o valor do quadro He e a textura. E dependendo de quantos quadros de
execução existem, podemos alterar os
quadros aqui também. Mas vamos duplicar
clicando aqui na animação e duplicar,
e vamos fazer Ok, agora queremos
clicar na textura, arrastar
e soltar a
planilha run sprite e ir até aqui Podemos ver que isso tem seis
quadros de animação. Então, o que isso significa
é que precisamos alterar o valor dos quadros H aqui para seis. Queremos alterar a duração da
animação para 0,6 porque estamos trabalhando em
seis quadros agora, não em quatro. E então vamos querer
ir para 0,4 segundos e adicionar o
quinto quadro da animação. Então insira a chave, clique aqui, altere o valor para quatro no quinto quadro e
depois vá para 0,5 segundos. Clique com o botão direito aqui,
insira a tecla, à esquerda, clique no quadro-chave, altere
o valor 4-5 e pressione play E aqui está nossa animação redonda. Portanto, a duplicação economiza
muito tempo. Ok, agora vamos adicionar a
animação da morte enquanto estamos em andamento. Então, vamos duplicar
e adicionar a morte. E então queremos
mudar a textura aqui, é
claro, para a folha da morte da
noite. Então, arraste e solte a folha de morte no inspetor de quadros-chave Eu posso contar aqui. Há
seis quadros. Então, vamos clicar. Na verdade, não precisamos
mudar mais nada porque
apenas o duplicamos de um
lado para o outro. Podemos simplesmente clicar em Play. Mas você pode ver que está girando. Então, os personagens
geralmente não fazem isso. Então, queremos realmente desativar o loop clicando duas vezes aqui. Isso fará com que a
animação seja repetida para frente e para trás. Tipo, vai até o final
e depois volta ao início. Isso seria mais útil para algo como
uma plataforma móvel. Queremos clicar
uma segunda vez para desativar completamente o loop. Então vá para 0.0, aperte play e a animação deve
parar aqui no final. E depois que a
animação da morte for feita posteriormente, só
precisamos
fazer algo como decifrar um fim de jogo
para nosso personagem, e pronto. Ok, então qual animação realmente será reproduzida
quando rodarmos o jogo? Bem, vamos clicar em
play e descobrir. Ok, então você pode ver que a animação
ociosa está lá, mas na verdade não está reproduzindo
nenhuma animação Na verdade, não configuramos uma animação para
reprodução automática no início Nossas animações
acabarão sendo
controladas com algo
chamado máquina de estado Isso será o que abordaremos
mais no próximo vídeo. Vamos clicar no reprodutor de
animação e mudar a animação aqui que estamos vendo
da morte à corrida. E clicaremos
aqui neste pequeno botão de
Reprodução Automática ao Carregar Então clique em reproduzir
e agora você verá
que, independentemente de nosso personagem estar
se movendo ou não, ele reproduzirá
a animação de corrida. Observe que ele também não muda de
direção automaticamente. Esse será um script simples que também
adicionaremos mais tarde. Mas temos três animações
em nosso personagem e podemos
alternar entre elas
chamando-as pelo nome No próximo vídeo,
criaremos a máquina de estado com um estado de movimento que poderá alternar
entre ocioso e Executar
6. Máquina de estado do jogador: Ok, então nosso personagem tem um reprodutor de
animação e
a habilidade de reproduzir a animação de corrida, mas queremos alternar entre animações de
ídolo e de corrida,
dependendo se há uma entrada importante para
nosso personagem ou Então, vamos controlar isso
com uma máquina de estado. Então, se você se lembra, no
início do curso, adicionamos o Limbo AI, que é uma máquina de estados e sistema de árvore de
comportamento que você pode usar imediatamente no Gado, economizando muito trabalho, sem
precisar fazer isso manualmente Vou usar
máquinas estaduais para o curso. Acho que é um
pouco mais fácil trabalhar com eles daqui
para frente e muito melhores para configurações
simples como essa E isso é, para ser honesto,
uma configuração muito simples. Então, vamos clicar com o botão direito do mouse no jogador na
base em um nó secundário. E vamos
procurar a palavra-chave limbo. Então você verá aqui Limbo HSM estado hierárquica Como no nó raiz aqui, a própria máquina de estados
controlará os estados, os estados do limbo, e será capaz de
alternar
entre eles à medida que adicionamos
transições entre esses Então, vamos criar o Limbo HSM. E então eu vou
clicar com o botão direito do mouse aqui e vamos
adicionar nosso primeiro estado,
adicionar um nó filho. Então, queremos um estado limbo
e simplesmente criá-lo. Portanto, a hierarquia é a máquina de estados
raiz, e todos os estados são o
que podemos alternar entre E cada um desses estados
executará código
diferente, dependendo do estado em que o personagem está. Para este curso, na
verdade, só
teremos um estado de mudança
e um estado de morte. Então, muito simples. Mas ainda é importante
porque queremos
saber quando nosso personagem deve
passar para o estado de morte, e o estado de movimento controlará as animações de
inatividade e movimento Tecnicamente, você pode separar Idle e mudar para
seus próprios estados, mas eles basicamente
executarão
o mesmo código porque, independentemente de
o personagem estar o mesmo código porque, independentemente de
o ocioso ou em movimento,
o movimento
do personagem ainda é livre É só uma questão de qual animação ele
vai reproduzir. E eu não acho
que isso necessariamente justifique um estado completamente
separado Então, vamos
clicar com o botão direito do mouse no Limbo HSM, e eu vou
anexar um script a Isso será chamado,
digamos, de player underscore HSM. Portanto, é a máquina de estado
hierárquica do jogador. Vamos criar isso. E então, aqui no topo,
vamos, é claro,
dar a ela o nome da
classe, player HSM modo geral, como
mostrarei no sistema de arquivos aqui, se pesquisarmos HSM, o
que quer que você coloque como minúscula
para o nome do arquivo, você também gostaria de ter o nome da classe aqui, mas isso, é
claro, tem
letras maiúsculas e você
pula os espaços porque esse
é um símbolo de tipo aqui em cima claro, tem
letras maiúsculas e você pula os espaços porque esse
é É uma boa ideia manter esse nome e o nome do script
sincronizados Portanto, o HSM do jogador nos ajudará
a controlar o corpo do personagem do jogador por meio dos estados que
existem no Limbo HSM Então, queremos pegar
o jogador e configurá-lo como o agente que
a máquina de estado controla. Ok, então primeiro, para
nosso player HSM, queremos uma referência
ao player que nossa máquina de
estado gerenciará Então, vamos exportar var
player do tipo player. E se definimos
o nome da classe para script corporal do jogador do
nosso personagem como jogador, isso
deve aparecer bem. E você pode ver no inspetor aqui à direita
que ele apareceu Então, se quiser, você pode clicar em Atribuir e atribuí-lo
ao jogador agora mesmo. Isso significa que nossa máquina
hierárquica de estados do jogador agora tem uma referência
ao Então, o que queremos
fazer é garantir que, no Rady, esse script configure
a máquina
de estado inicializando-a com
o player como agente Então, vamos criar uma função, sublinhar Rady, e o
tipo de retorno será nulo Quase sempre é para
funções prontas, porque essa é uma função de nó padrão
destinada a configurar seu nó, como em um desses nós
aqui à esquerda, algo que existe dentro de sua cena depois que todas as suas
propriedades foram definidas. Portanto, a função ready
executa o código que, quando
o objeto estiver pronto, executará algumas etapas
finais de configuração É muito comum usá-lo antes que o objeto realmente
comece a rodar na cena, mas seguindo as etapas essenciais de configuração
final. Enquanto
prosseguimos com isso, também
vou apresentar
alguns novos conceitos. Então, primeiro, a declaração
de afirmação. Então, vamos digitar assert. Então, isso significa que você passa
em alguma condição e espera que ela seja
avaliada como verdadeira. Então, neste caso, o que queremos verificar é se o jogador realmente
foi colocado no inspetor Sempre que você define uma variável de
exportação aqui, basicamente depende
do designer ou de quem está configurando o projeto do jogo para
realmente preencher esses campos, e é muito fácil definir um deles, especialmente se você tiver
muitos scripts
rodando com essas variáveis de exportação Eles são muito convenientes para configurar coisas
no inspetor, mas estão sujeitos a erros do usuário Portanto, podemos apenas afirmar que
o jogador não é nulo. Agora você vê que eu faço um ponto de
exclamação e depois um sinal de igual. O ponto de exclamação significa que você
inverte tudo o que está
tentando testar Portanto, se o jogador for igual a nulo, o que na verdade seriam
dois sinais iguais, você verificaria se o jogador
é Mas se você fizer um ponto de
exclamação e um sinal de igualdade
, estará dizendo que o jogador
não é e, sempre que
fizer uma declaração, você também terá a opção
de passar
uma mensagem de falha opcional Então, o que você quer
dizer para quem está executando o script quando essa
condição não foi verdadeira Então, nesse caso, eu
gostaria que algo como agente
do jogador
fosse configurado no HSM Então, máquina de estado hierárquica. Então, estou apenas
colocando aqui no topo, mencionando muito
claramente que essa é uma máquina de estado hierárquica Então, se você tiver alguma
dúvida sobre por que o HSM está, bem, está lá em cima, então
vamos mostrar isso em ação Se eu executar a cena, não haverá erro
porque definimos nó
do jogador como referência
na
variável de exportação de um jogador. Mas se eu desmarcar
o player aqui e o executarmos, você receberá uma mensagem de erro
imediata Vai dizer que a
afirmação falhou. O agente do jogador deve
estar configurado no HSM. Portanto, a afirmação é
apenas uma verificação para
garantir que o que você espera que
seja verdade é realmente verdade Portanto, escrever declarações
contra uma condição é a ideia geral de testar dentro da programação
em geral. Para ir mais longe do que isso, você escreveria testes unitários
ou testes de integração usando uma estrutura de teste como GD Unit ou o teste unitário
GUT Godot Isso definitivamente vai
além
do escopo desta série de cursos, mas é algo que você deve
pesquisar se tiver tempo mais tarde,
pois escrever testes garante que seu código
esteja realmente bem escrito e possa ser
útil a longo prazo. Pegando insetos cedo. Então,
vamos continuar com isso. Só vamos usar essas
pequenas declarações afirmativas como essa. Você pode
ver como isso funciona. Se a condição falhar
, recebemos uma mensagem que nos informa que, oh, esquecemos de definir algo que deveríamos
ter definido Então, na verdade, é muito útil. Então, vamos garantir
que, no Limbo HSM, mais
uma vez,
atribuamos o player E então vamos fazer a
configuração do próprio HSM. Então, eu vou realmente
fazer disso uma
função separada porque isso vai fazer algumas coisas
diferentes. Então, vamos criar outra
função aqui embaixo, função. E quando eu digo função, eu realmente quero dizer FU
e C, basta dizer. sublinhado configurou o HSM
e, em seguida, os parênteses, a seta giratória e o vazio Então, o que queremos chamar
na máquina de estado é inicializar e precisamos passar um agente Como mencionei, o
agente, neste caso, é o jogador que
passa o jogador
e, em seguida, precisamos
chamar o HSM configurado Dentro da função pronta. Então, sublinhe a configuração do HSM. Ok, então, para explicar isso, estou tornando-a uma
função privada com o
sublinhado aqui, que
significa que
só devemos executar isso dentro desse script HSM do
player A inicialização faz toda a configuração
em segundo plano da máquina de estado e fará com que ela opere com o
player como agente A outra coisa que precisamos
fazer aqui é definir o estado inicial. Então, qual estado vamos
executar primeiro? Vamos também renomear o nó Limbo
HSM para player HSM. Também gosto de manter esse tipo de sincronizado com o
script anexado a ele Então, toque HSM aqui. É igual ao player HSM dentro
da janela da cena. E então o estado Limbo aqui, chamaremos isso de estado de movimento e anexaremos um
novo script a ele Além disso, se você
renomeá-lo antes
de anexar o
script, se você
clicar com o botão direito do mouse no estado e
anexar o script agora, verá que o nome do script também é padronizado
para o nome do Portanto, manter essas três
coisas sincronizadas geralmente é uma boa ideia
para
manter as coisas organizadas E vamos salvar isso
na pasta do player por padrão por enquanto, e vamos herdar do estado
Limbo Crie. Ok, então eu vou
chamar isso de estado de movimento, nome
da classe estado de movimento. Na verdade, podemos reutilizar
isso para o inimigo também. Uma vez que todos eles
usarão
essencialmente a mesma configuração de animação. Então, no estado de movimento,
precisaremos dos nomes de
duas animações, que são nossa animação ociosa
e nossa animação em movimento,
que é Então, eu vou dizer
export para Idl anim, e vamos
configurar esse tipo para um nome de string E vamos padronizar
o valor para Idle. Agora, colocar o e comercial aqui para torná-lo um
nome de string é, na verdade Quando é declarada como
um nome de string aqui, a variável, ela será
convertida automaticamente. Portanto, é opcional se você
quiser fazer isso como Ah, então vamos fazer export var. Vou chamá-la de run
animation porque é assim que ela será chamada por padrão neste projeto, e faremos equals e ampersand Colocar alguns comentários aqui duas hashtags, faz com que os comentários
apareçam no inspetor Então, se eu for até o inspetor
e passar o mouse sobre a animação ociosa, você pode ver que os
comentários realmente
aparecem lá automaticamente, o
que é Você também pode ver
como a propriedade é definida como um nome de string com um valor padrão de idle ou
run para o. Para isso,
queremos ter certeza, verificando o player de animação, de
que nossos nomes coincidem Então você pode ver que eu estava fazendo um ídolo em
minúsculas, uma corrida em minúsculas. É sensível a maiúsculas e minúsculas quando
você usa essas cordas. Portanto, certifique-se de que
corresponda aqui e aqui, o que quer que apareça no reprodutor de
animação
para inatividade e execução Ok, então vou clicar com o botão
direito do mouse no nome do estado do
Limbo aqui
e procurar o símbolo E você verá
que há vários métodos
especiais para entrar,
sair, configurar e atualizar
esse nó . Portanto, esses são métodos
específicos do estado. Eles soam meio parecidos. Para o que você teria em
um nó Gadot padrão. Mas a diferença é
que eles só são executados quando a máquina de estado está
realmente usando esse estado. A máquina de estado
executa apenas o código de um
dos estados por vez, e os outros estados
basicamente ficam lá passivamente até a máquina de estado
determine que é
hora de fazer a transição para
um estado diferente Isso significa que você pode
escrever basicamente quatro conjuntos de código e apenas um
será executado por vez,
e isso é muito útil para
evitar que coisas desnecessárias aconteçam enquanto
seu personagem não
deveria estar fazendo essas coisas Por exemplo, um personagem
não deveria atacar quando está apenas correndo e não há nenhuma entrada de ataque Portanto, você não permite que esse código seja executado
gerenciando-o com uma máquina de estado. Ok, então queremos começar
com essa função enter. A palavra-chave virtual para
essas funções aqui significa que, embora possa haver uma implementação padrão
para a função, podemos escrever nosso
próprio código personalizado, que muda completamente o que ele faz quando essas funções
realmente são executadas. Vamos dar uma olhada no script de estado de
movimento e vamos fazer a
função underscore Enter Então, o que queremos que ocorra quando o estado de movimento entra dentro
da máquina de estado? Então, queremos pegar
o reprodutor de animação e definir sua
animação para inativa ou executada dependendo se o personagem
está se movendo ou não Ok, agora para o nosso estado de movimento, como vamos
obter uma referência ao player de animação? Então, a ideia é que,
para nosso agente, ele tenha apenas
um reprodutor de animação, o reprodutor
de animação do jogador. Existem várias
maneiras de realmente
obter essa referência dentro
do seu script Move State. Vou tentar mostrar aquela
que, do alto da minha cabeça, acho que seria a
mais prática aqui. Então, se formos para o player HSM
, podemos exportar uma referência
para o player de animação Então, vamos exportar o player de animação
var
e, em seguida, o player de animação Colon Ok, um comentário para deixar
claro que esse é o reprodutor de animação do jogador, e então o
atribuímos no inspetor Agora, a razão pela qual estou
fazendo isso neste script, em vez dos
scripts infantis, como nos estados, é que eu quero apenas uma referência
exportada aqui
e, em seguida, usaremos
isso para obter o reprodutor
de animação dos nossos scripts de estado Então, se entrarmos no script de estado de
movimento, eu poderia rapidamente
obter a referência que o player HSM
aqui no topo tem fazendo algo como get parent e depois
dot animation player Então, isso é realmente tudo que
você precisa fazer lá. E agora podemos atribuir isso a uma variável local, se quisermos. Outra opção seria
ter um método que sempre obtivesse isso ou
armazená-lo em cache aqui localmente. Então, só precisamos
pegar esse valor aqui e atribuí-lo
a uma variável local. Até agora, vou dizer reprodutor de
animação de sublinhado, que é do tipo reprodutor de
animação Então, pode estar em Enter, mas vou alterá-lo
para configuração mais tarde. Vamos fazer o Underscore
Animation player. Iguais, Get Parent. Sim. Você pode
vê-lo como preenchimento automático, livrou-se do nome da
função lá Esta deve ser sua linha
completa aqui. No Enter agora,
ele atribuirá o reprodutor de animação
a qualquer que seja o reprodutor de animação dos pais. Então, isso torna tudo um pouco
mais fácil do que ter que ter referência de variável de
exportação em
cada um desses scripts de estado. Em vez disso, os scripts de estado dependem apenas o pai ter uma referência
ao reprodutor de animação, que eu acho justo,
porque o HSM
do jogador realmente controlará as animações
do player de qualquer Então, acho que a configuração
faz sentido nesse caso. Agora, em vez de usar Enter, que será chamado toda vez o personagem entrar no estado, implementarei
a função de configuração. Função,
configuração de sublinhado e, em seguida preenchimento automático que retorna vazio Vamos pegar essa linha e
colocá-la aqui desse jeito. Portanto, a configuração só é executada uma vez quando a
máquina de estado é inicializada Então, basicamente,
não precisamos obter o reprodutor de animação toda
vez que entramos no estado, apenas uma configuração definida. Agora, o que queremos que ocorra em Enter é que toquemos
a animação certa. Então, no momento, não
temos a maneira correta de determinar a animação
porque nosso código para isso está, na verdade, preso
no script do player, com essa direção sendo definida como
uma variável local Então, teremos que
retirar isso mais tarde para que funcione totalmente. Mas o que podemos fazer agora é reproduzir pontos no player de animação e digamos que vamos começar
com a animação ociosa Agora, não, estou colocando
a variável aqui, uma referência à animação ociosa, que resolverá
o nome da string Então, isso espera um nome de string, mas não é difícil
digitar isso aqui Queremos ter certeza de que
é a variável para que ainda tenhamos a opção de alterá-la no
inspetor, se isso fizer sentido Geralmente, via de
regra, se você tem algo que deseja
alterar, que é uma string, você deseja trazê-la para
algum tipo de variável em
vez de digitá-la toda vez que fizer referência a
ela no mesmo script Às vezes, se a mensagem só
for usada uma vez naquele
local específico, não há problema em digitar
a string do seu código no
código da função. Isso também pode ser bom.
Ok, então ele reproduzirá a animação inativa
assim que o estado de movimento começar Agora, para testar isso,
queremos desativar
a execução automática dentro
do player de animação. Ou talvez não o façamos, na verdade. Vamos parar o jogo
e executá-lo como está, e ele deveria realmente entrar na animação inativa,
ou assim eu pensei Então, vamos tentar desligar
a reprodução automática ao carregar aqui. Agora, sem o Autoplay no carregamento, acho que não deveria funcionar nada Então, ainda temos o problema de parecer que o estado
não está entrando porque a
animação não está sendo reproduzida. Então, o que podemos fazer para provar isso é voltar
ao editor de scripts. E vou
definir um ponto de interrupção aqui clicando com o botão esquerdo
à esquerda do
número da linha no script. E isso significa que, quando atingir essa linha de código, ela será interrompida e nos
permitirá ver o que
está acontecendo no debuker Então eu vou apertar play, e não vai bater lá, que significa que o estado nunca realmente entrou.
Não está ativo. Isso significa que precisamos
voltar ao script do HSM e garantir que
o estado de movimento esteja realmente ativo no
início do jogo Então, vamos entrar no player HSM. E acho que o que eu esqueci
aqui foi realmente chamar set ativo no próprio
player HSM Então, queremos definir ativo como verdadeiro. Inicializamos, o que
executa a configuração, mas não o ativamos, que na verdade faz com que a máquina de
estado comece a funcionar Então, agora, se clicarmos em
play, atingiremos a linha Enter
no estado de movimento. Então, isso prova que o estado de movimento está realmente sendo reconhecido pela máquina de estado Para detalhar um pouco mais, você pode observar o
rastreamento da pilha na parte inferior
e ver, se
ler com atenção, que a função de
entrada do estado de movimentação foi executada
e executada após a execução do HSM de configuração,
e você pode realmente clicar
aqui e pular para a linha de código,
o
que fez com que Enter fosse e você pode realmente clicar aqui e pular para a linha de código,
o executado no estado de movimentação Consulte set Active true aqui, que chama Enter no
primeiro estado executado. E tudo isso ocorreu,
se você clicar na linha inferior
do HSM
pronto para configuração Então você pode ver, basicamente, o que
fez com que entrasse fosse chamado. Então, foi a função pronta
no HSM chamada de configuração HSM,
que chamada set active e, em seguida,
set active fez com que o estado de
movimento Então, agora, se ainda não o fez, você pode desmarcar esse
ponto de interrupção e clicar aqui para continuar ou pressionar F
12 no teclado e ver que o
estado ocioso será executado Se você quiser mudar
isso para o estado de execução, então vamos executar aqui e substituir play Idle pela animação play
run, clique em play E agora você pode ver
que ele está reproduzindo a animação de execução quando
o estado entra. Então, no próximo vídeo, vamos nos
concentrar em realmente controlar o estado do movimento com
a entrada do jogador para garantir que estamos reproduzindo a animação
certa no
momento certo.
7. Entrada do jogador como componente: Nosso estado de movimento é reproduzir a animação no
reprodutor de animação do nosso personagem, mas no momento ele não
tem o código para saber quando mudar
para a animação de execução, quando há uma entrada real do
jogador. Então, para lidar com isso, se
olharmos o script do jogador, podemos ver que é
aqui que a direção está sendo adquirida para o jogador, e estamos fazendo isso com uma
variável local para a direção. Então isso funciona para essa função de processo
físico, mas não podemos usar a direção de entrada
em nenhum outro lugar, exceto aqui. Então, gostaríamos de trazer
isso para algum tipo de variável de propriedade que possa ser acessada
por outros scripts. Agora, poderíamos fazer algo como direção
VR aqui do vetor dois e depois mudar
aqui para definir a direção da
variável local. E essa provavelmente
seria a opção mais simples. Juntos. No entanto, acho que se continuássemos seguindo
esse caminho e colocassemos todas as informações dentro do script corporal do
personagem do jogador
, estaríamos realmente quebrando
uma separação de preocupações. Portanto, o script corporal do
personagem do jogador consiste principalmente
em mover o jogador. Se adicionarmos todas as funcionalidades de
entrada, adquirindo todas as informações dos
jogadores
, agora o script
servirá a
dois, três ou
até mais propósitos à dois, três ou
até mais propósitos medida que continuamos bagunçando
o script do player Então, vou tentar trazer isso
para um script de nó separado
que nosso script de jogador
ainda pode usar, mas também podemos fazer
referência a, digamos, nossos estados para lidar com todas as entradas de nosso personagem de
jogador. Então, vamos clicar com o
botão direito do mouse no nó do jogador e eu vou
adicionar um nó filho. Vamos digitar node aqui. Então, essa será apenas uma classe
básica de nós, create. E eu quero renomear
isso para ser a entrada do jogador. Vamos anexar um script a ele. Clique com o botão direito do mouse em anexar
script, entrada do player. E podemos dar
a ela o nome da classe entrada
do player para
que ela possa
ser facilmente referenciada em uma variável de
exportação Agora, a partir do nosso script de player, precisamos basicamente pegar isso, e eu vou controlar C, colá-lo na
entrada do player, para que eu possa colocá-lo lá. Mas onde queremos
realmente obter a direção é dentro do método de entrada. Então, agora no script do
jogador, processo
físico está executando cada
quadro de processamento físico do nosso jogo, o
que, por padrão, é
algo em torno de 60 vezes por segundo Provavelmente não estamos pressionando
as teclas 60 vezes por segundo, então essa é uma chamada
vetorial muito
desnecessária e provavelmente não
importaria muito
para o personagem de um jogador. Mas, em geral,
acho que pode ser um pouco melhor no script
do player lidar com
a entrada de direção
dentro do método de entrada de
sublinhado da função Então, a função underscore
input, basicamente, sempre que um evento de entrada
for enviado para o jogo, ele
passará por esse método e verá se há algum
código para responder E a maneira de verificar se o evento é
realmente relevante para nós é basicamente verificar o nome da ação
no próprio evento. Então, vamos digitar if, e eu vou
criar um novo método se o
sublinhado for ação de movimento E vamos passar
o evento para essa função. Então vamos
fazer algumas coisas. Caso contrário, vamos
simplesmente passar e não
fazer nada ainda. O que é a função de
ação do movimento I? Normalmente, estamos apenas nos protegendo contra outros tipos de ações e só queremos processar a entrada se
a ação
for uma ação de movimento Então, diremos que função
é ação de movimento. Do tipo evento, evento de entrada. E então isso retornará um booleano. Portanto, um booleano é um
verdadeiro valor falso. É uma ação de movimento? Verdadeiro ou falso? Então, isso vai ficar mais
ou menos assim. Retorne o evento que é ação
e, na verdade, vamos apenas copiar e colar esses
nomes por enquanto. Ok, então podemos ver
aqui que estou repetindo a mesma string aqui
que está aqui em cima Então, geralmente, eu tentaria trazê-los para sua
própria variável separada. Mas nós poderíamos Sim, por que não
fazemos isso agora? E então eu vou te mostrar um passo podemos ir além disso, até mesmo. Então, vamos colocar uma variável aqui, Var left action ou, na verdade, digamos que var left
é do tipo string name, e será igual
a esse valor aqui. Então, vamos Controlar C, copiar isso, colar aqui e, em seguida,
selecionarei isso novamente. Vou pressionar Control
R para localizar e substituir, e vou
substituí-lo pela esquerda. Agora, quando você estiver
usando essa ferramenta, ela substituirá o que
você selecionou atualmente. Então, eu quero substituir isso nome
à esquerda, então
vou clicar em Substituir. Agora, a segunda,
para a qual
ele vai pular automaticamente ou talvez
não. Uh, aqui, queremos manter
a cotação Ampersand à cotação Ampersand Então, vamos clicar em Próxima partida, e descobriremos
aqui embaixo que queremos
substituí-la pela
esquerda, então clique em Substituir. E isso vai ser
basicamente isso aí. Provavelmente também
deveríamos cuidar
dessa mensagem de erro
agora. Então, vou declarar
essa direção distante e nos preocuparemos atribuí-la
corretamente em um minuto Ok, para eliminar a mensagem
de erro, você pode salvar o
script por enquanto. Então, agora, a ação
do movimento I está retornando se a
ação é a ação da esquerda. Então, o nome
da ação
no evento corresponde ao nome restante? Agora, temos três
outras ações, então precisamos verificar três
outras condições aqui. Então, vamos revelar isso rapidamente. Vou selecionar
esse Controle X para cortá-lo, digite corretamente. Vá até aqui, crie uma
nova variável var right, nome da
string igual e, em seguida,
controle V para colá-la Portanto, temos a variável atribuída ao nome da
string à direita. E faça a mesma coisa
para cima. Então selecione isso. Controle X para cortar, digite. Desça até aqui. Var up é do tipo string name e é igual a Control V para colá-lo N. E apenas mais uma vez
. Controle X. Digite abaixo, vá
até aqui, abaixo, nome da
string é igual,
Controle V, cole Ok, agora temos nossas quatro
variáveis que correspondem
aos nomes reais das strings que estamos realmente passando
para métodos como esse. Se quiser outro truque divertido, você pode tabulá-los
assim,
selecionar logo atrás da aba de acerto de sinal
igual,
atrás da aba de acerto senoidal igual,
atrás da aba de acerto de sinal igual,
atrás da aba de
acerto de igual sinal, desse jeito E você pode realmente
alinhar tudo isso
e ficar bonito
e tudo mais. Pode ser um pouco mais legível. Depende de você se você gosta
de ter a aba ou não. Ok, mas agora o
importante é terminar esse método, precisamos verificar
as outras ações. Então, vamos fazer espaço. E então o caractere de
linha reta, que é shift e logo abaixo do backspace, a linha
vertical Então, a
linha vertical, a linha vertical, e você tem que manter a tecla Shift pressionada para fazer isso, pelo
menos no meu teclado. Então, essas duas
linhas verticais significam ou. Eu acho que você poderia realmente
digitar ou gostar disso, e seria o mesmo. E poderíamos
tentar que, se isso realmente for um pouco mais fácil de ler e fazer, o
evento ponto é ação, e queremos Right. Espere aí. Escreva o nome da
variável. Bom. Então,
parece que isso funciona. Então, vamos fazer isso de
novo ou se eu aumentar a
ação ou evento
for ação negativa. Ok, então espero
que isso faça sentido. Estamos verificando se o
evento é ação esquerda, ação
direita,
ação positiva ou ação negativa. Agora, essa fila está meio
longa. Você pode ver isso como um ponto de
corte na vertical. Então, essas são apenas diretrizes
gerais aqui. Você pode ver que
temos 107 caracteres nesta linha. Não é um problema. Quer dizer, acho que é
bem legível, mas se você quiser que seu código fique
mais vertical
, você pode
dividi-lo aqui pressionando Enter Agora, se eu pressionar o Controle S aqui, isso vai nos causar um problema. Será a
expressão esperada após ou. Portanto, atualmente não sabe que estamos tentando
pular para as próximas linhas. Então, o que você realmente
precisa fazer é colocar uma barra invertida logo após o O, e agora ele sabe que isso
continua na próxima linha Então você pode continuar fazendo
isso desta forma, inverta Enter para
colocar uma nova linha e, em seguida, inverter Enter
e colocar Agora, eu diria que isso
parece bem limpo aqui. Então, temos nossas quatro condições, e ele
verificará todas elas, e assim que uma
delas for avaliada como verdadeira, ela retornará verdadeira E se nenhum deles for
verdadeiro, então é falso. Então, se a ação for
uma ação de movimento, poderemos
processar nosso código de movimento. Ok, então é aqui que
realmente atribuímos o vetor. Há dois lugares em que
vamos usar a entrada. Uma é para a direção voltada e a outra é para a direção do
movimento. Então, vamos pegar a
variável para a entrada. A entrada Var é do tipo vetor dois, vamos defini-la igual
ao vetor Importar ponto G. E, assim como antes, queremos esquerda, direita, para cima e para baixo. OK. E aí está nossa opinião. Então,
sempre que pressionamos qualquer tecla, queremos definir a entrada
direcional Então, a direção será igual a qualquer valor de
importação. Mas com a direção voltada, é um pouco especial. Um personagem em um jogo de quatro
direções e dois D não pode encarar o vetor 00 porque isso seria basicamente
olhar para si mesmo, não olhar para a direita, para
cima, para a esquerda ou para baixo, que são as únicas
direções que ele pode olhar Quando atribuímos
o vetor oposto, só
queremos fazer isso se
a direção não for zero Portanto, se a entrada não for
igual ao vetor 20, para um vetor com duas
direções de zero, isso significa que X é
zero e Y é zero, lembre-se de que os vetores têm componentes
X e Y. Então, dado que essa
condição está definida, podemos pegar a face
e configurá-la para a entrada. E vamos nos livrar
desse pequeno passe aqui porque não precisamos disso. E então, no topo aqui, var voltado para o vetor tipo dois. Podemos simplesmente usar como padrão
, digamos, o vetor de dois pontos à direita,
o que funciona perfeitamente. Se
sempre se espera que nosso personagem fique
voltado para a direita por padrão durante o carregamento, é claro
que
você pode virar para a esquerda, se quiser. E então, na direção aqui,
queremos
substituir isso pelo vetor dois ou, se você
quiser ser um pouco mais sofisticado, embora esse também seja o valor
padrão, poderíamos dizer que dois pontos são iguais ao
vetor Então, isso aqui
na verdade significa que estamos inferindo o tipo da
variável a partir da atribuição, e a atribuição
é um vetor dois, que significa que isso
será automaticamente atribuído
a um vetor dois, que significa que você
não precisa digitar esse vetor dois é
igual ao vetor dois Isso parece meio engraçado. Então, da mesma forma, você também pode fazer isso aqui embaixo. E torne-o um
pouco menos prolixo, embora ambos funcionem
perfeitamente bem aqui A única desvantagem
é que, se você
transformar esse vetor de dois pontos à direita em algo como uma string, isso também
estará tecnicamente correto,
porque agora está atribuído à sequência do vetor
de dois pontos à direita,
e
isso significa que agora é uma string e
isso significa que agora é uma Então, você tem que ter um
pouco de cuidado com isso. Na verdade, não vi
isso ser um problema. Então, acho que nesses casos, inferir o tipo
da variável em
vez de declarar
o tipo de variável diretamente é perfeitamente razoável e correto e, muitas vezes, um
pouco mais Então, depende de você, você pode fazer as duas coisas. Se eu estou vendo
as coisas corretamente, acho que esse é basicamente o
nosso script de jogador por enquanto. Voltaremos e adicionaremos
sinais um pouco mais tarde. Ok, então em nosso script de jogador, vamos mudar as coisas aqui. Então, em vez de ter
uma variável local para direção e atribuir a direção em vez
do processo físico, o que vamos fazer
é clicar em Exportar var. A entrada é
do tipo player E aqui no processo de
física, o que queremos fazer é obter a
direção da corrente a partir da entrada. Então, a direção var, e eu vou inferir o tipo da direção do ponto de
entrada, será atribuída
à direção local, e então usaremos
isso para o resto do nosso script, verificando a direção
é realmente
um valor que não vetor 20 é o que
essa linha significa E nesse caso, pegamos a direção e a multiplicamos pela velocidade A diferença agora é que a entrada é gerenciada por um script
completamente separado. Nosso script de jogador
é mantido mais limpo e temos um componente de
entrada de jogador reutilizável que
pode ser usado para designs de
personagens
completamente diferentes que precisam do mesmo
tipo de entrada do jogador,
mesmo que o personagem realmente
lide com a mecânica de
seu movimento de seu movimento Então, vamos clicar no script
do player e queremos ter certeza de
que a importação está atribuída. Então, como antes, o que
poderíamos fazer é colocar a função, sublinhado pronto, afirmar que a entrada não é nula
e dar entrada deve ser atribuída para o corpo do
personagem se mova corretamente, execute o jogo e veja se nossa
afirmação falha, o que é bom Clique no player e
atribua a entrada à entrada do player, execute-a mais uma vez e
veja se ela realmente funciona. E se você usar o WASD, poderá ver que
ele está se movendo com base na entrada
do nosso script de importação do
player
8. Troque animações com sinais: No momento, nossa entrada direcional de cima para baixo, para a esquerda e para a
direita, é controlada pelo script de entrada do
player, mas ainda não temos as animações controladas pela
direção desse script Então, se dermos uma olhada
no script de estado do movimento, poderíamos imaginar que poderíamos simplesmente
pegar uma referência à entrada
do jogador e começar
a usá-la como antes. Esse método, embora geralmente
funcione bem, depende do script HSM do
player, tendo uma referência a
todas essas propriedades Se alterarmos o script da máquina de
estado hierárquica do
player , a qualquer
momento, isso pode quebrar a forma como
esse script funciona, e o script também tem uma
espécie de dependência direta de
o pai ter todas Portanto, não
poderíamos reutilizar isso em uma
máquina de estado completamente diferente que não tenha,
digamos, um
player de animação exposto Então, o que você pode fazer como outra opção é
usar quadros negros Então, olhamos aqui à direita. Quando você
seleciona o HSM, você pode ver que o
plano Blackboard é uma Então, quando você cria
um plano Blackboard, ele informa a qualquer nós-filho
no sistema da máquina de estado a
que ele terá acesso E, nesse caso, queremos a direção oposta
da entrada do player. Então, vou criar um novo plano Blackboard
aqui no HSM do player e clicar Podemos ir até aqui
e adicionar uma variável, e queremos adicionar,
vamos usar a face. Então, quando falamos
sobre as animações, o que é mais relevante para nós é a direção que o
personagem está tentando
encarar , em vez da direção em
que o personagem está se movendo Normalmente, seriam a
mesma coisa, mas nem sempre. Então, teremos de frente para aqui
e, na lista suspensa, o vetor dois, para que possamos clicar em Gerenciar aqui e
adicionar uma variável E vamos procurar o vetor
de direção dois. Portanto, mude o tipo de
flutuador para vetor dois. E então podemos clicar em OK,
então, para obter essa
direção também e usá-la em nossos diferentes estados de máquina de
estado, queremos ir para vinculação
e, em seguida, direção, queremos
vincular isso ao script de importação do
player Mas se fizermos isso agora,
nada vai aparecer. Portanto, uma das limitações do sistema Lambo AI é que, para vincular uma propriedade
ao plano Blackboard, essa propriedade precisa
ser Então, se formos para a entrada do player, podemos seguir a orientação
aqui e simplesmente fornecê-la na exportação e depois salvar. Então você clica em Importar jogador, você verá que a
direção aparece aqui. Tecnicamente, isso
significa que você pode mudar a direção
antes do início do jogo Ela
será imediatamente substituída por essa função de importação
assim que você pressionar uma tecla Portanto, não há realmente
muita desvantagem. Só que a direção precisa ser exposta para que isso funcione. Então, no HSM, agora
podemos nos vincular ao script de entrada do
player e
procuraremos a propriedade Então escolha a direção
e clique em abrir. Ok. Então, se você leu isso agora, a direção agora está vinculada
à direção de importação do jogador, o
que significa que tudo o que definirmos na direção de importação do
jogador será espelhado
neste Blackboard, e poderemos usar isso nossos scripts,
como
o estado de Então, enquanto estamos
nisso, também podemos configurar o player de animação
no plano Blackboard,
o que eliminará
a dependência
entre o estado e o HSM Vamos gerenciar e adicionar uma variável, vou dizer um player de animação. E vamos digitar
e escolher o caminho do Node, acredito que é o que queremos aqui. Ok. Clique em OK. E atribuímos isso ao reprodutor de
animação. Portanto, agora, se lermos no Blackboard
o reprodutor
de sublinhado de animação da propriedade, poderemos obter uma
referência ao reprodutor de animação Ok, agora, se
formos para Move State, a
aparência disso será mais parecida com esta. Então, o player
de animação underscore será igual
ao Blackboard Portanto, o Blackboard é
criado em tempo de execução, com base no plano Blackboard Então, esse é basicamente
o objeto de tempo de execução em que obtemos as
variáveis de que precisamos. Então, precisamos fazer
Blackboard dot, Get VR, get underscore var e estamos procurando
o nome da propriedade Então, neste caso,
esse será o reprodutor de
sublinhados de animação O padrão será nulo. Queremos que ele reclame
se não conseguir encontrá-lo,
porque isso significa que erramos em algum lugar em nossa
configuração Agora, podemos basicamente
remover essa linha agora, e agora nosso script
não
depende nem um pouco do script HSM Depende apenas da configuração do Blackboard para ter
um reprodutor de animação, que receberá uma mensagem de erro se não tiver um
reprodutor de animação no Blackboard Então, agora, para a direção,
só precisamos atualizá-la
, eu suponho. Então, funcione, sublinhe,
atualize e
obteremos a variável atual do
Blackboard Então, essa
será a direção da realidade virtual. Será igual ao
Blackboard dot Get VR, e estamos procurando uma direção E não podemos inferir esse tipo de
variável porque não
sabemos o que o Git VR realmente retornará aqui Então, vamos declará-lo
como um vetor dois. Ok, agora temos
a propriedade de direção, e nosso script
nem precisa saber nada sobre o script de entrada do
player. Tudo o que precisamos saber é que o Blackboard tem uma propriedade de
direção e podemos usá-la
para nossas animações Então, de forma muito simples, se a
direção não for zero, essa é a forma
abreviada, então
vamos reproduzir a animação de execução
no reprodutor de animação. Então, sublinhe o player de animação, dot play, o run animation, Ale, o reprodutor de animação, o
dot play, a animação inativa Então, vamos clicar em Jogar
agora e ver se isso funciona. Então, se I WAS e D, você pode ver que obtemos o movimento
de
animação do nosso personagem. Agora, há uma grande falha aqui, que é que a compensação em
nossos sprites não Agora, essa é apenas a natureza de como as
planilhas de sprites específicas foram configuradas Acho que o tamanho de cada
moldura não coincide. Então, isso cria um deslocamento. Agora, isso seria algo que
você pode corrigir em um editor como O Sprite, se você for o artista, ou se
quiser apenas fazê-lo funcionar Nesse caso, podemos fazer isso
no reprodutor de animação Então, no reprodutor de animação, podemos ir para, digamos, vamos
verificar a animação ociosa E aqui está centralizado
aqui, como seria de esperar. Então, quando vamos para a animação de
execução de Run, precisamos apenas ter
certeza de que ela
corresponde à animação ociosa Então, vamos
querer enquadrar
a posição em cada uma
de nossas animações. Então, vamos adicionar uma faixa, faixa de
propriedade. Vamos ver, o
Sprite two D porque estamos falando sobre
o deslocamento do sprite,
não do deslocamento do personagem do jogador E então queremos uma posição aqui. Então, vamos adicionar uma chave. No momento, está em menos 14. Eu vou para Idle. E então vamos adicionar
a mesma propriedade com antecedência. Então posicione dois D e, em seguida,
adicione o quadro-chave aqui. O motivo pelo qual estou fazendo isso é porque a posição de marcha lenta já
está correta, então não quero que essa alteração seja alterada ao
configurar a corrida Enquanto estamos nisso,
vamos verificar a Morte. Acho que a animação da morte está realmente no lugar certo. Então, tudo o que precisamos fazer é ir aqui, adicionar a faixa, sprite
two D, posição Ok, insira a chave. Ok, e então isso
deve ser bom. Então, agora precisamos
alterar o valor da rodada para animação
especificamente. Então aperte Q para ir para o Modo
de Seleção. Clique com o botão esquerdo no sprite. Você deveria ter essa caixa grande. Você provavelmente pode ver de
onde veio o deslocamento daqui, porque há
muito espaço vazio aqui em cima Mas de qualquer forma, só
precisamos pressionar W e depois mover isso para a
direita. Deixe-me verificar a transformação.
Sim, 27 pixels negativos. Acho que era isso que eu tinha e estava
no rascunho do projeto. Então, vamos estruturar
isso. Vamos clicar em Play e ver se isso é melhor. Então, o WASD está quase lá, mas acho que precisa
estar alguns pixels mais alto Então, vamos W e
, em seguida, movamos isso para cima. Vamos tentar 30, acertar W. N
, ainda não está lá. Ok, vamos aumentar ainda mais. Vou ver a animação inativa. Ok. E é aí que seus
pés estão no chão. Então, vamos voltar a correr. Ok, e seus pés
devem estar aqui em cima, dois pixels abaixo da parte inferior. Ok, depois
fique ocioso e depois corra. Ok, eu esqueci de enquadrá-lo. Então, deixe-me mudar isso mais uma vez. Não acho que
precisemos do deslocamento X. Vamos enquadrar isso em
menos 30 pixels aqui. Ok, vamos clicar em play
e testar mais uma vez. WASD. Isso parece
correto para mim. Então, vamos continuar com isso. Vamos
pressionar Sop no player aqui. E só para ficar claro, para
uma solução de longo prazo, provavelmente
seria melhor corrigir as
folhas de pico de animação e apenas garantir que
todas tenham o mesmo tamanho, independentemente da quantidade de
movimento
nas animações, para que você não precise mexer longo prazo, isso é um
pouco mais difícil de gerenciar, então é melhor
fixá-lo diretamente
na folha de animação. Ok, então, para nossos personagens ficarem
ociosos e se moverem, a última coisa que
realmente precisamos fazer movimento básico de
nossos personagens
é fazer com que eles girem quando estamos nos movendo para a esquerda e depois voltem para trás quando
estamos nos movendo para a Esse será o próximo vídeo,
então nos vemos no próximo.
9. Virando um personagem 2D: Então, temos nosso movimento de cima para baixo, para
a esquerda e para a
direita do personagem, e ele pode voltar ao estado
ocioso. Isso é ótimo. O que precisamos
mudar aqui, porém, é que nosso personagem
precisa ser
capaz de virar da direita para a esquerda, dependendo se temos
uma entrada esquerda ou direita Então, queremos basicamente
virar o nó do sprite
da esquerda para a direita Agora, Sprite
tem diretamente um flip H aqui. Certamente poderíamos
simplesmente dizer em
um script personalizado que inverta o H
com base em tudo o que a entrada do
player faz Para dar um passo um
pouco distante disso. Em vez disso, o que poderíamos fazer é
colocar um nó pai que se vira quando a
direção voltada para a entrada do jogador muda, e então isso inverterá
automaticamente o nó do sprite porque
o nó do sprite é filho desse
nó pai dois D. Então, se eu clicar no nó do jogador
e adicionar um filho,
vamos adicionar um nó dois D, e então eu vou chamá-lo de virar que se vira quando
a
direção voltada para a entrada do jogador muda,
e então isso inverterá
automaticamente
o nó do sprite porque
o nó do sprite é
filho desse
nó pai dois D. Então, se
eu clicar no nó do jogador
e adicionar um filho,
vamos adicionar um nó dois D,
e então eu vou chamá-lo de virar dois de frente para dois D.
é
clicar com o botão direito do mouse e anexar um script. Vamos colocar isso no local
padrão, criar e fazer com que o
nome da classe vire dois de frente para
dois D. E isso vai
virar a escala X na transformação,
dependendo se o personagem
está voltado para a esquerda ou Ok, então o que
isso significa basicamente? Se eu pegar esses dois D brilhantes e colocá-los de frente
para dois D, e então vamos colocá-los de volta
onde estavam antes, no topo
da hierarquia, vou virar para dois D
e, aqui à
direita, desmarcar a ligação entre X e Y porque estamos
apenas alterando Está bem? Em seguida, digite
menos um para o X e você verá que o
caractere vira para a esquerda Se digitarmos um no X,
o personagem fica voltado a direção original,
que está à direita. Obviamente, você precisa
ter um
pouco de cuidado com a configuração. Se você colocar suas armas sob
o controle de dois Dno, isso significa que suas
armas também
estarão voltadas para a
esquerda ou para a Agora, às vezes você quer
isso e, em outros casos, você não quer que seu sistema de
lançamento de projéteis mais tarde, você não quer que ele gire com
base na escala desse nó Mas se você
colocasse, digamos, uma lança na mão do personagem,
provavelmente gostaria
que o sprite ficasse voltado para a direção certa
quando você estivesse voltado para
a
direita ou para a esquerda
quando estivesse voltado para direita ou para a esquerda
quando Portanto, você só precisa ter
cuidado com os nós
colocados aqui, porque qualquer coisa que esteja
invertida para dois D na hierarquia agora será invertida sempre que
o nó
pai for
invertido Portanto, lembre-se do que está relacionado ao quê, e
você ficará bem Então, dentro de nossa virada
para dois scripts em D, queremos adicionar uma var de exportação E vamos dizer entrada, que é do tipo entrada do player. Agora, por enquanto, depender da entrada do jogador
significa que esse script é especificamente do
jogador e não necessariamente usado pelos scripts
do inimigo. Para um script tão
pequeno, nesse caso, pode valer a pena ter
a referência direta à entrada
do player, pois
isso fornece a configuração mais simples e
prática. E então, a única coisa que você
precisa ter certeza é que a entrada está realmente
atribuída ao inspetor Então, podemos fazer isso
com o assert. Vamos
sublinhar uma função já e ,
em
seguida, afirmar que a entrada não
é nula e dizer que, para inverter
a referência à entrada do player, é necessário, mais
uma vez, você sempre pode
simplesmente ir até a reprodução mais alta e ela
atingirá sua afirmação, para que o teste Caso contrário, neste ponto, podemos simplesmente obter o acesso ao
sinal da entrada do player e usá-lo para
inverter esse nó sempre que a direção da
face mudar Se bem me lembro, ainda não
coloquei os sinais. Então, se clicarmos com o
botão direito do mouse na entrada do player, procurarmos o símbolo,
queremos ir até o topo e
declarar alguns sinais Então, um sinal é como um evento. Se você
vem de outras linguagens como C Sharp, é um evento. E, nesse caso, isso significa
que
algo é acionado dentro
do seu código e você deseja notificar os objetos
assinantes que algo ocorreu e opcionalmente, passar algumas informações
ou dados
contextuais para o Ok, então
deixe-me declarar uma, e depois explicarei de
forma um pouco mais simples Então sinal é a palavra-chave, e então
diríamos que face mudou, e gostaríamos de passar na
direção em que ela mudou também, para que pudéssemos dizer valor ou face, e esse
será um fator de tipo dois. Então, estamos declarando
o parâmetro. O que estamos enviando para qualquer objeto receptor está
entre parênteses Então, a face do sinal está mudada. Portanto, no evento, sempre que a propriedade de face, neste
caso, aqui embaixo muda, queremos enviar
um sinal que permita que qualquer objeto inscrito saiba que o
valor de face mudou Então, nesse momento, eles podem responder a isso
em seu próprio código. E isso significa que você não precisa
verificar constantemente a propriedade de face da entrada do player em
cada atualização de quadro. Basta esperar que o script o notifique de que o valor realmente
mudou para
algo diferente. Portanto, você tem essas informações
significativas e só precisa
atualizá-las uma vez a cada poucos segundos,
porque o jogador
só mudou a direção do
movimento uma vez cada 3 segundos ou a
direção voltada para o lado oposto neste caso. Em outras palavras, você se torna
dependente de um sinal acionando seu outro
código, em vez verificar
constantemente um valor
para alterações manualmente Então, com nossa
propriedade voltada aqui embaixo, queremos pegá-la e adicionar um setter para que, quando o valor de
face mudar, nós realmente emitimos o sinal
sempre que ele Então, se você adicionar
dois pontos no final, isso permitirá que você declare
seus setters e getters Você pode simplesmente fazer um deles. Você não precisa fazer as
duas coisas. Então, neste caso, queremos dizer valor definido. E observe que isso está em uma nova linha. Então, neste caso, estamos realmente declarando uma função,
na verdade E isso só é executado
sempre que definimos o valor dessa propriedade
para algo novo. Então, estamos alterando o padrão de apenas definir o valor e não
fazer mais nada para
configurá-lo e fazer algum código extra. Então, quando definimos o valor, queremos pegar a face
e defini-la como o valor. Então, isso seria o que
ele faz por padrão. Se você não declarar nenhuma função
setter Getter,
o Getter seria mais parecido com isso, voltado para o
retorno, certo? Isso é
o que você esperaria. Você acessa a propriedade pelo nome, frente para frente, e ela retornaria
o valor com o qual está definida. Portanto, se você não precisa de
código personalizado para o Getter, não precisa
declarar isso porque é isso
que ele faz por padrão, e é isso que o facing
faria por Agora, se você quiser fazer
algo como emitir um sinal, precisará do código extra Então, agora queremos dizer que a face mudou o nome do
ponto emitido do sinal, então emitimos o sinal, que significa que qualquer objeto se
inscreva nele agora
será notificado, mas queremos passar as
informações da Então, passamos de frente. Então, estamos pegando esse valor, enviando-o por meio do sinal e, em nossos outros scripts, receberemos
essa informação e podemos decidir
o que fazer com ela. Agora, há um outro truque que
eu quero mostrar aqui, porém, que é que
não queremos que a
mudança de face seja emitida sempre que
definimos o valor de face Isso pode estar sendo definido com o mesmo valor em cada quadro. Acho que a verificação da ação de
movimento na verdade evita isso, porque isso
só seria acionado quando houvesse uma ação de
movimento real, que seria, nesse caso, como pressionar a tecla certa ou soltar a tecla certa ou o mesmo nas
outras direções. Mas é sempre bom
ser mais defensivo
na programação Basta supor que suas
outras suposições não estejam necessariamente corretas e, em
seguida, se proteger contra elas Então, vamos
colocar um guarda aqui. Se a face já for
igual ao valor, isso significaria
que não há mudança. Então, nós só queremos voltar aqui. Não precisamos definir face porque o valor
já está atribuído à face. Já está correto e
não precisamos emitir o sinal e não devemos emitir o sinal
porque o valor na verdade
não muda Portanto, temos essa proteção contra conjuntos
defeituosos na propriedade oposta. Mas se esse guarda for ultrapassado, colocamos a face
e emitimos o sinal Então, com tudo isso,
o sinal agora será emitido. E podemos simplesmente
virar para dois D. E depois de afirmarmos que
Importar não é nulo
, sabemos que Então, podemos ir para a entrada voltada para o
ponto alterado. Você verá que o sinal é realmente referenciado
pelo nome aqui e tem aquele pequeno símbolo ou sinal de
Wi-Fi Então, alteramos
as faces dos pontos de entrada. Agora estamos
vendo o nome do sinal e queremos nos conectar a ele. Então, não se conecte. E o que
queremos conectar a ele? Bem, isso seria
uma função chamável que configuramos aqui Para manter as coisas, acho que, o mais simples
possível, devemos criar uma
função personalizada na parte inferior. Então, eu vou dizer que o underscore
facing mudou. Ainda haverá
um erro porque
não há nenhuma função com esse nome
dentro do nosso script. Então, se eu pressionar Enter
algumas vezes, diremos função,
sublinhado na face alterada Agora, quais parâmetros essa
função vai usar? Bem, vai
levar o que foi passado para o sinal. Então, neste caso, você estaria
olhando para a direção oposta. Então eu vou dizer
P, com o sublinhado virado, P como parâmetro, deixando bem claro
que esse valor vem dos parâmetros que foram passados
para a função E então esse é um vetor dois. Não vamos
devolver nada, então estamos retornando vazios E agora podemos escrever
o código para responder
à alteração da
face emissora do sinal Ok, então quando a face é alterada, queremos pegar
a direção X
da face e usá-la para
determinar se devemos ficar voltados para a direita ou para a esquerda. Então, se p ponto voltado para o ponto
X é um valor positivo, então o que queremos
fazer é pegar
a escala X desse nó dois D, virar para
o nó voltado para o nó oposto, e queremos defini-la igual ao valor absoluto
do ponto
da escala X. Quando você pega o valor
absoluto, você está fazendo um número sempre
positivo Então, para encarar a
direita, estamos fazendo maneira certa nossa direção positiva. Portanto, sempre queremos ficar voltados
para a direita sempre que a entrada estiver
realmente voltada para a direita. Agora, não
vamos dizer mais nada. Vamos dizer outra coisa se P
voltado para X é menor que zero, então não queremos esse caso zero porque nossos personagens não
deveriam ser capazes de encarar o ponto 00 no
vetor dois que realmente
não existe como direção inversa para
esse tipo de jogo de dois D. Portanto, não queremos fazer
nada quando for esse o caso. É por isso que estou verificando se o valor é menor que zero, porque menos de zero estaria
realmente voltado para a esquerda. Então, fazemos o ponto X escalado, e vamos definir
isso igual a menos uma
vezes o
valor absoluto do ponto X.
Ok, então isso
sempre dará um número positivo
e, em seguida, sempre
o tornaremos negativo vezes o
valor absoluto do ponto X. Ok, então isso
sempre dará um número positivo
e, em seguida, sempre
o tornaremos Portanto, provavelmente existem algumas maneiras
diferentes
de calcular isso aqui, mas acho que
deve funcionar bem. Ok, então vamos para duas vistas em D. Clicamos em flip
para virar dois D e atribuímos a entrada do player Ok, então é aí que
vamos obter o sinal. Vamos nos conectar a ele em Rudy em nosso roteiro frontal Ok, então se eu apertar play, vamos fazer o movimento certo. Nosso personagem fica voltado para a
direita e, se eu apertar para a esquerda, nosso personagem fica voltado para a esquerda. Se virarmos no canto superior esquerdo,
estamos voltados para a esquerda. Se virarmos para a direita,
estaremos virados para a direita. Basta testar todas as
oito direções em que
nosso personagem pode se mover com a entrada do teclado, e isso parece bom para mim. Então, só para pensar um
pouco no futuro, uma coisa que podemos fazer é pegar esse código e transferi-lo
para uma função diferente, refatorando-o em
uma Então, digamos que a função atualize ,
gire, e isso exigirá
a direção oposta Então, voltado para P, vetor dois, e então eu vou pegar isso, cortá-lo aqui e, na
face alterada, vou chamar update flip P facing Agora, o motivo para
fazer isso é para que eu também
possa reutilizá-lo quando estiver pronto Então, quando estiver pronto, diremos apenas atualizar e virar a importação voltada para o ponto Então, quando nosso script é carregado pela primeira vez, queremos definir a
direção voltada para cima imediatamente antes qualquer importação realmente venha do nosso player, porque pode
ser o caso em que decidimos, digamos, na entrada do player, exportar essa direção voltada
e, em seguida, alteramos
o padrão de ponto
vetorial à direita para vetorizar dois pontos à esquerda, porque, por qualquer motivo,
queremos nosso a serem virados para a esquerda por padrão. Agora, com isso, podemos estar preparados para isso
inicializando automaticamente com a direção de giro
correta com base no que quer que
a entrada esteja dizendo Então, agora, essa é uma função
pública. Poderíamos simplesmente chamar isso de
outro script se houvesse um caso não relacionado à importação em que quiséssemos mudar a
direção de inversão do personagem Por exemplo, talvez
durante uma cena, você queira cortar
todas as entradas do player e
chamar isso manualmente. Então, seu personagem estava
voltado para a direita
e, na cena, você
quer que ele fique voltado para a esquerda. Portanto, você teria a
opção de simplesmente chamar Update flip on the flip
to facing two D node. Ok, então definitivamente abre
algumas possibilidades. E isso é praticamente tudo o que
precisaremos fazer
para o movimento WASD
do nosso jogador Está parecendo bom. Acho que todas as preocupações estão bem
separadas
10. Camadas de mapas com grama e terra: Ok, então, como o movimento e a
animação de nossos
personagens basicamente
jogam tanto no Idol quanto no Run, incluindo a direção
invertida, acho que agora é um
bom momento para começar a colocar um plano de fundo para que o jogo
fique um
pouco mais bonito, em vez de apenas
ter o fundo cinza padrão do Gadot Então, vamos seguir em frente e
mudar para o nosso cenário mundial. Se você não tiver isso aberto, você pode ir para o canto inferior esquerdo aqui. Basta pesquisar o mundo e você poderá
encontrar o mundo dottScn se esse for o mesmo nome que
você estava usando como eu E então, na hierarquia mundial, queremos clicar com o botão direito do mouse
e adicionar um novo nó, e estamos procurando por
uma camada de mapa de mosaico Você pode ver que havia
outro nó chamado Tilemap, mas ele está obsoleto,
eu acredito, desde 4.3,
e desde 14.41 e
prestes a ir para 4.5, é definitivamente
recomendado que você
mude para camadas de tilemap, que divide o tilemap em
nós de camada individuais em vez de ter cada camada. camada. Contido dentro
de um mapa de blocos. Então, vamos adicionar uma camada de mapa de mosaico. E vamos chamar
isso de algo como ground, então vou renomeá-lo para ground E se você a tiver
selecionado na parte inferior, deverá ter a janela do
mapa de blocos Então, abra
isso se ainda não estiver aberto. E então precisamos encontrar os ativos
artísticos do nosso projeto. Então, vou abordar arte e,
em seguida, conjuntos de ladrilhos de
ambientes
Pixel Crawler, e vamos querer trabalhar com os pisos Então, para que possamos fazer isso, não
queremos
estar no mapa de blocos,
mas sim na guia do conjunto de blocos Olhe no canto superior
direito enquanto você tem a camada do mapa de
mosaico selecionada e você verá o conjunto de mosaicos como um recurso que você
pode atribuir aqui. Você deseja clicar com o botão esquerdo
e fazer um novo conjunto de blocos Depois de fazer isso na parte inferior, haverá uma nova guia Tilset Então, depois de
renomeá-lo para chão, olhe para o canto superior direito
com ele selecionado e você verá um
campo para o conjunto de blocos Então, queremos clicar aqui e declarar um novo TilesetrSource Você faz isso na parte inferior, deve
haver duas guias aqui
relacionadas ao mapa de blocos,
que é um mapa de blocos para realmente selecionar e
desenhar esse conjunto de blocos, que serve para
configurar seus blocos
e, em seguida, um mapa de blocos para
desenhar seus blocos Então, queremos ir para o Tile set. Você deve ver uma caixa aqui podemos arrastar os ladrilhos do
piso. Portanto, encontre ladrilhos
dentro do projeto. Então, são pisos sublinhados,
ladrilhos, pontos PNG, e vamos apenas arrastar
e soltar isso aqui Haverá um pequeno pop-up, que pergunta se você deseja criar
automaticamente
os blocos, nós fazemos. Então, vamos em frente
e nos atingiremos aqui. E então você verá
na janela de pré-visualização que todas as peças
foram automaticamente divididas em recursos reais
de que podemos usar e
pintar no jogo Portanto, a maneira mais simples desenhar seria ir
ao Tilemap e selecionar
individualmente os ladrilhos que
queríamos colocar Pressione Q para verificar se você
está no modo de seleção. E aqui embaixo na janela
do mapa de blocos, queremos estar nas ferramentas de pintura, então isso é D no teclado E então você pode
clicar com o botão esquerdo para desenhar o ladrilho. Você pode passar por cima de um, clicar com o botão
esquerdo e colocar
outro ladrilho no chão. Você verá que, neste momento, o Tap está realmente aparecendo na frente do player.
Não é isso que queremos. O que você pode fazer é simplesmente mover
o chão até o topo aqui, e isso o classificará
automaticamente, forma que o solo fique
embaixo do jogador. Então essa é a
maneira mais simples de fazer isso. Portanto, embora a seleção
das peças , uma de cada vez, funcione, é muito, muito entediante Então, o que provavelmente
queremos fazer em vez disso é criar um conjunto de terreno com base nesses ladrilhos de grama e usá-lo
para desenhar automaticamente qual ladrilho precisamos, dependendo do que está adjacente a esse
ladrilho, se é que existe alguma coisa Portanto, se você expandir o
conjunto de blocos no canto superior direito, poderá ir até os conjuntos de terrenos e adicionar um novo elemento Então, vamos
deixá-lo nos cantos e
lados correspondentes e você expande os
terrenos e adiciona um elemento E podemos simplesmente renomear
isso, digamos terreno
gramado mude a cor para algo um pouco
mais gramado, como Agora, na parte inferior,
vá para o conjunto de azulejos e depois
vamos pintar. Vamos selecionar um dos
terrenos do editor de propriedades. Vamos
selecionar o conjunto de terreno como
conjunto de terreno zero
e, em seguida, o terreno que
estamos desenhando é grama Portanto, deve ser bastante óbvio quais são
os ladrilhos de grama aqui. Mas para que os ladrilhos sejam
construídos de forma correta
e automática, precisamos selecionar os ladrilhos que deveriam fazer parte
desse terreno gramado Então, você pode simplesmente clicar com o botão
esquerdo, segurar e arrastar uma caixa ao redor de todos esses
ladrilhos de grama, mais ou menos assim. Se estiver destacado,
isso significa que está basicamente marcado como
parte desse terreno E isso é grama escura aqui. Poderíamos
configurar isso mais tarde. OK. E então talvez precisemos trazer
esses aqui também. Vamos ver como isso funciona e
esses ladrilhos claros estão lá. Agora, esses de baixo
parecem mais uma grama escura. Podemos tentar
incluí-los e ver no que acontece, mas eles podem não
aparecer no corte final do terreno, que pode ter um tom mais
escuro de grama Então, teremos que ver como
isso realmente funciona. Ok, então selecionamos todos
esses ladrilhos como grama. Agora, queremos ir para
o canto superior esquerdo e marcar
os cantos e lados que são grama ou
adjacentes à grama. Portanto, a maneira mais simples de
pensar sobre isso com este conjunto de ladrilhos é apenas se a área for
transparente, geralmente, você não vai marcá-la, e se for grama maciça
ou próxima de grama sólida, você marcará como sendo grama ou grama adjacente. Se eu clicar com o botão esquerdo
aqui e arrastar, você verá que está
preenchendo o cursor, e queremos que esses oito
quadrados que não estão
no canto inferior direito sejam marcados como grama porque
isso aqui
no canto inferior direito está dizendo que há
algo mais aqui embaixo O ladrilho no
canto inferior direito não é grama e esse ladrilho
está refletindo isso Então, ele basicamente usará
esse ladrilho quando tudo da direita para a esquerda
e esses três cantos forem grama, grama adjacente, mas o canto inferior direito não. Então, a ideia é que você tenha um
para todos esses cenários. Então, nesse caso, você
faria esses seis ladrilhos superiores, e isso significa que,
se não houver grama embaixo deles, no canto inferior
esquerdo ou no canto inferior direito, esse ladrilho será atribuído
automaticamente Então, só queremos continuar fazendo esse tipo de coisa em
todos os sentidos. Portanto, este se
parece com todos os cantos e lados, exceto
o canto inferior esquerdo. E então esse
é o top quatro. Este é, eu acho, exatamente como este aqui
de novo, o top oito à direita. E sim, é possível
ter vários blocos a mesma máscara, acredito que eles
chamam isso de máscara pequena aqui. Então, se descermos até o final, você verá que
todos esses são nove ladrilhos quadrados, certeza, porque são todos
grama e grama adjacentes. Então, você realmente preencheria
tudo isso até o fim. E então isso preencherá tudo dentro
desses ladrilhos de borda. Ok, então nós meio
que precisamos continuar fazendo isso. Então, este aqui
no topo vai ser do meio de cima para baixo, e o direito de cima para baixo. Aqui temos os oito lados e cantos, exceto o canto superior esquerdo. Este é o quarto
inferior direito. Este é tudo,
exceto no canto superior esquerdo. Os seis ladrilhos inferiores, tudo exceto o canto superior direito, os quatro inferiores esquerdos, tudo exceto o canto superior direito, os seis esquerdos, tudo exceto os quatro inferiores e
os quatro superiores esquerdos. Temos nossas
peças de canto aqui em cima, e temos as peças
sólidas de grama aqui embaixo. Então, para desenhar com ele, basta ir ao Tilemap e
selecionar terrenos E o que podemos fazer é
pegar essa ferramenta retangular. Deixe-me diminuir o zoom
da câmera aqui um pouco. E vamos diminuir o zoom com a roda
central do mouse
no mapa do jogo, e podemos simplesmente clicar com o botão
esquerdo e arrastar uma caixa gigante para o fundo. E aí está nossa grama
de fundo. Agora, você verá que esses
ladrilhos eram, na verdade, mais escuros. Foi um pouco difícil
dizer na minha tela. Então, talvez no conjunto de ladrilhos, também
seja grama escura que realmente parecia
a mesma para mim. Então, a solução para isso
é apenas remover
os ladrilhos
escuros dos ladrilhos claros ao
atribuir a grama Então, se eu clicar com o botão direito
do mouse em qualquer uma dessas peças de máscara de bits, ela será removida como parte do ladrilho se removermos totalmente todos os nove
lados, cantos e centro. Agora, se redesenharmos isso novamente, não será uma opção quando
estiver preenchendo os blocos Então, basta clicar com o botão esquerdo e
arrastar outra caixa sobre ela, e aí temos
a grama clara e somente a grama clara
de toda a cena. Agora, em um jogo tipo Survivor, seu personagem pode se
mover muito pelo mapa Então, na verdade, vou
fazer disso uma área muito grande. Vamos ir daqui
até aqui para que
haja bastante espaço para o personagem
se movimentar. Agora, você pode ver que
realmente demora um pouco para preencher
isso porque são muitos blocos. Ok, eu também quero
mostrar se eu pressiono E, para ir para o modo Corrida e
depois D para a ferramenta de pintura. Em seguida, podemos clicar com o botão esquerdo
aqui e você verá que ele atribui automaticamente as peças adjacentes com
base no ladrilho no centro Portanto, esse ladrilho não tem ladrilho, então ele
reconheceu automaticamente: Oh, eu preciso dos cantos
e das peças laterais que atribuímos no terreno E eu posso continuar usando
o pincel de borracha assim. E você verá que
ele está
gerando automaticamente as
laterais e os cantos. Pode ter algumas limitações,
como precisar ir dois por dois e uma linha
para parecer correta verdade, depende do conjunto de
ladrilhos, porque existem
maneiras diferentes de construir os ladrilhos. Mas, no mínimo,
isso é muito,
muito mais rápido do que se
você tivesse que
atribuir manualmente todos esses blocos
laterais e de canto. Deixar o computador
descobrir por você com base nas
regras de terreno que você define, como acabamos de fazer, economiza
muito tempo Então, vamos preencher isso. Há também a ferramenta
de balde de tinta aqui embaixo, então podemos clicar nessa área em que todos os
ladrilhos são iguais. E oh, bem, também temos que E
para remover o erasuod. E agora clicamos com o botão esquerdo e
tudo é preenchido. Como você pode ver, ele
selecionará qualquer região que
você esteja procurando. Então isso pode ser tudo
isso. Se você quiser preenchê-lo com um terreno de
ladrilho totalmente diferente, você pode fazer isso definindo uma terra, mudando
para terra aqui embaixo e declarando-a
baixa, para que seja um pouco mais avançado do que
eu realmente pretendia,
mas vamos definir
outro terreno com
essa terra aqui,
o tipo de terra alaranjada para mas vamos definir outro terreno com
essa terra aqui, a qual a sujeira pode se transformar um terreno de
ladrilho totalmente diferente,
você pode fazer isso definindo
uma terra, mudando
para terra aqui embaixo
e declarando-a
baixa, para que seja um
pouco mais avançado do que
eu realmente pretendia,
mas vamos definir
outro terreno com
essa terra aqui,
o tipo de terra alaranjada para a qual a sujeira pode se transformar
grama. Então, vamos no canto superior direito, declarar um novo tipo de terreno, e eu vou chamar isso Esse marrom está bom, eu acho. Na verdade, talvez você não
queira usar, tipo, um marrom em ladrilhos marrons para que seja mais fácil ver onde você definiu e onde não definiu. Mas se funcionar para
você, tudo bem. Qualquer cor que você deseja
atribuir está perfeitamente correta. Ok, então vamos
trabalhar com sujeira de
tinta na janela do conjunto de
ladrilhos e faremos exatamente
a mesma coisa com
esses ladrilhos de terra. Então, aqui, estamos pintando
os oito superiores esquerdos, não os inferiores direitos, e
depois os seis superiores, desse jeito. E eu
vou continuar andando por aí assim. Este não é um pouco claro, mas vou usar os quatro
no canto superior direito e veremos se
funciona corretamente Se quando você realmente desenha com o terreno,
ele não parece, você pode ter perdido uma
das partes aqui ou ali,
você sabe, se está ligada
ou desligada, no centro ou nas laterais Então, às vezes, é
preciso um pouco de tentativa e erro para acertar. Mas definitivamente
vale a pena a longo prazo. Então continue andando, você sabe, da mesma forma. Coloque os cantos e os lados onde está sujo e marque-o como sujo, e depois
continue até terminar a volta
completa no círculo. Ok, e então termine com as três
peças inferiores aqui embaixo. Vamos pegar a sujeira clara e pular a sujeira
escura por enquanto Ok, e isso parece bom. Ok, você sabe o que?
Eu mencionei que eu ia lidar com
a transição da terra para a grama. Mas, na verdade, com
esse conjunto de ladrilhos, acho que isso não é necessário porque esses ladrilhos,
individualmente, têm menos
transparência do que
grama aqui ao lado da terra. Então você não precisa definir o terreno gramado individual como parte da terra dessa forma, onde você pegaria esses
outros ladrilhos e diria: Ah, isso é grama ali e depois sujeira no canto inferior esquerdo Porque é
transparência aqui, então isso realmente não é necessário. Mas em outros conjuntos de blocos,
talvez seja necessário fazer isso. Onde, se você sabe que um canto deveria ser grama, então você o marca como grama lá. Portanto, ter dois tipos de terreno
para um canto ou lado. Mas aqui, acho que só
precisamos de um. Deixe-me dar uma chance e ver como vai
ficar. Então eu vou para o Tilemap Vamos limpar a sujeira e
tentar desenhá-la. Estou pensando no que realmente
precisamos. Ok, então sim, aqui
podemos ver que está marcando os lados como
transparentes. Eu estou errado. Então, vou tentar marcar
esses lados como grama, mas acho
que isso não vai realmente nos
dar o resultado esperado. Acho que o que
precisamos fazer é
ter apenas duas camadas separadas para
esse conjunto de blocos específico. OK. Então, vou
tentar desenhar com isso. Então, mova o modo de mapa de blocos e depois desenhe com terra e
vamos tentar isso. Ainda está meio
confuso. Vou experimentar uma caixa. Sim, ainda não funciona. Então, desfaça o Controle Z algumas vezes. E o que realmente
vamos querer fazer é pintar com
terra sobre a grama,
ou grama sobre a terra dependendo da camada que
você quer colocar no topo. Então, vou clicar com o botão direito na
raiz e adicionar um nó filho. Digamos que uma camada de mapa de mosaico. Vou renomeá-lo para
, digamos, sujeira. Vou mover isso abaixo do
solo para que, por padrão, apareça acima do solo. Então, o que está no fundo
está na verdade no topo. Não sei por que está
configurado dessa forma. Eu simplesmente sou. E então
vamos para a terra. Ah, e queremos reutilizar o
mesmo conjunto de peças, a propósito. Então, no chão, vou
clicar com o botão direito do mouse no
conjunto de blocos e salvá-lo. A propósito, isso está no topo,
à direita. Então, salve-o. Localmente no projeto. Assim, posso criar uma nova pasta de conjuntos de
blocos
e, em seguida, direi
ground tileset dot TRs Ok, agora, se clicarmos na sujeira e depois formos
até o inspetor, podemos clicar no menu suspenso,
Quickload, conjunto Quickload, Ok, agora com essa camada
de mapa de blocos, podemos usar os mesmos conjuntos de blocos que já definimos
anteriormente É mais ou menos assim que
os recursos funcionam em geral. É muito fácil
compartilhá-los em vários nós ou
várias cenas, etc., compartilhando os
recursos dessa forma Ok, então vamos
desenhar com terra aqui, e então eu vou
desenhar com terra aqui, e você
vai ver que
a sujeira fica
perfeitamente no topo porque estamos
pintando em camadas diferentes, então isso só aparece em cima
do fundo e há transparência
aqui nessas bordas laterais, a grama basicamente
preenche as lacunas O outro método que eu estava
mostrando, em que todas as informações de
textura, como
grama e sujeira, estão informações de
textura, como
grama e sujeira todas em um sprite de ladrilhos seria mais quando você configura vários
terrenos em um ladrilho, que é mais
complicado, Então, vou renomear o
solo para grama. Porque seremos mais específicos lá. Portanto, temos duas camadas de mapas de mosaico, e é muito mais
fácil
manipulá-las do que
seria um mapa de mosaico Ok, vamos ver onde estamos. Provavelmente queremos mais,
tipo, desenhar um caminho de terra batida. Ok, então para que a
sujeira seja atribuída corretamente, queremos desenhar uma linha de
dois por dois. Então, você quer usar
a ferramenta retangular
ou o teclado Se você fizer apenas uma linha de ladrilho, vai acabar
mais ou menos assim. Com base no
site do tile, não se sabe como encontrar as
informações aqui. Não há ladrilho
com transparência na parte superior e transparência na
parte inferior, então isso não funcionará. Na verdade, você precisa
fazer um caminho de dois pixels de altura como esse e depois
arrastar sua caixa, e isso funcionará para isso. Então, poderíamos criar
alguns caminhos no nível, mais ou menos assim
, você sabe, apenas desenhando dois caminhos com a
largura de um ladrilho para onde
você quiser. E isso vai torná-lo um pouco
mais interessante do que apenas ter um ladrilho de grama
simples. Embora dependa totalmente
de você como você deseja, você sabe, organizar isso e torná-lo
mais interessante. Então, se você já jogou, digamos, Sim City, é exatamente
isso que estou fazendo aqui
agora, tipo , criando o sistema rodoviário e basicamente
colocando-o onde eu quiser. Não vou preencher nenhuma
zona residencial em nenhum lugar ou
algo parecido. Mas ter mais algumas
peças no mapa é um pouco mais interessante do que
literalmente apenas grama. OK. Então, vamos ver se isso é
bom. Vou clicar em Play. E sim, nosso personagem meio que tem algo
em que andar agora, então isso é um
pouco mais interessante.
11. Como colocar árvores como objetos cênicos no mapa: E agora acho que
seria uma boa ideia
adicionar alguns adereços
ao nível do jogo Portanto, também temos alguns adereços aqui na
pasta do ambiente Portanto, há alguns
animados e estáticos. Poderíamos começar
com as árvores como o suporte mais simples que podemos
colocar no nível do jogo Então, vamos pegar, uh, eu não sei. Vamos clicar duas vezes aqui e você poderá ver os
modelos das árvores lá em cima. Então, talvez queiramos
pegar essas árvores grandes, e podemos fazer isso com uma amostra do nó Sprite two D. E podemos colocá-los de
forma super simples. Tudo o que
realmente precisamos fazer é acessar o arquivo PNG e
arrastá-lo para a cena do jogo. Ele vai criar
automaticamente um Sprite two D aqui em cima Então, basta renomeá-la para Árvore então vamos
pegar essa textura, e não vamos
desenhar a textura inteira Vamos desenhar
uma região dela. Então, o que queremos fazer é usar uma textura de atlas para que possamos selecionar a
região que estamos desenhando Então, clique com o botão direito aqui,
e eu vou copiar essa imagem bem rápido porque vamos
clicar no menu suspenso, ir para a textura do Atlas, que vai remover
essa textura temporariamente Expanda isso e clique com o botão
direito do mouse e cole a textura que acabamos de
copiar no atlas E aí
está ele aparecendo novamente. Agora, queremos
clicar em Editar região. E então, dentro daqui,
vamos para o modo Snap, Cid Snap, roda
do
meio do mouse para aumentar o zoom,
e vamos pegar
essa árvore assim,
clicar em e vamos pegar
essa árvore assim, Fechar e temos
uma árvore na cena Ok, agora,
dependendo do seu estilo de jogo, você pode decidir adicionar formas de
colisão à sua árvore Você faria isso da mesma forma faria com, tipo,
um personagem de jogador. Então, se olharmos para o personagem do
jogador, você pode vê-lo como uma forma de
colisão aqui e fazer com que os objetos colidam com as árvores No entanto, para esta demonstração, queremos minimizar
a quantidade de colisões que nossos inimigos
farão com qualquer tipo
de personagem do jogo Se tivermos muitos objetos
colidíveis dentro
do jogo e não
colocarmos algo como um agente de navegação ou usarmos corpo dois D do
personagem para que ele possa se mover e deslizar ao longo
da forma de colisão
, você fará com que
os inimigos fiquem presos Muito mais simples do que isso
seria pular
a colisão e deixar
qualquer personagem atravessar
a árvore e deixá-la lá qualquer personagem atravessar
a árvore Estritamente para efeitos visuais.
Temos a árvore aqui. Vou
clicar com o botão direito na cena e criaremos um novo
nó para todas as árvores. Então eu vou dizer nó dois D, criar, e vamos mover isso para
fora da árvore, então deve ser o submundo E eu poderia simplesmente
renomeá-lo para adereços. Vou mover a árvore para
dentro daqui. E então podemos simplesmente duplicar essa árvore quantas
vezes precisarmos Então, primeiro clique com o botão direito do mouse e
salve o galho como uma cena. Vamos colocar a árvore em
uma nova pasta, eu acho. Vou ligar para ele.
Vamos com Objetos. Sim, e
vou colocá-lo aqui dentro . Então, TSN de três pontos Podemos clicar em Salvar N se
quisermos editar a árvore, alterá-la para um tipo
diferente de árvore e, em
seguida, podemos simplesmente
entrar na cena. Então, para fazer isso, basta encontrar esse pequeno ícone aqui
e abrir um editor, para que você possa editar essa árvore e
alterá-la para o que precisar, se quiser alterar todas as
cópias dela no mundo. Deixe-me mostrar um exemplo disso. Então, temos a árvore. duplicá-lo
várias vezes
e, em seguida, pressionarei W para mover
as cópias pela cena Então selecione a árvore dois, W, mova-a pela cena. modo de movimento está aqui.
O modo de seleção está aqui. Então você precisa selecioná-lo
e depois ir para o modo de movimento. E agora eu quero
mudar a árvore, todas as cópias da
árvore em todo o jogo. Então, vou até a cena da árvore
e, aqui à direita, expandimos o atlas,
editamos a região
e, em seguida, selecionamos
essa vermelha Então, árvore vermelha, aperte
perto, clique em salvar, e agora de volta ao mundo, todas as árvores são aquele tipo de árvore vermelha com folhas de
outono. Agora vou
voltar para a árvore
e vou desfazer isso Então, vamos pressionar o Controle
Z algumas vezes. Vamos escolher a árvore verde
padrão. E se você quiser dois
tipos de árvores, encontre a cena da árvore
em sua hierarquia aqui Então você pode clicar com o botão direito
aqui e duplicá-lo. Vamos chamá-lo de
outono de árvore e clicar em OK. Abra a árvore de outono com um clique duplo. Vamos ampliar a árvore, pegar a textura
e editar a região, e podemos simplesmente pegar essas árvores
vermelhas daqui. E agora, se formos para o mundo,
podemos colocar as árvores de outono ou podemos colocar a
árvore apenas arrastando a cena direto para a cena
principal, o mundo Se você se acostumar com
isso,
poderá preencher a
cena rapidamente Agora, uma coisa que eu
quero mudar aqui, e talvez eu precise
demonstrar para tornar isso óbvio, é que, quando se
trata da classificação Y, a posição e a cena
da árvore do sprite serão
importantes porque vamos classificar em
Y a partir da posição central Então, onde quer que o personagem
toque o chão,
geralmente é onde vamos
querer posicionar o sprite Então, aqui
nesse estilo de jogo porque eu fiz isso com
o jogador, certo? Então, queremos ter
certeza de que os personagens estão classificando de onde estão Isso também se aplica aos objetos. Para demonstrar por
que isso é um problema, vamos voltar aos adereços da cena
principal Eu vou começar a fazer o pedido
aqui à direita. D Y Sort habilitado no
mundo, faça a mesma coisa. Vá para o pedido e
escolha WySort ativado. OK. E agora, se jogarmos e movermos nosso personagem
na frente de uma árvore, bem, as câmeras na verdade
não nos permitem fazer isso. Então, vamos adicionar uma câmera de
acompanhamento para que
possamos realmente
nos mover um pouco mais pelo mapa. Vou pegar
o player,
clicar com o botão direito , adicionar um nó secundário , transformar
remotamente dois D e, à direita,
queremos atribuí-lo à câmera. Queremos atualizar a posição
e não a rotação e não
a escala, então desmarque-as Ok, agora se apertarmos o
play, então pare e jogue. A câmera
seguirá nosso player, e essa é uma câmera básica de
acompanhamento em Gudo Ok, então chegamos a esse objeto. Se estivermos aqui, você
pode ver que estamos nos classificando atrás da árvore, o
que seria de esperar Mas se eu for até a
metade,
agora os personagens estão
basicamente na árvore Visualmente falando, ainda
queremos que o personagem fique atrás
da árvore
até chegar aqui. Caso contrário, parece estranho. Então, para corrigir esse salto
na cena da árvore, você pode clicar aqui
para abrir um editor. E queremos que esse
sprite esteja aqui. Mas acho que se você simplesmente
mover o sprite dessa forma, porque é o nó raiz, isso não vai consertar nada Então, vamos voltar para o mundo, e sim, vamos clicar em
play. Você vai ver o que quero dizer. Vamos até aqui, e
isso mudará a posição em que se
situa essas
árvores, não a posição de
onde elas são classificadas, certo? Você vê que o
problema ainda está aí? Então, precisamos voltar
para a cena da árvore, e eu vou clicar com o botão direito do mouse. Vou adicionar um nó filho,
um nó ao qual vou
clicar com o botão direito nele e
torná-lo a raiz da cena. Então essa é a
árvore real na raiz, e agora esse é apenas
o sprite dois D. Então, quando você coloca um objeto
dentro de outra cena, ele coloca a raiz basicamente
em sua posição central. Então, este é o centro
do nó D principal raiz, e agora podemos
deslocar o sprite Então, se eu pegar esse sprite, bem, ele já está realmente deslocado, mas você pode simplesmente W e movê-lo para onde
você precisa Lembre-se de que sua posição de
transformação é um deslocamento da raiz, e a raiz é onde
ela realmente será instanciada no
ponto 00 aqui É por isso que
é necessário ter uma base sem dois D e, em seguida,
seu sprite aninhado abaixo dela Então, também queremos fazer a
mesma coisa com o outono das árvores. Mas você pode
notar que, como esses objetos são muito semelhantes, eles estão na verdade repetindo
várias etapas Então, o que podemos
realmente fazer é ter uma cena herdada
baseada na árvore verde do verão onde apenas substituímos
a imagem srt, mas todo o resto é
o mesmo para aquela Então, vou deletar a cena
do outono
aqui embaixo. Árvore de outono. Vamos deletar isso. Oh, eu tenho que deletá-lo e
fechar a cena. Então exclua isso e, aqui em cima, certifique-se de fechar isso
também. Portanto, não economize. E então, no
mundo, ele ainda pode ter uma cópia
da cena porque não a exclui
completamente. Só que agora não há nenhuma cena
parental para isso acontecer. Vou cortar isso
também e guardar isso. Então, movemos todas
as instâncias. OK. E agora,
no canto inferior esquerdo, queremos clicar com o botão direito do mouse em Árvore, fazer uma nova cena herdada Portanto, agora temos uma cena não salva
com base na cena principal. Podemos salvar isso como outono de árvore e queremos colocá-lo na pasta de objetos.
Então guarde isso. E a única coisa que estamos
mudando aqui é o sprite. Então clique em Editar região e pegue o sprite para a árvore de
verão, clique em Fechar E se voltarmos
à cena principal, você verá que
poderemos ver
o outono da árvore novamente. Parece que eu realmente errei. Portanto, precisamos tornar a textura do
atlas única. Caso contrário, você
acaba substituindo as árvores. Agora, na cena de outono das árvores, queremos pegar
esses dois D brilhantes, e o primeiro instinto que
tive foi simplesmente editar
a região e
alterá-la para esta aqui embaixo Mas isso está realmente incorreto. E deixe-me explicar o porquê. Então, aqui, esse
é um recurso de textura, e os recursos são compartilhados entre qualquer cena
que faça referência a ele. E tanto nossa árvore quanto nossa árvore de outono estão se
referindo ao mesmo recurso Então, se alterarmos suas propriedades,
como a região do atlas, assim como a região de edição
aqui na cena do outono, ela também
atualizará essas mesmas propriedades na cena da
árvore original, porque elas estão compartilhando
o mesmo recurso Portanto, não é uma nova cópia
do recurso de textura. É literalmente o
mesmo recurso. Então, queremos
clicar com o botão direito do mouse aqui e
torná-lo único na cena do outono. E agora podemos mudar isso
para essa textura aqui embaixo. Então selecione a
árvore de verão e clique em Fechar. Clique em Salvar. Se formos até
a árvore verde, você verá que ela ainda tem o sprite da árvore verde.
Podemos ir para o mundo. Parece que algumas
dessas árvores meio que não foram referenciadas,
então talvez queiramos excluí-las bem rápido Então, na verdade, vou
pegar adereços e fazer com que seja 00. E então eu quero pegar o nó de adereços e
bloqueá-lo Então, se você clicar aqui, poderá bloqueá-lo e, sim, deve impedir
que ele se mova. Então, se eu pressionar W e tentar mover o nó de adereços agora,
ele não se moverá Então, uma coisa importante a observar é que você tem um
nó pai dois D aqui, adereços, toda a posição de seus
filhos é na verdade, baseada em relação
à posição dos pais Portanto, se você tem um
nó de agrupamento como props, mas ainda precisa
que seja um nó dois, provavelmente é uma boa ideia bloqueá-lo Então, eu aplicaria a
mesma coisa se você tivesse um nó de
agrupamento de inimigos ou projéteis, o que provavelmente
teremos mais tarde Agora podemos simplesmente adicionar
nossas árvores aos adereços, então vou
colocar algumas lá Ok, então se eu pegar essa árvore que acabamos de criar e pressionar W e tentar movê-la
além do ponto de cimentação, você notará que
quando ela chegar aqui, ela simplesmente desaparecerá
atrás da grama e da sujeira Então, isso se deve
ao motivo da classificação. Então, o que
precisaremos fazer é, no canto superior esquerdo,
para grama e terra, precisaremos selecioná-las. Acho que você pode até selecionar
os dois ao mesmo tempo. E depois vá para o lado
direito. Estamos procurando uma
ordem, pegamos seu índice Z e o configuramos para algo como,
digamos, menos dez, qualquer valor negativo Então, isso fará com
que eles estejam sempre atrás de qualquer coisa que
tenha um índice Z de zero. Então, se selecionarmos a
árvore agora e formos para W e movê-la, agora está corrigido. Sempre aparecerá em
cima desses outros objetos. Então, isso é apenas sobre como
estamos estratificando nossa cena. Alguns objetos, você
deseja classificar com outros objetos
no mesmo índice Z, como o caractere na árvore. Mas outros objetos, como o mapa de blocos, devem
sempre estar em segundo plano para esses ladrilhos porque os personagens estão no
chão, então você deve ver os personagens antes
de ver o chão. OK. E agora
nós meio que queremos preencher a cena
com mais algumas árvores. Você pode simplesmente
selecioná-los,
duplicá-los e movê-los para cima. Certifique-se de colocá-los no nó
de adereços como pais
apenas por motivos de classificação E então vamos simplesmente
selecioná-los e duplicá-los. Você pode duplicar
mais de um por vez. Então, se você
quiser um certo padrão, podemos criar um grupo de árvores e
copiar tudo isso. Você pode até mesmo
movê-los para seu próprio subgrupo, como se fosse um bloco de
árvores pai, e então teremos várias árvores
diferentes e você poderá ocultá-las
para não ter tantos nós de árvores
preenchendo Se isso te
ajudar. Ok, então vamos mover algumas árvores
um pouco mais, e eu poderia simplesmente
selecionar todas essas dez árvores. E eu vou sim, vamos tentar o bloqueio
que mencionei. Vou clicar com o botão direito do mouse
e adicionar um nó secundário. Digamos que nó dois
D, bloco de árvore. Vou pegar todas as árvores e
movê-las para baixo do bloco de árvores. Então, basta selecionar todos eles. E agora eu poderia salvar essa cena de
bloco de árvore no projeto, e nós vamos querer
salvar esse bloco de árvore de objetos. Agora podemos simplesmente duplicar
o bloco da árvore, controlar D W, movê-lo
assim e preencher a cena conforme necessário com árvores onde
quisermos Em algum momento, você
provavelmente quer personalizar isso um
pouco mais, mas acho que essa é uma maneira rápida criar um protótipo da cena, e espero que
não pareça muito ruim quando clicamos em Play
e ampliamos o zoom Mas sim, se eu estivesse fazendo
isso árvore por árvore, isso levaria, você sabe, provavelmente, 20
minutos ou algo assim. Então, se precisarmos fazer
algumas personalizações, como aqui, se aumentarmos o zoom, vejo que essa árvore, você sabe, meio perto da estrada, talvez eu queira editá-la para
poder pressionar Q e clicar com o botão
esquerdo nela Podemos ver que faz parte do bloco três
da Árvore. Podemos clicar com o botão direito do mouse
na hierarquia e fazer Filhos editáveis E então, para
esta, especificamente, agora
podemos selecionar as
árvores e movê-las. Então, assim,
temos mais ou menos um bloco de árvore
personalizado. Ok, e podemos esconder isso.
Então, agora estamos vendo apenas 15 blocos de árvores em
vez de 150 árvores. Podemos jogar, entrar no modo de jogo e simplesmente caminhar pelo
nosso mundo de jogo. E a partir desse Zoom In, é muito difícil dizer
isso, basta copiar e colar a mesma configuração de árvore
umas dez vezes, mas é muito menos chato do
que apenas ter Tipo, temos o
caminho, temos grama. Se colocarmos algumas flores
ou outras coisas aqui, na
verdade pode
parecer quase um nível de jogo legítimo Ah, e aqui está uma
árvore que podemos consertar. Então, você sabe, um
pouco de teste de jogo. Você pode encontrar coisas
assim. Vamos ampliar e corrigir isso bem rápido. Então, isso faz parte do bloco dois da
Árvore. Se você olhar na
tela, poderá realmente ver o nome do nó sobre
o qual estamos passando o
mouse. Portanto, este é o nó pai, aquele em que a cena é
Enstus, o bloco da árvore, não seus nós secundários que estão contidos dentro
dessa Para torná-lo editável,
clique com o botão direito do mouse em Tree Block
two, editable Pressione Q para ir ao Modo de Seleção, selecione esta árvore,
mova-a e podemos pegar
essa também, movê-la para fora do caminho e fazer essas
pequenas edições E sim, ao diminuir o zoom, parece que nenhuma das
árvores está mais na estrada Então, isso é provavelmente
o mínimo do que precisamos que aconteça
12. Adicionando tropeços e fixando a classificação Y: Então, eu estava procurando
no pacote
Pixel Crawler algumas flores que pudessem ser colocadas ao redor da cena para
enfeitá-la um Realmente não vi isso
na versão gratuita, infelizmente. Mas acho que temos
esses tocos aqui. Podemos tentar usar
isso como suporte e preencher um pouco as lacunas e torná-las
um pouco menos monótonas Então, vamos pegar isso e criar
uma nova cena de toco a partir disso. Então, vou basicamente
repetir os mesmos
passos com a árvore. Vou arrastar isso para a cena. Vamos para a textura. À direita, clique em Copiar. Então copie essa textura. E então, no menu suspenso, clique em uma nova textura de atlas
e, em seguida, vamos
colar o atlas Assim. Ok, então você
deve ver a imagem inteira. Agora, queremos editar a região e selecionar o toco que
queremos usar em nossa cena Então, acho que este tem um toco um
pouco menos avermelhado, que parece mais próximo da nossa
árvore real Então, vamos fazer essa. Clique em salvar. Agora vou clicar com o botão
direito e salvá-lo em uma nova cena. Então, vamos dizer stump dot TACN. Agora, se você se lembra, queremos compensar
esse toco Talvez precisemos de qualquer maneira. Acho que, nesse caso
, precisa estar
alguns pixels abaixo. Então isso significa que precisamos de outro
nó, dois D na raiz. Então, clique com o botão direito do mouse em Adicionar um nó filho, nó dois D e, em seguida,
clique com o botão direito do mouse e faça disso a raiz. Ok, agora isso é apenas
um Sprite dois D. Ok, então a textura do toco
é um Sprite dois D, e então a raiz é o Então, agora vamos salvar
a cena do toco. Pegue o sprite, pressione W, mova-o provavelmente para a direita para fins de classificação
Y. Volte para o mundo.
Agora temos o toco Vamos criar mais alguns tocos e criar mais tocos em
toda a cena Se acontecer de você
selecionar acidentalmente a grama ou a terra, o que você pode fazer é
subir até aqui no canto superior esquerdo e bloquear os
nós dessa forma E agora você não deveria ser
capaz de selecioná-los, eu acredito. Então, se pressionarmos Q e selecionarmos o toco ou
ao redor do toco, tudo Portanto, agora esses nós não
devem poder ser selecionáveis
clicando no mapa Vamos descer até os
tocos aqui embaixo. Eles não estão usando essa cena básica
correta. Na verdade, vou apenas
selecioná-los e excluí-los. E vamos nos livrar do
nó dois D também. Ok, pesquise o
projeto em busca de tocos. Coloque isso em adereços como esses. Ok, agora vamos diminuir o zoom. Encontramos esse reservatório, aperte W para movê-lo,
posicione-o onde quiser Controlei você para duplicá-lo. Ok, agora tem o nome de quando é criado como adereço , então é mais parecido com
o que estamos procurando E basta colocar alguns tocos
ao redor da cena, você sabe, apenas coisas que você pode encontrar que são mais interessantes de se ver
do que apenas grama Claro, o pacote
tem outras coisas como edifícios para,
tipo, um jogo de artesanato Não achei que fossem
os mais apropriados. E se você realmente vai
construir prédios, acho que
começaria a argumentar que
realmente precisa das formas de colisão
e, possivelmente, dos agentes de navegação para torná-la mais crível Mas estamos mantendo o mais
simplista possível, porque estamos apenas
fazendo, você sabe,
um jogo muito simples, tipo sobrevivente Acho que já há o suficiente no
curso para que, você sabe, eu não
queira sobrecarregar ninguém, mas se, no final, você realmente quiser entender os agentes de navegação
e os tocos, me avise Eu tenho alguns vídeos no
YouTube para esse tipo de coisa. Se você pesquisar o agente de navegação do
tutorial Chris, deverá
conseguir encontrá-los, se quiser
começar com isso. Mas sim,
parece uma cena decente montada. Tudo bem, jogue Vamos correr por aí. Nossa cena. Nós temos os tocos. Agora, podemos simplesmente
percorrê-lo. Tudo bem. Agora, aqui, isso está
um pouco menos certo. Podemos ver que a classificação
nessa árvore não está correta. Na verdade, a árvore
não está nem um pouco ordenada. Acho que sim, acho que aqui
precisamos entrar na cena
das árvores de outono
e tentar consertar isso. Ok, então vamos para a visão
local da cena
aqui no canto superior esquerdo. Estamos vendo a cena do outono das
árvores. Clique na raiz. E talvez o que
precisemos aqui seja
verificar por que a classificação está
ativada para essa cena, e talvez você precise fazer isso também
na cena principal Portanto, a ordenação Y está ativada. Observe que meus jogos
ainda estão rodando, então eu posso voltar e ver imediatamente se
funcionou ou não. E atualmente, não
é. Então, deixe-me ver aquela árvore no mundo. É realmente parte
dos pais? Oh, você sabe o que deve
ser? São os blocos da Árvore. Ok, então temos que
entrar nos blocos de árvores, clicar no bloco de árvore
ordenando YSort Ah, sim, quando você cria um
novo nível da hierarquia, se você ainda quiser que a
classificação Y esteja lá,
você deve atribuir YSOrdenabled Então, props ativou o YSorting,
mas o Tree Block não. Agora o Tree Block tem. Então, se eu voltar ao jogo,
é por que classificar. Ok, então queremos ser
capazes de caminhar sobre os tocos e ver se
podemos classificar na frente e
atrás
do toco E, na
maioria das vezes, isso funciona. Agora, eu também notei que há um pequeno
problema com as árvores. Eles fazem a classificação, ou pelo
menos estavam fazendo
a classificação, espere Deixe-me verificar com a árvore aqui. Sim, este está funcionando. Mas a posição de onde está sendo
classificado está bem errada. Então, o que eu realmente
quero fazer é entrar na cena
da árvore base para que
ela se aplique às duas árvores, e certifique-se de que você esteja na visão
local aqui se tiver o jogo rodando
no canto superior esquerdo. Selecione o nó Sprite two D porque estamos controlando
o deslocamento do Pressione W e, em seguida, mova-a para baixo, provavelmente
em algum lugar como lá. Vou voltar ao jogo agora. E então você
tenta andar assim, você deve ver que a
classificação Y é muito melhor Então, aqui estamos em
frente
à árvore, como seria de esperar. E então aqui estamos
atrás da árvore. Então, isso é muito melhor.
Você precisa acertar essas compensações ou as coisas
simplesmente não parecerão certas E isso
parece ser a maior parte do que
precisamos aqui para os adereços de nível Eu também poderia criar um grupo de
tocos, então eu poderia pegar
esses 16 tocos e dar a eles um Então, vamos clicar com o botão direito do mouse
e reverter para um novo nó. E então faremos um nó dois D. Então, agora todos esses tocos
foram agrupados em um nó dois D. Vamos chamar isso de bloco de
coto Clique com o botão direito do mouse aqui e
salve o bloco como sua própria cena
na pasta de objetos E agora podemos simplesmente duplicar
nosso bloco de tocos, pressionar W, movê-lo pela
tela e,
você sabe, colocar tocos Portanto, não é exatamente como a geração
processual aqui, mas uma ideia semelhante em
que estamos apenas
tentando preencher o mapeamento
com o padrão Dos parâmetros, que
basicamente são apenas duplicar as posições dos tocos
e depois Então, parece um pouco diferente. E podemos rodar
um jogo mais uma vez. Temos a classificação Weiss
funcionando muito bem aqui. Talvez para o toco, queiramos
alterá-lo em alguns pixels para que possamos
entrar na cena do toco E então vamos para a visualização
local e moveremos
o deslocamento de dois D do sprite
para baixo alguns pixels Então, vamos ver como
isso é agora. Talvez eu tenha confundido a
direção. Na verdade, talvez
precisemos fazer mais
assim e depois clicar em salvar. Então, estamos aumentando isso. Ok,
isso está atrás do toco Isso está na frente do toco. Ok. Sim, isso parece
um pouco certo. Portanto, apenas a parte inferior
do coto deve estar abaixo
do ponto 00 do progenitor E vamos dar uma volta. Sim, vamos ver apenas
tocos e árvores. Na verdade, não precisa ser
muito variado aqui, porque o foco está apenas no
combate e
será subir de nível, obter notas e esse tipo notas e Mas ter algo em segundo plano torna
tudo mais interessante. Então, eu só queria
passar por tudo isso. Obviamente, você pode mover
manualmente alguns
desses tocos para fora
do caminho se eles
acabarem na estrada da
mesma forma Então, vamos ao
mundo, vamos encontrar aquele toco que estava
na estrada, ok? Vou pressionar Q, vamos selecioná-lo. Então, vemos o bloco três de Stump
aqui à esquerda. Clique com o botão direito do mouse e clique em Filhos
editáveis. Em seguida, clique no coto, retire-o do caminho e faça a mesma coisa com qualquer
outro toco E aqui está um. Ok, então eu vou
selecionar esse nó, Stump block two. Seremos crianças
editáveis Em seguida, clique no coto
individual, W para movê-lo, mova-o para fora
do caminho e pronto Ok, também podemos fazer isso
com essa árvore aqui em cima. Então isso faz parte do bloco cinco da
Árvore. Vamos torná-lo editável. Selecione a árvore e mova-a. Oh,
tem outro aqui. Interessante Na verdade, devo ter duplicado um
bloco de árvore no mesmo local Sim, certo. Vamos passar por
aqui. Tudo bem Ok, eu realmente não vejo nenhuma
outra árvore na estrada. Há um toco aqui, então vou tentar consertá-lo
também. W para movê-lo,
tire-o do caminho. Torne o pai editável,
se necessário. E isso provavelmente
vai ficar quase tudo bem. Um último.
Crianças tão editáveis. Então, selecione-o. Torne o pai editável, selecione o nó individual e retire-o do caminho.
E é basicamente isso. Portanto, reduza tudo, para que não
sobrecarregue sua hierarquia Essa é uma das razões pelas quais eu criei o prop node, para começar Hum, se você tivesse, tipo, texturas de
flores ou outros rabiscos, talvez pedras, você provavelmente os colocaria em uma camada separada de pedras ou
rabiscos aqui em cima
e apenas os posicionaria em
um índice Z que é mais alto do que Essa seria uma boa maneira
de começar com isso. Como alternativa, eles podem ser
seus objetos individuais vistos. Mas não tenho certeza sobre o
desempenho. Eu diria que, se for
parte do mapa de blocos, provavelmente
é muito
melhor do que se eles fossem,
você sabe, seus próprios
nós na cena do jogo. Mas, desde que você não
tenha muitos,
provavelmente não é um Um, então essa será basicamente
nossa
parte de mapeamento de blocos do curso nossa
parte de mapeamento de blocos do E a partir daqui, podemos simplesmente começar
a montar
armas e inimigos,
ganhar experiência, subir de nível, HP,
todos esses recursos do
tipo a montar
armas e inimigos,
ganhar experiência, subir de nível, HP, RPGSh
rogue
13. Projéteis gerados com um cronômetro: O personagem pode se
mover. uma
espécie de
mundo de jogo para jogar. Em seguida, o que precisamos
fazer é criar um ataque com um
cronômetro que criará um projétil onde
possamos usá-lo para atacar inimigos sem precisar nenhuma outra entrada importante
do Em jogos de sobrevivência, você normalmente acaba acumulando várias
armas diferentes, e elas são
acionadas automaticamente para A única coisa com que você precisa se
preocupar é andar
pela tela e deixar as armas trabalharem
enquanto evita os inimigos. E esse é basicamente
o ciclo de jogo. Então, comece com isso. Vamos criar nosso
script e player de armas. Então, nesta cena em dois D, vou
clicar com o botão direito na raiz. Vamos adicionar um novo
nó filho D, nó dois D aqui. Vou renomear
isso para arma, vamos
clicar com o botão direito do mouse e anexar um script para ser arma DotGD E isso pode ir para a pasta do
player por enquanto. Então, vamos ter
esse script de armas. Podemos até mesmo fazer dela a
arma 2 D, honestamente. Então, se quisermos
entrar no sistema de arquivos, podemos renomeá-lo
para arma dois D, se isso fizer mais sentido Ok, então o que esse script de arma em dois
D precisará
para criar os objetos de
jogo de projéteis que na verdade, são a
representação em dois D da arma
no mundo do jogo que pode danificar um inimigo é que
precisaremos de um cronômetro Então eu vou dizer var
timer do tipo timer. Agora, você pode
adicioná-los diretamente
no inspetor de cena
aqui à direita, como você adicionaria outros nós Mas eu não quero
ter que fazer isso para cada
script de arma que eu crio. Então, para tornar isso um
pouco mais rápido e fácil, direi que a função de
sublinhado está pronta Então, quando nosso script estiver pronto, pegaremos a variável
do cronômetro e a definiremos como um novo cronômetro Bem, adicione o cronômetro como filho, então adicione o cronômetro infantil Isso significa que
esse novo cronômetro existirá sob a arma Se removermos a arma, também
removeremos o cronômetro E então queremos nos conectar
ao sinal do cronômetro. Portanto, o cronômetro tem um sinal de
tempo limite, e queremos conectá-lo a uma função,
uma função
que pode ser chamada, para que
possamos dizer “tempo limite de tempo E aqui embaixo, podemos
funcionar no tempo limite do cronômetro. Agora, esse tempo limite do sinal na verdade
não envia nenhum dado, então não precisamos de
parênteses E então essa
função terá um tipo de retorno de vazio Então, quando o tempo acabar, queremos basicamente
lançar nosso feitiço Queremos
invocar os projéteis. Então eu acho que cast é um bom
nome para essa função. Então, vamos apenas dizer lançar, e queremos
passar na direção que nosso projétil será lançado Então, se estivermos voltados para cima,
vamos lançar para cima. Então, podemos obter uma referência para a
direção voltada para isso, mas voltaremos
a isso em um segundo. Então, teremos uma função convertida, e isso tomará a direção
P do vetor dois, a direção em que estamos
lançando, e podemos retornar vazio para isso Portanto, para que o
sinal de tempo limite seja atingido, precisamos primeiro iniciar
o cronômetro. Então, diremos que o timer dot start. Então, o tempo que queremos
configurar por quanto tempo até
criarmos uma instância
de projétil dependerá
da definição de cada arma de
projétil Mais tarde, teremos diferentes
níveis de armas, então podemos realmente
mudar o
resfriamento à medida que o nível da arma sobe para que possamos atirar com mais frequência seria uma forma de
fortalecermos nosso personagem. Para a arma dois D,
vamos querer ter essa definição como
um recurso que possamos usar para que nossa arma
saiba como operar. Então, vamos exportar VR
e, digamos, a definição
da definição do tipo de arma, e
precisaremos criá-la. Então, no sistema de arquivos, vamos expandir para fora
e, em seguida,
vou criar uma nova
pasta para nossas armas Então, vou clicar com o
botão direito do mouse nos recursos e fazer Criar novas armas de pasta. E dentro dessa pasta, vou criar um novo recurso. Então, clique com o botão direito em Novo recurso. E vamos criá-lo como um recurso
básico por enquanto. Eu vou dizer definição de lança. Como nosso personagem é um ragonte daremos a ele uma lança
como arma padrão Então, vou salvá-lo aqui, Script, precisamos criar nossa
nova definição de arma. Então, vamos clicar com o botão direito nas armas criar um novo script. Digamos que a
definição de arma no momento seja herdada do
recurso e a criará Então, agora vamos para a definição da
arma. Vamos dar a ela o
nome da classe, a definição da arma. E aqui é onde
vamos definir as estatísticas nas especificações da interface, como o nome de
como nossa arma é representada
em um formato de dados, mas não no mundo do jogo Isso será mais
da classe de projéteis, que se estende do
nó ao D. Então precisamos de alguns
aqui para juntar
tudo Eu diria que o sistema de armas é provavelmente a parte mais
complicada, então vou tentar examiná-la
minuciosamente. Então, primeiro, talvez
queiramos definir um nome. Então, em export var name. Portanto, os nós, por padrão, têm uma propriedade de nome, mas
os recursos não. Portanto, podemos tirar proveito disso definindo um nome de string
personalizado. Então esse
será o nome de exibição, como representamos na interface do usuário. E então poderíamos dizer no ícone
export var do
tipo textura dois D. Mais tarde, adicionaremos blocos de estatísticas
personalizados para
cada nível de arma, mas isso é demais
para este vídeo Então, por enquanto, o que precisamos daqui
pode ser algo mais parecido com uma função de resfriamento, e podemos passar de um nível
aqui porque, na verdade,
não sabemos que nível a arma está a
partir da definição da arma. Isso será definido na arma de tempo
de execução, dois objetos
D aqui. Porque isso sobe de nível no jogo. E então a definição é
mais uma definição de editor. Ele configura como a arma
opera em cada nível. Então, essas são coisas separadas. O nível da arma
está em D. Então, queremos passar o nível em que
ela está atualmente. Então, poderíamos dizer, nível P, e isso vai
ser um número inteiro Devolveremos uma bóia para
esfriar a arma. Então, por enquanto,
vou simplificar isso e, digamos,
se você virar um ponto. Posteriormente, podemos torná-lo
mais personalizado
resolvendo o resfriamento com base
no nível que passamos Mas basta simplificar
aqui para que possamos testar se tudo que a arma
dois D realmente funciona. Então, na arma dois D, queremos
iniciar o cronômetro em,
digamos, ponto de definição Get Cool Down. E vamos simplesmente passar digamos, menos um aqui porque
pretendemos alterá-lo. Então, estou colocando uma pequena
nota aqui para me
lembrar de obter
o nível real, apenas uma nota para que, você sabe, uma vez
que testemos isso, possamos continuar a partir daí e
implementar totalmente o sistema. Ok, também vamos
querer conseguir a instância
do projétil que
estamos tentando criar Então, vamos fazer uma
função get scene. Também podemos passar de nível. Isso
retornará uma cena lotada. Vamos criar
essa cena de arma, o projétil,
mais especificamente Então, em duas visualizações em D,
vamos adicionar uma nova cena. Vamos criar
uma cena em dois D aqui. Vou renomear
isso para Spear. Vamos clicar com o botão direito do mouse
nele, anexar um script, e esse
será o ponto de projétil GD Eu provavelmente quero
salvar isso e, oh, digamos que a pasta de armas. Eu acho que isso faz
sentido. E, em seguida abra Criar, isso é cancelar. Create está aqui, e então
queremos dar a ela o nome de
classe projétil, e salvaremos o spear
dot TSCN dentro das armas para que possamos
realmente Queremos anexar
um Sprite a ele. Clique em Spear, anexe
um nó Sprite two D
e, em seguida, vamos
pegar a arma Que fará parte de uma textura de atlas
aqui no canto superior direito Então, faça uma textura de atlas. E então vamos
carregar rapidamente nosso projeto. Acho que foi 16 por 16. E então precisamos
obter nossa textura. Então vá para a arte no canto inferior esquerdo. Vá para Pixel Crawler, vá para armas, madeira E então a palavra ponto PNG, nós a colocamos
no slot Atlas Ok. E agora
podemos editar a região,
ampliar e queremos a
lança, que está aqui Então, vamos arrastar
isso e clicar em Fechar. Ok, agora temos
o sprite da lança. Assim, podemos pelo menos ver
nosso projétil no topo do jogo quando ele estiver
basicamente carregado Queremos incluir essa cena. Vamos voltar para o jogador, e eu vou
abrir o script da arma. Em seguida, vou clicar com o botão direito do mouse na definição da
arma
e no símbolo Loup. E para obter a cena, simplesmente
faremos
algo como retornar a carga. E agora queremos carregar
a cena da lança. Então cuspa o ponto TSN. Você pode ver que você
pode simplesmente encontrá-lo
nos recursos weapons spit dot TSEN e colocá-lo lá Então, mais uma vez, essa é
uma medida temporária apenas para simplificar para
que não precisemos implementá-la
totalmente. Então, em nossa arma dois
D, quando lançamos, vamos fazer com que essa arma seja
vista a partir da definição. Então, queremos dizer var, projétil
será do tipo projétil, e vamos definir
isso igual à definição Get SN e vamos dizer menos um aqui para
o nível. Você sabe o que? Na verdade, poderíamos começar a declarar nosso
nível real da arma Então, vamos fazer disso um nível um. Eu direi no nível export var. Esse será um
tipo de número inteiro e
começará em um Ok, agora podemos simplesmente passar o nível para essas funções, nos acalmar e ser vistos. Ainda não faz nada com isso ,
mas pelo menos o
temos lá. E, claro, quando aumentarmos o
nível de nossa arma, aumentaremos
o nível aqui em um, e isso mudará o que
essas funções nos
devolvem se tentarmos
esfriar ou pegar a cena Ok, então nós pegamos a cena, e então
queremos instanciar nela Então, queremos
adicioná-lo quando criança ao nosso grupo de projéteis
e à cena principal Onde estamos fazendo com que o nodo realmente gere os
projéteis Vamos ver o
cenário mundial em duas vistas em D, e vou minimizar isso. Vamos clicar com o botão direito do mouse em Mundo
e no canto superior esquerdo e adicionar um novo nó dois D.
Vou apenas renomear
esses projéteis Agora vamos para o canto superior direito e vou
usar grupos aqui. Vamos atribuir um grupo ao nó
de projéteis. Então, adicione um novo grupo. Vou apenas fazer projéteis em
letras minúsculas, torná-los globais, e vou dizer o nó em que todos os projéteis estão
contidos Ok, agora podemos ver se
o nó de projéteis
tem esse grupo, e podemos referenciar o nó
fazendo primeiro no grupo Então, vamos voltar ao roteiro. É o sublinhado dos projéteis. Também podemos declarar isso
como uma constante, se quisermos. Então, eu diria que um grupo de
projéteis constantes, tornando a constante em maiúsculas
a convenção padrão Isso deixa claro que
esse é um valor constante que não vai mudar e se diferencia de uma variável normal, como
nível ou definição, que pode mudar
durante o jogo Então, vamos definir isso
igual a projéteis minúsculas, assim como Então, vamos querer
pegar esse nó e adicioná-lo a esse nó. Então, vamos armazená-lo em cache. Como variável local, digamos var
projectiles parent, e isso será um nó Então, para preparar isso, vamos fazer isso antes do cronômetro. O
pai do projétil sublinhado é igual ao nó G. Mas temos que pegar
a árvore primeiro. Então, pegue o ponto da árvore, obtenha o
primeiro nó e o grupo, e queremos o grupo de
projéteis, que é um nome de string Na maioria dos casos, strings e
nomes de strings podem ser
usados de forma intercambiável Ele se converte entre os tipos automaticamente em muitos casos na parte
de trás Podemos declará-lo
como um nome de string aqui porque é isso que
ele espera disso Então, obtemos o primeiro
nó do grupo. Se isso não existir, provavelmente
teremos
um erro no console, o que
é bom. Então, só precisamos
ter certeza de que nossos níveis de jogo realmente tenham um
nó de projéteis como esse Se quiser, você pode salvar esse nó em seu
projeto e reutilizá-lo, clique com o botão
direito do mouse em Salvar
cena de ramificações e, em seguida, talvez
criemos uma pasta de níveis Para qualquer coisa relacionada aos níveis coloque
os projéteis
pontilhem o TSC aqui Então, se você continuar
reutilizando-o a partir daqui, eles sempre estarão
nesse grupo de projéteis
e, basicamente, você não deveria
dessincronizá-lo dessincronizá-lo Então, agora você pode reutilizar a cena dos
projéteis sem se preocupar com a
mudança de valores entre os
níveis em que você os usa, então isso pode ser
um E agora, depois de
criarmos o projétil, queremos ter certeza de
que ele seja adicionado como filho ao
projétil pai Então, sublinhe os projéteis, projéteis de
pais e filhos. Assim. Nós podemos nos
livrar disso agora. E então só queremos
ter certeza de que a posição global é igual à posição global da arma dois
D. Então, digamos que a posição
global do projétil seja igual à
posição global aqui Então, estamos assumindo a posição
do nó D da arma dois. E então precisamos
passá-la em direção ao elenco. Então, vamos fazer o
vetor de dois pontos, certo? São maiúsculas.
Um valor constante. E agora o script deve
poder ser executado sem erros. Ok, então tem a cena. Eu sei qual tempo de recarga definir. E sabe criar uma cópia
do projétil em cima do nó D da arma
sempre que o cronômetro passar Então, vamos fazer isso
e tentar. Podemos ver o tempo de
recarga e o valor nulo. Então, na verdade, não definimos
a definição da arma. Então, poderíamos dizer, afirmar
que a definição
não é igual a nula Portanto, cada arma requer
um conjunto de definições de arma. Então, precisamos
ir até o jogador. Precisamos encontrar esse nodo D da
arma. Vou renomeá-la como arma dois D. Vamos até o
inspetor no canto superior direito
e, em seguida, definir nossa definição de
arma Então, nova
definição de arma, expanda isso. Possivelmente vamos
querer o ícone e o nome. Então eu vou chamar isso de lança. E vamos pegar o ícone
da cena da lança. Então, podemos simplesmente pegar o mesmo sprite e
copiá-lo para o ícone Então, vou clicar com
o botão direito na textura. E copie. Agora vamos para a
cena do jogador em que temos definição
da arma
definida,
clique com o botão direito do mouse no ícone e cole nele. Ok, então aqui está nossa
representação da lança na interface do usuário. Então, clicamos em Play e colocamos a lança na instância
a cada 1 segundo Agora nosso projétil ainda
não se move. Ele não tem código para se mover, mas temos tempo
para colocar
os projéteis no mundo
na hora
certa, com
base em nossa classe de definição de arma Claro, há
muito mais do que isso. Ainda não mexemos com as estatísticas nem nada, mas
esse é um bom começo Então, vou falar mais sobre
isso na próxima
14. Mova os projéteis na direção do lançamento: Então, neste momento,
estamos prontos para começar a colocar inimigos
no jogo e, em seguida, fazer com que nossos projéteis capazes de atingi-los se movendo
pela tela Ok, então vamos fazer com
que nossos projéteis possam se mover agora na direção em
que foram lançados Vou até a cena da lança,
e esse é o projétil da
lança, aquele que realmente aparece
no mundo
do jogo Vamos abrir esse script. E vamos querer
colocar uma função
de lançamento aqui para que, quando nosso
projétil for instanciado, outro script possa dizer em que direção ele se moverá Então, vou colocar
a função launch e vamos
passar em uma direção. Então P sublinha o vetor de
direção dois, e essa
será a direção em que
os projéteis
se moverão Então, queremos pegar essa direção de
lançamento e
torná-la local para que possamos
usá-la em nossas funções de processo, o
processo será atualizado
a cada segundo e traduzir nosso
nó de projétil pela tela Então, a
direção var será o vetor dois, e vamos
configurá-la aqui mesmo no lançamento. Portanto, a direção é igual à direção P. Agora, quando lançamos
um projétil, também
queremos colocá-lo na fila para liberado após um certo
período de tempo Caso contrário, projéteis
que nunca atingissem um alvo existiriam no mundo do
seu jogo
para sempre e
acabariam por causar problemas de
desempenho Portanto, queremos garantir
que os objetos sejam libertados eventualmente. Então, podemos fazer isso esperando um certo período de
tempo. Eu vou dizer espere. Então, isso basicamente significa que ele
voltará para o resto
do código que segue essa linha depois que a
condição for atendida. Então, vamos dizer: pegue uma árvore. Então, estamos obtendo a árvore de cena
atual na qual esse nó de projétil
existe
e, em seguida, criaremos
o cronômetro E nós damos um tempo. Então,
digamos que 1,0 segundo. Tudo o mais você pode
deixar como padrão. Então, tudo isso
significa que estamos aguardando o método de tempo limite
no cronômetro que criamos
usando a árvore de cenas e esperamos um segundo
para que esse tempo limite ocorra E então, uma vez feito isso, podemos colocar apenas um quarto
no nó do projétil Isso vai liberar o
projétil em qualquer coisa abaixo dele. Agora, um projétil
que atinge alvos, se atingir um alvo, provavelmente
se removerá antes disso, mas isso é apenas uma alternativa para
que, se
errar completamente todos os inimigos, acabe
se libertando que, se
errar completamente todos os inimigos, acabe se libertando Ok, e então precisamos que o
projétil realmente se mova. Então, digamos que o
processo de sublinhado de função ou processo de física, na verdade, seja provavelmente um
pouco mais apropriado Vamos fazer isso. Então, geralmente
você usa o processo de física para qualquer coisa que envolva mover objetos físicos
pelo jogo. Agora, este é um nó dois D. Não
estamos adicionando nada parecido física de corpo
rígido
ao projétil, mas apenas para que seu movimento se
sincronize com todo o
resto do sincronize com todo o
resto Se o processo físico for definido para 60 vezes por segundo ou 60 períodos de
movimento por segundo
, ele se moverá
60 vezes por segundo, apenas para mantê-lo consistente
com todo o resto do. Exporte a velocidade var aqui
na parte superior do tipo float. Vamos adicioná-lo a 100. Então essa será apenas a
velocidade padrão do projétil. Então, coisas como a velocidade e a duração que
esse projétil dura no mundo do jogo são estatísticas que eu quero extrair em
um script de estatísticas separado para
que possamos defini-las por arma e por nível de cada arma de uma forma muito
mais organizada Mas, por enquanto,
é bom o suficiente, então trabalharemos nisso mais tarde. Então, queremos dizer
traduza aqui. Qualquer nó TD pode ser traduzido
pela tela. É um movimento sem
qualquer colisão. E vamos dizer
que estamos nos movendo na direção vezes
a
velocidade, vezes o Delta. Agora, se você quiser saber o que isso calcula
quando você está depurando,
atingindo um ponto de interrupção,
talvez queira fazer algo mais parecido
com movimento Var, que é um vetor dois, será igual
a esse bit aqui,
Controle X, cole essa extremidade ali
e, em seguida, basta
traduzir o movimento. Agora, se você atingisse
um ponto de interrupção, aqui mesmo, e talvez
pudéssemos fazer isso apenas
pressionando play, porque o processo
físico será
acionado assim que esse
espírito for criado,
podemos ver na parte inferior que
temos o valor do movimento de
00 e Y é zero, zero,
porque não lançamos o
projétil com essa função,
então ele não tem realmente pressionando play, porque o processo
físico acionado assim que esse
espírito for criado, podemos ver na parte inferior que
temos o valor do movimento de
00 e Y é zero, zero, porque não lançamos o projétil com essa função, o que o padrão é o vetor dois
pontos zero no momento Ok, então eu vou
desfazer o ponto de interrupção. Você. Ok, então feche o jogo. Na verdade, isso traz um bom
ponto que quero abordar, que é que se a
direção for o vetor 20, isso provavelmente
representa um problema, porque sempre
lançamos na direção em os
personagens estão voltados, que nunca deve ser o
vetor dois pontos zero. Portanto, podemos esperar que a função de inicialização
já tenha sido chamada antes de colocá-la totalmente em
cena com Adhild Então, vamos preparar o sublinhado dessa
função. E vamos
afirmar que a direção
não é igual ao vetor 20 Chame o lançamento para definir a direção ou projétil antes de
adicioná-lo à criança Então, queremos
exigir que
já tenhamos definido a direção
com a função de lançamento e observe que devemos chamar o
lançamento antes de chamarmos Add hild Então, a prontidão ocorre depois de ok. Agora, se eu correr, devemos imediatamente clicar na afirmação
, conforme esperado Então, vamos entrar no script D da arma 2, onde adicionamos o filho do
projétil pai Então, agora queremos chamar o lançamento do ponto do
projétil na direção P que
passamos para a função de lançamento Para que ele realmente o configure
para algo adequado. Agora, podemos ver que
aqui embaixo, no tempo limite do vetor, estamos usando o vetor de
dois pontos à direita Então eu acho que seria
uma boa maneira de testar. Nesse caso, ele deve sempre se mover para
a direita. Então, o problema aqui
é que nosso lançamento está tentando
fazer duas coisas distintas. Acho que na verdade faz
mais sentido colocar essa parte na função ready,
já que a estamos usando agora. Então eu vou colar isso
lá, Controle X, isso, controle V, colar
. Isso faz sentido. Assim que o
projétil estiver pronto, nós o preparamos para ser liberado
após um determinado período de tempo Portanto, isso mantém o método de inicialização lidando
apenas com uma coisa, que é basicamente inicializar o objeto depois
de criado Então, essa é quase certamente
a melhor maneira de fazer isso. Ok, agora vamos clicar em play. E temos nosso projétil
disparando para a direita. Você também pode ver que eles duram
apenas 1 segundo, provavelmente não o suficiente, mas é um bom teste para ter certeza de que
estão realmente se liberando Então, neste momento,
haverá apenas uma ou duas lanças na cena
a qualquer momento Isso não deve causar nenhum problema de
desempenho.
15. Configurando inimigos e Hitboxes: Nossos projéteis
se movem para a direita. Agora, vamos criar
um inimigo para que nossos projéteis possam realmente
se conectar a ele e atingi-lo Então, isso
significa que estamos configurando uma caixa de acerto e uma
caixa de dor neste vídeo, e nos preocuparemos com
estatísticas mais tarde, como a HP. Então, no meu projeto agora, vejo na parte inferior, que há
alguns avisos aqui Eles estão apenas mencionando
que, se você não estiver usando um parâmetro, você
deve sublinhá-lo Então, vou clicar em cada um
deles e dar um
pequeno sublinhado Então, eu não estou usando o Delta
neste processo de física do jogador. Então, eu destaco o Delta. Isso implica que
não está sendo usado. E então aqui em outro roteiro, eu vou fazer a mesma coisa. E apenas para qualquer
um desses avisos que você está recebendo, basta repetir Você não está usando o parâmetro e, em
seguida, sublinhe-o para
indicar que você espera não usar o parâmetro e
que isso não é um acidente
ou um erro E vamos seguir em frente e
criar nosso primeiro inimigo. Então, vamos começar com um Oc. Vou criar uma nova
cena aqui no topo, e vamos para duas cenas
D à esquerda. Vou renomear isso para Oc. Vamos clicar com o botão direito,
mudar o tipo para um corpo de personagem dois
D. E selecionar isso. Ok, então eu quero clicar com o botão
direito do mouse no orc e adicionar um nó filho Vamos fazer um sprite TwoD aqui. Além disso, clique com o botão direito aqui e
adicione uma forma de colisão infantil. E à direita,
vamos fazer disso um pequeno círculo,
mais ou como o que você
fez com o jogador. E vamos controlar, salvar a
cena dentro dos personagens. Vou criar uma nova
pasta para os inimigos. Então, inimigos, coloquem isso lá e salvem o TAC da orca Ok, agora nosso orc precisa de
Bright, é claro. Então, vamos selecionar esse nó britânico e desceremos
para o canto inferior esquerdo Vamos procurar, acredito que
foram entidades, multidões, tripulação de orcs, e queremos
pegar uma dessas Então, eu estava apenas usando
o orc padrão para que pudéssemos pegar a folha ociosa Vou selecionar esse nó
Bright two D
e, à
direita, vamos
arrastar e soltar essa folha
ociosa aqui Está bem? Agora, obviamente, temos uma configuração semelhante à do player em que temos uma folha de sprites Precisamos definir quantos quadros H são da esquerda para a direita,
que você pode ver que são quatro. E queremos fazer isso
com um reprodutor de animação. Então, vou clicar em Ok, adicionar um nó filho.
Player de animação. Então selecione o player de animação, desça até o final, faça uma nova animação do Idol. Ok, e precisamos
estruturar algumas das propriedades do
sprite Então, vamos adicionar uma faixa, uma faixa de
propriedades, sprite de dois D e
vamos procurar quadros H.
Então, clique duas vezes nele. Ok, e então repita as
etapas para faixa de propriedades, sprite dois quadros D, V, trilha de
propriedades,
sprite duas texturas D. E no canto inferior direito, habilite o
encaixe aqui e altere o
tempo de encaixe para 0,1 segundos Então, um quadro por
décimo de segundo. E, por fim, à direita, queremos alterar isso para 0,4 segundos de duração total
e ativar o loop OK. Na linha do tempo aqui, volte para o início
da animação, clique com o botão
direito do mouse em inserir uma chave Então, temos nossos quadros H. Queremos pegar isso
e, no canto superior direito, mudamos para quatro. E, em seguida, vFrames,
queremos inserir uma chave. Deixamos isso como um aqui em cima. Clique com o botão direito do mouse para inserir uma moldura. Então esse
será nosso primeiro quadro. Não se preocupe em mostrar todos os quatro quadros de uma só vez, o que será corrigido
automaticamente em um segundo. Em seguida,
queremos clicar com o botão direito do mouse e inserir uma chave para nossa textura, que você pode ver
no canto superior direito que
já está usando
nossa animação como padrão Então, ainda não reproduzimos
a animação, então ela ainda está mostrando quatro
quadros, mas assim que eu jogar, ela mostrará o primeiro
quadro da animação ociosa,
e a seção de quadros
aqui embaixo é atualizada automaticamente de
acordo com o que esperávamos Então, agora queremos
ir para 0,1 segundos. Ele deve encaixar em intervalos de 2,1
segundos
e, em seguida, clicar com o botão direito
do mouse e digitar a tecla por quadro e, em seguida, alterá-la no canto superior
direito para uma aqui em cima Então esse é o segundo
quadro da animação. Em seguida, adicione o valor do
quadro de dois, que é o terceiro quadro aqui e o último
quadro de valor três, que representa o
quarto quadro da animação. Ok, agora, se estamos jogando, devemos ter nossa animação
inativa E para um personagem simples, parecido com um
sobrevivente, só
vamos
colocá-lo voltado para a esquerda e para a direita Então, precisamos apenas de um nó
giratório
nessas animações individuais para
saber se ele está voltado para a
esquerda Então, como isso é para um jogo
simples de sobrevivente, só o
temos voltado para a
esquerda e para a direita Então, precisaremos apenas adicionar
um nó giratório posteriormente. Além
disso, precisamos apenas de nossas animações de corrida ociosa e
morte E é basicamente isso, a menos que um personagem precise de uma animação de ataque
especial. Então, vamos duplicar
a animação ociosa e colocar
nossa animação de execução Para animação de execução, queremos colocar
a textura aqui embaixo e alterar o valor e o
canto superior direito da planilha de execução. Então corra e arraste
para o canto superior direito. OK. E são seis
quadros de animação. Então, queremos pegar os quadros H
aqui e alterá-los para seis. E então queremos adicionar o
quadro cinco e o quadro seis aqui. Então, a chave muda
esse valor e o canto superior direito para
quatro, insere uma chave, altera esse valor para cinco
e, em seguida, pega a duração
da animação de execução e
faz com que seja de 0,6 segundos, aperta play, e devemos
ter nossa animação de execução. Agora, acho que está
compensado incorretamente, menos como era o
ídolo da corrida do jogador Então, precisaremos fazer
essa configuração de deslocamento também. Então, vamos ao ídolo. Vamos mover esse personagem para cima. Certifique-se de selecionar especificamente
o nó do sprite. Em seguida, pressione W para ir para o
modo de movimento e mover o sprite
para cima , de modo que o ponto 00 fique
centralizado em seus pés aqui embaixo Onde quer que esteja, deve estar o centro de gravidade onde toca
o solo Em seguida, vá para transformar
à direita e insira um quadro-chave Portanto, tenho 14
pixels negativos como posição Y. Quadro chave: clique Criar e apenas
reinicie a faixa. Tudo bem. E agora também precisamos estruturar o
keyframe da execução. Então, para correr, vamos
para o canto superior direito, e eu vou fazer isso. Vamos
tentar 27 pixels negativos. Vamos tentar 30 pixels negativos. Achei que eles estão
configurados da mesma forma
que o jogador, o mesmo artista e tudo mais.
Então, vamos estruturar isso E crie. E temos
nossa animação de corrida. Agora, vamos
mudar rapidamente para o Idol. Ok, agora temos nossa animação de
corrida sendo reproduzida. Vamos mudar rapidamente
para o modo inativo e ele jogar. E parece que
os pixels se alinham. Teremos que testar esse
final de jogo, é claro, se quisermos realmente
mostrar a animação de Idle Nesse caso, porém,
talvez nunca mostremos a animação de Idle,
a menos que o inimigo pare de correr em direção ao jogador Mas a ideia, pelo menos com essa
configuração, será que o inimigo esteja sempre
correndo em direção
ao jogador enquanto
o jogador existir. Portanto, talvez nunca
vejamos realmente a animação ociosa. Dependeria de você. Talvez
quando o jogador for derrotado, os personagens simplesmente
comecem a ficar inativos em vez de se moverem mais na tela porque não há
mais jogadores para lutar Mas isso seria apenas
um extra que não é realmente necessário. O que precisamos, porém, é a animação da morte. Então, vamos correr porque acho que a
animação da morte tem seis quadros, e vamos duplicar isso
para fazer uma animação de morte
, então digite Death Enter Vamos
desligar o loop para isso. Os personagens morrem apenas uma vez. Em seguida, queremos pegar
a textura e alterá-la para a
folha Death Sprite no canto inferior esquerdo Arraste isso para o inspetor
e vamos clicar em reproduzir lá. E então, se mudarmos para inativo, parece que ele se alinha e a
execução parece que está alinhada Ok, então isso provavelmente é bom. Acho que a posição sobre
a morte é menos 30. De qualquer forma, temos nosso Oc. Podemos simplesmente colocar um orc
no mundo do jogo. Então, vamos pegar o orc aqui. E, na verdade, provavelmente
queremos a hierarquia de inimigos, então vou clicar com o botão direito do mouse para
inserir um nó Então, no segundo nó D, vamos matar inimigos ou até
mesmo ser NPCs, se quisermos Talvez inimigos sejam melhores. E eu vou
derrubar um orc
do canto inferior esquerdo. Sob os inimigos. Então, podemos ver que ainda não está
exibindo a animação. Então, vou clicar em
Abrir e editar, e vamos ver
o que está acontecendo com isso. Provavelmente precisamos, tipo,
definir uma animação padrão. Então, eu poderia pegar a morte
e transformá-la em ociosa. Vamos defini-lo como inativo. Está bem? Clique em play. Vamos voltar
ao mundo do jogo. Isso resolve isso? Acho que não. Ok, então como
isso não está funcionando, devemos ir para o reset. Animação. Então, sempre que você não está
reproduzindo uma animação, ela é redefinida para esses valores E podemos ver que
os quadros de He aqui, se olharmos no canto superior direito
, estão, na verdade, definidos como um. Então, se definirmos isso para quatro, e acho que agora clicamos em
play no reset, então é isso que devemos ver se voltarmos
ao mundo do jogo. Então salve sua cena de orc,
vá para o mundo do jogo e tudo bem, agora está tudo
certo Então eu vou pressionar W
e mover o c. Ok, e então vamos apenas Controlar D, duplicar mais alguns cs E então eu acho que
a última coisa
que queremos fazer aqui é pegar os inimigos e habilitar o
Order y Sort. Como isso é evidente
para todos os orcs, queremos que os orcs também se classifiquem uns
com os outros Isso pode ser necessário. Então, isso pode ser
necessário para colocar lá. Ok, então nossas lanças podem se mover, mas
na verdade não podem atingir nada Não montamos uma caixa de ataque e nossos orcs podem existir, mas eles não têm uma caixa de HRT
para realmente sofrer danos Então, as caixas HRT e as caixas de sucesso e Gadot D serão
os Ds da Área dois Se você
vem da unidade,
seria mais como uma zona de gatilho. Vamos até Spear
e criaremos uma Área dois D que
criaremos como nossa caixa de sucesso Então, vou clicar com o botão direito do mouse na lança adicionar o nó filho, Área dois D, e vou renomeá-la
rapidamente para clicar na caixa dois D. Vamos clicar com o botão direito do mouse
nela e anexar um script Agora, isso
provavelmente será mais parecido com a raiz. Então, deixe-me ver.
Acho que colocá-lo na pasta de armas faz sentido
aqui e clicaremos em abrir. Então, criaremos o script
em weaponlash Hit Box two D. Create dê a ele o
nome de classe Hit box two D. Ok, então em nosso script HIT box, queremos nos conectar imediatamente
ao sinal que a área já tem,
que é
a área que é Porque o que estamos
tentando verificar é se entramos na
área de uma caixa RT. Então, se fizermos a função underscore
ready, então, em ready, podemos fazer a conexão de pontos
na área inserida e vamos
conectá-la a uma área inserida, que é uma função que
estamos prestes a configurar Portanto, crie o
sublinhado da função na área Inserida. Isso vai receber e a
área dois D é o parâmetro. Então P área dois D e tipo de
retorno v Ok, então uma área entrou nessa área, que tipo de áreas
nos preocupamos? Nós nos preocupamos com caixas
especificamente feridas. Então, se a área P é uma caixa de Hurt, dois D e o
tipo ainda não existe, então deve ser uma era aqui. Então, por enquanto,
poderíamos dizer algo como impressões, então, por enquanto, poderíamos dizer algo
como Prance, que imprimirá uma
mensagem no console Por que não tentamos assim? Porcentagens e aspas significam que vamos
substituir isso por uma string Porcentagens de sucesso. Poderíamos até dizer, na posição, porcentagens, e então
substituiremos essas sequências usando
outro E temos três strings que precisamos substituir
dentro dessa string Então, vamos
passar uma matriz de valores que queremos fazer
para a substituição. Então, a primeira será, digamos, eu. Então, vamos
pegar a caixa Hit, que atingirá a caixa Hurt
da área P. E então vamos
dizer que a posição é a posição global
do ponto da área P. Portanto, uma Área dois D
ainda está no nó dois D, então ela ainda tem uma posição
global. Isso funcionará
apenas para perceber que nossa caixa de sucesso está, na verdade,
atingindo a caixa de HRT Ok, agora precisamos
fazer uma caixa RT no Oc. Então, vamos para o Oc e eu vou
clicar com o botão direito aqui e criar um nó ágil Area two D. Vamos renomear isso
para Hurt Box,
e eu vou colocar B em
maiúscula para caixa e eu vou colocar B em
maiúscula para Dois D. Vamos clicar com o botão
direito do mouse e anexar um script. Vamos querer
machucar o Box 2 D. Isso pode aparecer em talvez
personagens por enquanto. Na verdade, não teremos
nenhum objeto destrutível, pelo
menos nesta demonstração Então você pode argumentar: Ok, isso pertence mais
à pasta de objetos, ou talvez você esteja organizando
seus scripts
em uma pasta de scripts que
contém especificamente scripts A
organização depende de você. É mais ou menos
assim que estou fazendo as coisas. Então, os personagens
cortam Hurt Box two D, vamos criá-lo lá Ok, agora esse script, precisamos chamá-lo nome de
classe Hurt Box
two D. Por enquanto, não
vamos mudar mais
nada sobre ele. Só queremos aquela etiqueta
identificadora, Hurt Box two D. Agora, a caixa Hurt, você pode ver que ela também precisa de uma
forma de colisão Então, vamos clicar com o botão direito do mouse e adicionar um nó secundário, forma de colisão E então, à direita,
vou criar uma
nova forma de círculo. Assim, podemos definir onde
esse personagem pode ser atingido. Então, eu poderia pressionar W e movê-lo para cima. Podemos fazer com que seja
meio grande aqui. Então, se eu torná-lo maior
, mais ou menos
assim, tudo bem. Você também pode preferir
um formato de cápsula. Portanto, se selecionarmos o formato de
cápsula você também poderá preferir um formato de
cápsula aqui. Então, se fizermos uma forma de cápsula, que é mais parecida com um humanóide, podemos
selecionar a forma de
cápsula E então aqui,
podemos simplesmente pressionar W, movê-lo para cá. Isso seria bom se você quisesse que
todos os pixels exibidos na tela
do k fossem, na verdade, áreas
danificáveis Então você poderia apresentar esse argumento. E então nós só queremos que isso seja uma criança
do Hurt Box Tot. E então nosso orc também
precisa de uma forma de colisão. Então, onde os pés podem
colidir para o c? Então, isso vai fazer mais sentido como uma forma de
círculo aqui. E então olhamos para os
pés dos orcs. Vamos reduzi-lo
aqui, algo assim. Então, se escolhermos
ter colisões entre nossos orcs e outros
orcs ou orcs e o jogador, outros adereços e o objeto
, essa é a forma que realmente
usaríamos Agora, se você quiser que seus
inimigos colidam com outros inimigos e
jogadores e coisas
assim quando eles se movem
usando mover e deslizar, isso é algo que
um personagem com corpo dois D pode fazer fora da caixa Mas terá
um custo de desempenho
associado a isso,
já que na verdade está calculando movimento com base na física Se você quiser obter o número
máximo de
caracteres na tela, considere usar a
tradução, assim como fizemos com a lança, o que significa que ela
se moverá independentemente do que na tela na direção em
que está tentando se mover Então, mantendo-o o mais idiota simples possível, depende de você o que você
quer no final do dia E quantos milhares de inimigos você precisa
na tela ao mesmo tempo. Ok, então antes de concluirmos isso, acho que a lança também precisa uma forma de colisão
para a caixa de impacto Então, vou clicar com o botão direito
aqui, adicionar um nó filho, forma de
colisão dois D.
Vamos para o canto superior direito Vamos fazer disso uma forma de círculo, e então vamos pegar a
forma de círculo e movê-la até
a ponta da lança e
encolhê-la, algo assim Você pode preferir que
seja em forma de cápsula. Depende de quão
exigente você quer ser. Obviamente, a cápsula pode ser mais oval ou menos
um círculo puro. Ou talvez até mesmo um retângulo. Então, se você quiser
usar um retângulo, você pode fazer, digamos, a forma de um
retângulo aqui em cima,
encolher os lados assim, abaixar isso e
talvez Portanto, use
aqui a forma primitiva
mais simples possível para a caixa de sucesso e, ao
mesmo tempo, tente manter a forma real do sprite onde
faz sentido Então eu acho que isso
seria muito bom. Eu não acho que alguém
realmente notaria que, você sabe, talvez essa metade
da lança não tenha atingido aqui Se você realmente
quisesse ser exigente, poderia fazer assim E sim, talvez isso
fosse um pouco melhor. Apenas um pouco
menos de chance de
atingi-lo pode deslizar ao longo da
borda aqui à esquerda. Mais uma vez, uma dessas opções, experimente e tenha uma ideia de como as coisas estão funcionando e veja se é adequado para
o seu jogo ou não. Vamos começar o jogo agora
e tentaremos fazer com que os orcs atinjam com esses projéteis Então, vamos ver que não é possível
instanciar um nulo. Nível. OK. Então, neste momento, o projétil não está mais
colocado na arma dois D.
Isso é interessante. Vamos até o jogador, e
eu vou pegar a arma dois D. Podemos ver que a definição da
arma está definida aqui. Se eu expandir a arma dois D, vamos entrar na definição da
arma. Então, temos o símbolo de busca. Talvez eu tenha movido a arma.
Vamos ver. Onde está a lança Eu acidentalmente movi a lança da lança de armas para essa
pasta diferente Então, vamos
voltar para as armas. Ok, vai funcionar bem
agora. Vamos clicar em Carregar. Ok, e então
temos as lanças. Então, vamos para a saída. Vou
diminuir um pouco, esses orcs estão realmente sendo atingidos pela
lança, o que é bom Podemos ver a posição
em que isso ocorreu. As informações da caixa de acerto
não são muito úteis, mas pelo menos sabemos que
tipo está atingindo qual tipo Se fosse um tipo de área completamente
diferente
, diria o
nome da classe aqui. E isso está praticamente funcionando.
16. Causando dano aos inimigos com Hitboxes e Estatísticas: As caixas de acerto e as
caixas feridas estão funcionando suficiente para que possamos perceber
o impacto na caixa HRT, o
que será
o início de
causar dano aos nossos inimigos orcs Então, neste vídeo, precisamos
configurar as estatísticas do
orc e ter certeza que estamos passando o dano atingido para o orc que
sofrerá Uma grande parte deste
tutorial será na verdade, definir as
estatísticas da lança, as estatísticas do
orc e configurar a interação entre
as duas Então, se entrarmos no script do
projétil, queremos que o projétil
responda quando a caixa atingida atingir a caixa ferida, passando
o dano do projétil para
a caixa
ferida e atingindo-a Então, vou colocar uma barra de
exportação at para caixas de sucesso. Isso vai ser uma matriz
de hit box two D. Ok. Agora, aqueles que eu quero atribuir
na inspeção. Então, se eu clicar
na matriz Spear dois D, a matriz de
caixas de acerto está aqui Precisamos aumentar
seu tamanho para um, clicar em um sinal
no primeiro elemento e escolher a caixa de acerto. Então, agora temos uma referência
à caixa de acerto do projétil
dentro do script É feito como uma matriz porque algumas armas podem, na verdade,
ter duas ou mais caixas de acerto. Então, fazemos disso uma
opção desde o início. E o que vamos fazer é nos conectar
a
cada sinal da caixa de acerto ao cada sinal da caixa de acerto atingido para que nosso projétil
possa causar o dano Então, vamos clicar com o botão direito do mouse na caixa de
acerto dois símbolos D. aqui, símbolo
do Lou, e isso passará para
o script da caixa de acerto Então, em vez de
imprimir o que
clicamos, na verdade queremos
emitir o que clicamos Então, vamos criar um
sinal de alerta aqui. Sempre que a caixa de acerto
reconhecer um acerto
, passaremos
pelo alvo que atingimos ou pela caixa ferida
que atingimos nesse caso Então, vamos dizer que Hurt box aqui é um tipo de rt box two D. Ok. Então, em vez de imprimir aqui, vou recortar isso, e eu
vou dizer aperte dot EMIT, e vamos passar
isso com a área P como uma Hurt Box dois D. Então, agora, se passarmos para
o script do projétil, podemos simplesmente nos conectar a
esse sinal Então, vamos fazer isso antes de
fazermos a parte de espera. Primeiro, diremos que assert
hit booxes dot empty. Então, não queremos
que isso seja verdade. Então, poderíamos dizer
igual, igual a falso e dizer que precisa de pelo menos uma caixa de acerto para
atingir um alvo Agora, isso
depende um
pouco de qual é sua intenção Teoricamente, você poderia ter um projétil que
não precisa ser atingido Portanto, essa afirmação pode não ser
necessária, mas para o nosso jogo, queremos que os projéteis sejam
capazes de
causar danos aos alvos inimigos Então, vamos deixar
essa afirmação lá. Então, depois de nossas afirmações, podemos dizer quatro
caixas e acertar caixas Vamos dizer box
dot hit dot Connect, e poderíamos dizer em hit box hit. Então, vamos
conectar esse sinal a uma nova função que estamos
escrevendo aqui na parte inferior. Então, a função no
Hit Box Hit vai usar uma caixa P Hurt
pode fazer a caixa de sublinhado HRT se quisermos ser
mais consistentes E isso vai
ser do tipo Hurt Box two D e return void Ok, então com a caixa HRT, vamos chamar,
digamos, P Hurt box Digamos que dobre o dano de DL e o valor será baseado em nossos cálculos aqui. Então, onde obtemos o
dano para calcular? Bem, vamos declarar o dano
final aqui. E vamos definir isso para
dez por enquanto. E isso será um número inteiro. Portanto, todos os danos e HP do jogo
serão baseados
em números inteiros Só para
simplificar, tecnicamente, você pode causar uma fração de uma unidade de dano, mas
isso é muito confuso A maioria dos jogos usa
apenas números inteiros. Ok, então diremos que lidamos
com o dano final aqui e nos preocuparemos com o cálculo do
dano posteriormente. Então, poderíamos dizer, para fazer o cálculo de
danos. Ok, agora, em nossa caixa Hurt, queremos adicionar esse método de causar
dano. Vamos até Hurt Box. Então, eu vou dizer que a função causa
dano, e vamos transmitir o
dano de um número inteiro Oh, poderíamos colocar um
tipo de devolução aqui agora Vou devolvê-lo
como nulo porque esperamos
que o dano causado seja o
dano que ele recebe estamos calculando
no script do projétil Neste caso, estamos calculando
no script do projétil
em vez do
script Hurt box Na verdade, vamos alterá-lo
para um tipo de retorno booleano. Então, eu vou dizer que tente causar
dano aqui. A razão para isso é que estabeleceremos a
condição de que seja possível que as estatísticas
sejam impossíveis de serem atingidas, então resolveremos isso aqui. Portanto, o ponto de falha final para saber se
ele realmente sofrerá o dano será a
invencibilidade nas estatísticas Então eu acho que isso faz mais sentido do ponto de vista da caixa. Então, diremos que, se não, um
ponto do controlador de estatísticas pode ser atingido, então retornaremos false Agora, as estatísticas são onde
estamos aplicando o dano. Ele gerenciará as
estatísticas de tempo de execução do personagem. Então, precisaremos
configurar tudo isso em um minuto. Então, agora provavelmente seria o momento
certo para configurar isso. Então, aqui no topo,
vamos querer usar o Export VR, uma referência de controlador de pilha Então, isso será do
tipo controlador de pilha. Então, criaremos um
novo script com. Vamos até a
cena organizacional em duas visualizações em D, clicaremos com o botão direito do mouse
nela e adicionaremos um nó secundário. Então, esse
será um nó normal. Não é um espaço de posição. Este é um gerenciador de estatísticas, então tudo é banco de dados. Portanto, é um
nó, não um nó TD. E vamos chamá-lo de
Stat Controller. Tudo bem, clique aqui.
Vamos anexar um script. Então, o nome dele será
apenas Sat Controller, e vamos colocá-lo na pasta do
personagem porque nosso
personagem principal também terá um controlador de pilha.
Vamos criar o script. Vou colocar o nome da classe e vou controlar o controlador
vPasteDN Stat porque copiei isso Isso gerencia as
estatísticas de tempo de execução de um objeto. Então, vamos
ter coisas como VaraHP, que é um número inteiro, e podemos definir isso para um valor
padrão Também temos o Var Max HP,
que pode ser o mesmo. A ideia é que o HP
nunca possa ser colocado acima do MX HP Então, se você quiser apenas
cuidar disso agora, colocaremos outra ferramenta aqui
no final, e eu direi valor definido. Portanto, o HP será igual aos homens
do valor
e do MaxHP Ok, então isso aqui
apenas o limita para que você possa definir o HP
acima do MaxHP Também podemos querer uma variável
para é o objeto vivo. Então, diremos que, ao vivo,
isso será um booleano. O padrão será verdadeiro. E então precisamos
dessa função na qual estávamos recebendo
um erro. Então, se eu marcar Hitbox, há a função can be hit Temos que implementar isso. Então, vamos ao Stat Controller. A função pode ser atingida, o que
retornará um booleano Assim, podemos colocar
as condições que quisermos aqui. Por enquanto, vamos
dizer que voltaremos ao vivo. Então, se o personagem estiver
vivo, ele pode ser atingido. Caso contrário, não poderá ser atingido. Então, aqui,
se estiver vivo, poderá ser atingido, mas isso é inverter
isso com o k. Então se não estiver vivo,
retornamos falso Basicamente. Agora, aqui embaixo, diremos return true porque presumimos
que, neste momento, ele causou danos porque
as condições foram atendidas. Já aprovamos a cláusula
da Guarda. Então, queremos pegar
o controlador SAP, pegar seu HP e
defini-lo com o novo valor. Talvez queiramos calcular
isso logo acima. E como uma variável local. Portanto, o novo HP será igual
ao ponto do controlador
estatístico: HP menos é ponto do controlador
estatístico: HP menos igual ao dano ou
apenas menos, na Portanto, a tarefa está, na verdade aqui à
esquerda do novo HP Então, configuramos o HP do
controlador de estatísticas para o novo HP e retornaremos verdadeiro Também podemos querer colocar aqui um sinal
que a caixa Rt emite, o que também
seria um sinal de sucesso Ok, então eu quero testar
tudo até agora. Vou definir um
ponto de interrupção aqui
à esquerda para que
possamos acertá-lo no Debug se a arma conseguir
danificar o personagem Então, vamos clicar em Play e ver
se funciona neste momento. Tenho certeza de que estou perdendo
algumas coisas. Então, podemos ver na parte inferior
aqui que o dano causado não existe porque,
na verdade, agora é dano triplo Então, mudamos o nome e
, em seguida, vamos executar isso novamente. Atingimos o ponto de interrupção?
Chegamos até aqui. controlador de pilha pode ser acionado, mas na verdade não
atribuímos o
controlador de pilha à caixa RT Portanto, esse pode ser outro
caso em que queremos afirmar no topo que
o controlador SAT
realmente foi configurado Portanto, o controlador assert stat
não é igual a null. O HRT Box precisa de uma
referência do controlador para efetivar. Portanto, a caixa HRT precisa de uma
referência ao controlador SAT para que possa alterar suas
estatísticas. Então, vamos ver. Se formos para o TD View, modo
local aqui em cima, e clicarmos na caixa RT, atribuiremos à direita
o controlador de pilha aqui Caso esqueçamos, a qualquer
momento, alguma caixa ferida, afirmamos que temos
um substituto para nos pegar Então, vamos executar isso mais uma vez. Vamos acertar isso e você pode ver que
voltamos à realidade. Você também pode ver
na parte inferior que o novo HP foi configurado para 90. Nosso HP básico para o controlador de
estatísticas é 100, então 100 menos dez, obtemos 90, então sabemos que está
realmente sendo atualizado corretamente E a próxima coisa que faremos
no início do próximo vídeo será configurar
a máquina de estado orc para
que possamos fazer a transição
de vivo para morto quando o HP cair para zero e depois remover o
orc da cena
17. Estado de morte quando o inimigo atinge 0 HP: Agora queremos criar uma
máquina estatal para nossos inimigos. Vai ser
incrivelmente simples. Haverá apenas dois
estados logo de cara, que serão o
estado de movimento ou o estado de morte, que o eliminará do jogo Então, vamos clicar com o botão direito do mouse em
Oc para adicionar um nó filho. Eu vou dizer HSM aqui, e nós vamos
pegar o Limbo Poderíamos renomear isso
para Enemy HSM, e então eu vou
clicar com o botão direito nele e anexar um script Então, isso vai direto para a pasta de inimigos
slash EnemysHSM Vamos criar isso.
Defina a parte superior aqui. HSM inimigo Essa é a máquina de estado dos
inimigos dentro do Okay,
então, olhando para o player HSM, vai ser
muito parecido aqui Acho que, como na verdade
mudamos para o Blackboard, esse script não precisa mais uma referência direta ao reprodutor de
animação, que seria correto se eu
examinasse aqui no plano do
Blackboard Não há necessidade
da segunda referência. Então, eu posso realmente
cortar isso aí mesmo. Então, vamos
copiar esse código do HSM do player para o script
do HSM inimigo Então, digamos que,
em vez de um jogador, esse
será um script de NPC, que pode ter suas
estatísticas definidas nele Então, um NPC do tipo NPC afirma
que o NPC não é nulo. Portanto, o agente NPC deve
estar configurado no HSM e nós o inicializaremos
com o script Então, estou meio que mudando
os nomes aqui, principalmente. Então, o script do NPC, vamos até a cena dos
orcs no D View. E vamos
querer clicar
em OC, anexar um script. Diremos que isso é NPC
e o colocaremos em personagens, não em Character Slash Enemy, ou pode ser em
inimigos que dependem de você Criaremos esse script
para o corpo do personagem. E vamos chamar isso de
ClassName NPC. Portanto, o NPC
terá apenas uma referência fácil ao controlador
da pilha Para que não
precisemos necessariamente
referenciar essas duas
coisas separadamente. Dentro da máquina de estado, é muito conveniente
acessar as propriedades do
agente porque você sempre sabe que o agente estará presente em qualquer
script de máquina de estado depois inicializá-lo
na máquina de estado Então, se exportarmos as estatísticas do
VAR aqui
e, em seguida, dizermos controlador de
pilha, poderemos referenciar isso muito fácil dentro da máquina de
estado Então, aqui à direita,
atribuímos o controlador de pilha
e, agora, dentro do HSM inimigo, os erros devem
desaparecer desde que
clicemos no HSM inimigo.
Bem, isso não está certo. Deveria dizer NPC. Então, só precisamos reiniciar
o projeto Cadle,
ir para Projeto, recarregar o projeto Ok, e isso
deve resolver isso. Agora atribuímos o
orc, que é o NPC, e temos uma referência
ao agente e às estatísticas,
e isso deve ser a maior parte do que
precisamos para nossa máquina de estado Ok, então vamos
clicar com o botão direito do mouse no HSM inimigo. Vou adicionar um nó secundário. E vamos fazer um estado de limbo. Eu poderia renomear isso e dizer algo como NPC move state Bem, clique com o botão direito do mouse em anexar
um script. Criar. Ok, então, a seguir, vamos criar
um estado de perseguição para o inimigo. É aqui que estará
a lógica central para nosso personagem se mover em direção
ao jogador, além de reproduzir
a animação de execução assim que a
colocarmos no estado. Então, vou clicar com o botão direito do mouse
no HSM inimigo. Vamos adicionar um
nó secundário, um estado do Limbo. Vou renomeá-lo para Chase State. E eu vou clicar com o botão direito
aqui, anexar um script. Então Chase afirma que provavelmente
pertence a um inimigo. Vou clicar em Criar. OK. Vamos dar a ela um nome de
classe no topo, Chase State, e vamos
fazer um comentário. Então, isso vai
acabar correndo em direção ao jogador onde quer
que esteja no jogo. Por enquanto,
vamos fazer que ele reproduza a animação. Vamos configurar uma transição
do estado Chase para
o estado de morte e garantir
que nosso personagem,
caindo para zero HP dê vida ao inimigo
dentro do jogo Então, vamos dizer
sublinhado da função, Enter. Quando entramos, queremos
reproduzir a animação de execução. Então, podemos até mesmo fazer a configuração do
sublinhado da função
e, em seguida,
obteremos aquele reprodutor de animação Até agora, sublinhe
o player de animação do tipo player de animação, e vamos
obtê-lo do Blackboard, assim como fizemos
com o Portanto, o player de animação é igual a
Blackboard dot get var. E estamos procurando o reprodutor de
animação de citações finais e queremos reclamar
se não o encontrarmos Então, temos o player de animação. Quando entramos no estado,
reproduzimos a animação. Então, vamos dizer underscore animation player dot play, e queremos
reproduzir a animação definimos aqui na parte superior Vamos fazer em Export var. Digamos que a animação do Chase. Claro. E esse
será um nome de string. Vou defini-lo como padrão para ser executado. E depois copiamos
isso para aqui. Então, reproduzimos a animação certa
quando entramos no estado. Ok, e nosso HSM inimigo, nós já o inicializamos Nós já o ativamos. Então provavelmente vai funcionar. Então, podemos ver se funciona agora. Vamos entrar no modo de jogo. Oh, nós não colocamos o
player de animação no
Blackboard, é claro Então, isso nos diz imediatamente
que houve um problema. Isso é bom. Clique em Enemy HSM, vá até o plano Blackboard e vamos fazer o Novo Plano
Blackboard, gerenciá-lo e adicionar um player de animação variável Escolha o tipo de caminho do
nó. Clique em OK. E agora, queremos atribuir um
player animação
ao player de animação do or e agora podemos usá-lo
dentro de nossos estados. Ok, clique em Play novamente. E vamos ver se nossos orcs
estão correndo. Todos eles são. Isso é ótimo. Então,
precisamos do nosso estado de morte e precisamos
configurar nossa transição. Então, vou
clicar com o botão direito do mouse em Enemy HSM adicionar um nó secundário, que
será Limbo State Renomeie isso para Death State. Clique com o botão direito, anexe um
script e clique em Criar. Vamos chamá-lo de
Estado da Morte no topo. Então, nome da classe Death State. Ok, agora em nosso estado de morte, também
precisamos reproduzir
uma animação muito semelhante à que fizemos
no estado Chase. Esse é um código que vamos
repetir aqui, mas como estamos fazendo apenas
alguns estados para o nosso jogo, acho que fazer
coisas como criar uma nova classe base é um
pouco extra
no momento. Então, eu vou
copiar isso. Para o estado da morte.
Bem, cole isso. E eu poderia simplesmente
dizer que a animação aqui que queremos
para o estado de morte é padronizada para morte, e fazemos com que a animação seja
reproduzida da mesma maneira Mas então queremos reproduzir
a animação aqui. E como não estamos
usando um estado base, não
precisamos nos
preocupar com coisas como chamar Super para garantir que o
código do estado da animação realmente seja
executado, porque ambos usarão setup e Enter. Se você declarar uma nova
configuração ou função Enter, ela realmente substituirá
o que está na classe base se você esquecer de chamar
Super e, a propósito, você chamaria Super Super significa apenas que,
seja qual for a turma principal, você a executa
neste momento. Então você pode ver que é um
pouco complicado e confuso usar esse tipo
de herança direta Se você tem cinco ou
dez estados diferentes,
todos em que são estados de animação porque todos são reproduzidos
na animação exatamente da mesma maneira
, vale
a pena ter isso. Mas nós literalmente
só teremos
Chase e a morte,
então é um exagero Mas Tay deve mencionar
que essa também é outra maneira de
fazer as coisas Então, no Inter,
basicamente queremos
tornar nosso personagem invencível Então, talvez queiramos fazer algo como agent dot stats dot LI, e queremos ter certeza de
que isso seja definido como falso. Portanto, lembre-se de que quando um
controlador de estatísticas não está ativo, então can be hit
retornará false. Portanto, isso
nos impedirá de
atingir acidentalmente um personagem que
está em estado de morte Eles também fazem algo como,
digamos, função concluída, e declaramos essa função
para que você possa chamá-la da animação
ou de outros lugares E vamos dizer que
o agente precisa de você de graça. Então, agente Qu está livre. Então, isso basicamente significa
a rota Aosne the org. Vamos libertá-lo e
tudo o que está dentro dele. Quando chamamos o método
finalizado. Então, agora podemos ir para dois reprodutores de animação de visualização em
D aqui na parte inferior. Vamos ver a animação
da morte. Ampliamos a linha do tempo,
vamos até o final aqui. Vamos adicionar Track, call method track
no estado de morte. Em seguida, clicaremos com o botão
direito do mouse aqui embaixo, inseriremos uma chave e procuraremos o
método finalizado que acabamos de criar. Então, isso significa que, quando nossa animação de
morte estiver concluída, ela chamará de
finalizado ; o
estado de morte liberará
o agente assim que a o agente assim que renderização
do quadro terminar
e todo o resto for resolvido Então,
normalmente você liga para um trimestre, não gratuito, para
congelar gratuitamente imediatamente, e um trimestre espera outras operações
sejam resolvidas adequadamente Então, isso realmente
reduziria a quantidade de insetos
estranhos que você pode
pegar ao comer Ok, então a última
coisa que precisamos fazer é entrar no HSM inimigo Vamos criar uma nova função
para transições de configuração, que retornará nula Então, queremos adicionar
uma transição do
nosso estado de perseguição para o estado morte quando o evento de
morte é emitido Então, quando você declara um
evento aqui como este, esta é apenas uma string à qual nosso
sistema responderá poderíamos
ir até aqui e
criar um evento de morte constante Será um nome de
string igual ao de “
morte” em minúsculas,
colaremos isso
lá embaixo e poderemos nos conectar às estatísticas do
nosso agente dessa forma Digamos que as estatísticas de pontos do NPC
dot Alive mudaram. Não criamos esse sinal, mas vou
pular aqui, então conecte-se. O sublinhado em NPC Alive mudou. Ok, então eu vou
copiar isso para
a parte inferior da função paste
on NPC live changed, e isso vai
ter o novo valor Então, vivo é um booleano. Poderíamos dizer P como parâmetro,
se quisermos aqui. Eu geralmente gosto de
fazer isso. E isso vai devolver
um tipo de vazio Então, quando o NPC
não estiver mais vivo, eu quero emitir
o evento da morte Então, se P vivo é igual a falso, então vamos
despachar o evento da morte OK. E quando
adicionamos a transição, isso significa que
essa transição acontecerá quando
esse evento de morte ocorrer. Agora, ele ainda está nos dando uma mensagem de
erro porque não
temos o estado de Chase ou a referência do
estado de morte aqui no topo. Então, podemos apenas dizer em
export var Chase state, que é um estado limbo, e em export var death state, que é um estado limbo Agora salve
o script no inspetor. Podemos atribuir o estado de Chase
e atribuir o estado de morte. E agora, depois de chamarmos as transições de
configuração, ele cuidará do
gerenciamento dessas transições Acho que queremos chamar
isso antes de inicializar, ou talvez logo depois Vamos fazer isso logo depois. Então,
sublinhe as transições de configuração Nós chamamos isso.
Configuramos nossas transições. Não deveria haver a necessidade de criar um estado de morte para perseguir porque não temos inimigos voltando
à vida atualmente, mas você poderá
adicionar esse tipo de coisa mais tarde. Certamente, esse
seria um tema comum, especialmente para inimigos
mortos-vivos Ok, então a última coisa para
fazer isso funcionar muito rápido ir até a cena da lança e vamos pular na caixa de sucesso, ou é a lança?
Certo, a lança. E queremos reduzir o
dano final e defini-lo em 100, então será um golpe
igual a um orc Clique em play e vamos ver se tudo
isso se encaixa. Então, isso está nos dando um erro.
Eu não criei um evento
alterado ao vivo nas estatísticas do NPC Clique com o botão direito no
símbolo do NPC, vá para o símbolo Lou. Clique com o botão direito no
símbolo, símbolo Lou, clique com o botão
direito em Stat
Controller, símbolo Lou Ok, e aqui estão nossas estatísticas.
Vamos criar o sinal, para que possamos dizer que o
sinal ao vivo mudou. E isso passará
o novo valor real como um booleano Voltaremos aqui e atribuiremos mais sinais, mas, por enquanto, quero ter certeza de
que esse sinal seja
emitido sempre que um valor
real mudar Então, eu vou dizer valor definido. Então, primeiro, vamos
evitar se
o valor for igual
ao valor que está sendo definido para ele. Portanto, se uma vida for igual, dois sinais iguais ao
valor simplesmente retornarão. Caso contrário, uma vida ativa é igual ao valor. E, finalmente, um ponto
alterado ao vivo é emitido
com o novo valor Então, onde queremos calcular
o Alive? Bem, um bom lugar para fazer isso
seria neste configurador HP. Então, sempre que o HP muda, queremos verificar se o
personagem ainda está vivo. Então, isso
vai ser ao vivo, é igual a HP é
maior que zero. Ok, então isso está resolvido. Agora temos o evento alterado ao vivo. Tudo isso deve ser acionado quando
o personagem atingir zero HP. Vamos parar o jogo
e executá-lo novamente e ver se o
atingimos com uma arma.
Assim, o
personagem se remove sozinho? Vai para o estado de morte? E podemos ver que
a resposta é sim. Então, leva 100 de dano. A HP chega a zero. Uma live
é definida como falsa. O sinal é emitido. E então isso significa que,
na máquina estadual inimiga,
a transição é acionada
porque esse sinal é atingido Esse patch no HSM inimigo
emite o evento interno. Portanto, esses eventos da máquina de estado
são separados dos sinais. Eles são apenas para
a máquina de estado nos sinais de IA do
Limbo no contexto
maior de Gadot Então, temos esse evento
interno de morte, e isso nos faz ir do estado de
Chase para o estado de morte. Dentro do estado de morte, reproduzimos a animação morte em Enter, mas garantimos que isso seja definido
como falso aqui. Em teoria, você não
precisaria fazer isso, mas acho que
não vai doer nada garantir que, se estivermos interpretando o estado da morte, que o personagem não
esteja mais vivo, acho que está tudo bem. E então temos o método
finalizado, que na verdade estamos apenas
chamando da animação. Como você viu antes, a animação de
morte
aqui embaixo aparece logo
no final de nossa animação, e é assim que
fazemos nossos inimigos entrarem ao vivo
assim que caem para zero de HP. Então, eu sei que há muitas
peças se juntando. Eu
recomendaria que, nesta parte, se você ainda não baixou os
instantâneos individuais das partes , pegue aquele para
este vídeo se estiver, você sabe, com problemas e
veja onde talvez seu
script esteja um pouco errado Então, o que estamos fazendo aqui com sinais é o padrão do
observador É muito útil quando
você quer que uma parte do código responda a uma alteração em outra
parte do seu código. E algo como C Sharp, isso seria chamado de eventos
e, em seguida, tratamento de eventos. Mas em Gadot isso é
chamado de sinais. Essencialmente, eles são
o mesmo conceito, no entanto. Portanto, é o padrão do
observador Se você quiser pesquisar
isso e ler mais sobre isso. Então isso vai
ser um embrulho para isso
18. Rotação e direcionamento dos projéteis com carga de arma: Ok, então neste vídeo, vamos fazer
com que nossa lança gire para a direção
certa após a instanciação e que também
possamos
lançar a lança na direção
correta Então, a forma como
precisaremos configurar isso está dentro do nosso script D da arma
2 aqui. Então, em nosso jogo de sobrevivência, provavelmente
queremos fazer
com que um personagem possa ter várias armas
ao mesmo tempo Portanto, na verdade,
faz sentido ter algum tipo de gerente para
todas essas armas. Assim, podemos criar um script de carregamento de
armas que seja aparente para
essa arma dois D, e podemos usar isso como um exemplo de forma de
resolver coisas como
a importação de nossas
armas pelo jogador Então, vamos clicar com o botão direito
do mouse no nó do jogador e
adicionar um novo nó filho. Vou chamar esse nó dois de D, e então vamos
renomeá-lo para carregamento de armas Vamos transformar
imediatamente a arma dois D no carregamento da arma aqui,
e eu deveria renomear a arma
dois D para ficar como uma arma lança, deixando claro
o que ela realmente E então vamos clicar em Weapons
Loadout e adicionar um script. Então, esse será o
carregamento de armas que pode ser usado no jogador,
criado e, no topo,
faremos o carregamento de
armas com o nome da classe Então, esse
será um script de gerenciamento para todas as armas que
um jogador equipou. Então, aqui podemos pegar uma referência rápida à entrada
do player. Ok, e agora podemos acessar
o roteiro de armas de lança
e insistiremos que, e insistiremos sempre
que
tivermos uma arma de lança, dependemos de
que a mãe seja
uma carga de armas que será consistente em todo o jogo Então eu acho que
a configuração está boa. Então, vou fazer var
underscore loadout aqui dentro do script D de nossas
armas. E isso será do
tipo carregamento de armas. Então, quando estiver pronto, vamos
querer obter esse carregamento. Então, digamos que underscore loadout
é igual a get parent, e devemos afirmar que
o loadout não O pai de uma arma deve
ser o carregamento da arma. Ok, e parece que eu
poderia ter definido o nome da classe. São armas com S? Sim. Ok, então isso é o carregamento de
armas aqui,
não o carregamento de armas Ok, então temos uma referência
ao script de carregamento principal. Isso cria uma dependência, mas também facilita o
acesso às coisas de que precisamos Então, caso alguma vez
tenhamos decidido que queríamos mudar
esse padrão, criarei uma função
aqui embaixo para Get direction. Então, a função Get direction retornará um vetor dois. E nesse caso, vamos usar o loadout para conseguir Portanto, retorne a entrada de pontos de carregamento de sublinhado.
Direção do ponto. E é assim que
resolvemos a direção, mas sempre podemos usar a função
de direção G para lidar com isso. Então, se ligarmos, digamos, obtemos a direção em dez lugares
diferentes, mas mudamos o carregamento Então, na verdade, não
usamos
mais um carregamento ou talvez o carregamento
não use uma entrada, então só precisamos entrar
aqui uma vez e mudar Então, talvez o carregamento tenha uma referência
direta à direção, então simplesmente mudamos assim e ele funcionaria novamente Mas, na verdade, preciso
mudar isso um
pouco porque não vamos
usar a direção. Vamos usar a
direção voltada porque, lembre-se, direção é a entrada bruta. Pode ser um ponto vetorial zero, mas nunca lançaremos
uma lança nos
pés do personagem nesse estilo de jogo Então, na verdade, queremos
ficar voltado para aqui, e vamos levar isso
para Importar com frente para pontos. Então, vamos realmente
resolver a direção para a
qual o personagem está
voltado e, em vez disso. Ok, então vamos pegar isso Get
facing e, onde
lançamos, vamos apenas lançar para ficar de frente para
ficar de frente para frente. E se movermos nosso
personagem, você já
verá que podemos lançar na direção
certa, e isso também deve incluir
diagonais, assim Ok, então isso é metade do que
precisamos fazer ali mesmo. Agora, também precisamos girar
todos os projéteis que instalarmos. Então, vamos obter esse ângulo
de rotação. Então, dentro do elenco, abaixo de onde criamos a cena do pacto
para o projétil, vamos fazer o ângulo de rotação VR E vamos pegar
o vetor voltado para ficar. Vamos converter
isso em um ângulo aqui, e acho que está em brilho. Se eu clicar com o botão direito do mouse
e fizer o símbolo Lou, podemos ver o retorno
do ângulo vetorial em relação
ao eixo X positivo em radianos Então, isso seria algo como Pi dividido por dois tipos de coisa. Ok, mas queremos
girá-lo para que a lança ou outros projéteis estejam voltados para a direita, por padrão,
como nosso Então, se o sprite estiver voltado para
cima, queremos girar
esse Pi dividido por dois ou cerca de 90 graus
assim , então vamos adicionar Hi, que é uma constante
dividida por dois, e isso fará com que fique voltado para a direita por padrão Sem
dar conta, é realmente mais uma questão de tentativa e
erro Mas vamos fazer essa rotação. Então, depois de
instanciarmos o projétil e
dizermos que é a posição global, vamos fazer a rotação do ponto do projétil
e essa função leva radianos e essa função Então, temos nosso ângulo de rotação. Realmente, eu deveria renomear
isso para ser anúncios rotativos. Então, vou
coletar duas vezes esse Control R, e vamos dizer que gire
os anúncios para ver a luminosidade, substitua tudo, e aí
fica muito mais limpo Então salve e corra, e aí temos nossas lanças apontando na direção certa E isso também deve funcionar essencialmente
com qualquer projétil Desde que esses projéteis estejam
voltados para cima por
padrão, caso contrário, você pode girar esse
sprite individualmente na cena dos projéteis até que
estejam voltados para
a estejam Então, aí temos nossa mira
e rotações para
os projéteis e rotações para E para mostrar mais uma coisa,
se eu soltar a direção
, nossa direção agora
é o vetor 20, mas ainda estamos atirando
para a direita porque a
face nunca será definida como vetor dois pontos zero. E é por isso que usamos face em vez da entrada de
direção bruta. Ok, esse é um grande
passo feito ali mesmo.
19. Adicionando efeitos sonoros e música: Vamos adicionar alguns
efeitos sonoros ao nosso jogo. Primeiro, vou começar
fazendo um efeito sonoro de lançamento
e, então, talvez, quando os inimigos
atingirem seu estado de morte, tenhamos a opção
de fazê-los tocar um efeito sonoro
lá também. Eu provavelmente ficaria longe dos sons de sucesso porque
vários inimigos serão
atingidos
a cada segundo, e isso
acabaria sendo,
eu acho, muitos efeitos
sonoros ao mesmo tempo. Você não gostaria de sobrecarregar demais
seu jogador. Então, vamos começar
com esses dois. Então, para a arma de lança do jogador, digamos que na arma em D, adicionaremos um reprodutor de som Então, em Export var audio
player of type ou audio stream player two D.
Queremos que sejam dois D porque esses projéteis existem dentro do mundo do jogo TD, então faz sentido
afetar o áudio com
base no posicionamento espacial da câmera e do
projétil e tudo Então, pegaremos o reprodutor de áudio e teremos que
colocá-lo aqui embaixo. Então, para adicionar o nó do reprodutor de áudio, vamos ampliar aqui e clicar com o botão
direito do mouse na
arma Spear, adicionar o nó filho Então, queremos que o
stream player two D, adicione isso lá embaixo. E queremos atribuir um stream de áudio que possamos reproduzir aqui. Então, vamos descobrir os efeitos sonoros. Vou fechar todas as pastas. Vamos entrar no áudio. Vamos ver. O que eu estava usando?
Acho que tivemos, tipo, efeitos sonoros de Ball Ok, deixe-me colocar meu fone de aqui para que não chegue
pelo microfone Ok, então dentro de a, acho
que estava com a barra 04, então poderíamos
clicar duas vezes nela, ir para o canto superior direito e visualizar Sim, acho que era isso que eu
estava usando no meu projeto de demonstração. Então, vamos pegar a barra e colocá-la
no stream aqui Agora podemos simplesmente dizer a
esse reprodutor de streaming de áudio para tocar sempre que
lançarmos um projétil Então, vamos entrar em stream weapon. E quando tivermos o
projétil lançado, diremos que, se o reprodutor de
áudio não for nulo,
solicitaremos que ele reproduza o clipe
de áudio atual Então, aqui embaixo, depois instanciarmos o
projétil,
diremos que o reprodutor de áudio toca, e isso é basicamente
tudo o que precisamos fazer A razão pela qual temos essa condição aqui é
que, para algumas armas, você pode não querer
que ela reproduza nenhum áudio, então vamos pular
essa opção aqui Agora, uma coisa que quero
ressaltar aqui é
que estamos dando responsabilidades
extras
a esse roteiro de armas. Portanto, agora a arma dois D não é apenas responsável por
instanciar os projéteis, mas também por mandar
o reprodutor de áudio tocar quando o
projétil for instanciado contratando sua própria referência ao carregamento
das armas e
criando um Então, algumas coisas
estão acontecendo agora, não
acho que
isso seja avassalador e um problema para o jogo, mas é algo que
você deve conhecer Se você perceber que seus scripts estão assumindo muita
responsabilidade, considere dividi-los em vários nós
com scripts diferentes
e fazer com em vários nós
com scripts diferentes
e fazer com que funcionem juntos como peças
individuais, em
vez de um megascript gigante. Mas
ainda não chegamos lá. O roteiro tem apenas 50 linhas. Na verdade, não é um problema. Se você tivesse talvez duas
ou 300 linhas de código
, provavelmente
chegaria ao
ponto em que precisaria de alguns
subobjetos, eu acho Mas não se
preocupe muito com isso. A maioria dos scripts deste
curso é bem simples. Eu só quero que vocês saibam
que, daqui para frente, um roteiro pode
se tornar muito monolítico, e isso pode ser problemático
a Temos uma
arma de lança. Precisamos atribuir o reprodutor de áudio para
que ele realmente reproduza áudio. Então, atribua e, em seguida, reprodutor
de fluxo de áudio. Agora, se tocarmos, devemos
obter nossos efeitos sonoros. Ok, sim, lá
vamos nós. Toda vez que lançamos um projétil Ok, agora queremos
reproduzir um efeito sonoro quando nossos orcs morrem. Então, vamos entrar na cena dos orcs. Tudo bem, clique no orc, adicione um novo
player AudioStream Se quisermos, eu poderia
renomear isso para ser um reprodutor de áudio de morte Poderíamos dizer. Ok, então
agora gostaríamos de encontrar um efeito sonoro de
morte adequado. Brincando um pouco com
isso, acho que o inimigo
Death 01 é demais. Até mesmo flash oh two também é um
pouco demais. O fato é que
haverá inimigos caindo como moscas
nesse tipo de jogo Então, precisamos de algo muito sutil ou talvez até mesmo nenhum. Acho que estou
procurando algo mais parecido com o Step grass 03. Agora, isso pode parecer
um pouco estranho, mas acho
que qualquer coisa que seja
mais longa do que isso vai ser
demais para ver no que vai dar, pode até mesmo remover isso completamente Então, vamos atribuir o Step grass oh three ao stream aqui
e, para pedir que ele reproduza esse efeito
sonoro na morte, vamos até o reprodutor de
animação. No canto inferior esquerdo, selecionaremos a animação da
morte. E adicionaremos uma nova
faixa, adicionaremos uma faixa aqui, chamaremos o método no reprodutor de áudio
Death, clicaremos com o botão direito do mouse no
início da animação, inseriremos a tecla e queremos jogar. Então, é como se estivéssemos
escrevendo um script ao definir esses quadros-chave de
animação, exceto que temos a linha do tempo, então podemos dizer exatamente quando queremos que ela
reproduza essa animação, e é muito fácil
movê-la para um momento
diferente apenas
arrastando-a para um Assim, você poderia criar um script de tudo isso escrevendo o código de script GD
se quisesse e simplesmente
pular o player de animação Mas, obviamente, o
reprodutor de animação meio que
torna muito mais fácil
fazer isso visualmente. Ok, então agora, se
tocarmos, devemos tocar os dois efeitos
sonoros. Então você pode ouvir
quando os orcs mergulham, eles tocam aquele
pequeno efeito sonoro Está um pouco quieto,
mas talvez esteja tudo bem. Se acharmos que as lanças estão
muito altas em comparação, podemos até pegar o reprodutor de streaming de
áudio da lança e diminuir um pouco o
decibel do volume aqui E aperte play e
execute mais uma vez. Você pode até mesmo editar isso
enquanto o jogo está rodando. Então, poderíamos simplesmente deixar
isso lá embaixo. Ok. Você pode ver que
já está muito mais silencioso. Mar, uma das
coisas boas do cado é que você não precisa necessariamente fechar o jogo para mudar
suas propriedades. E vamos atacar um inimigo. Ok. E a diferença de volume entre eles é um
pouco menos pronunciada. Então, provavelmente está bom agora. Como um pequeno
bônus para este vídeo, se você quiser adicionar música,
vamos ao mundo
e vamos adicionar um reprodutor de fluxo de
áudio, um reprodutor fluxo de
áudio de dois
D, apenas a nota padrão Então, transmita o player aqui e escolha este, o
Audiostream player Ok, então com nosso reprodutor
AudioStream, vá para a direita
e vamos querer que isso seja reproduzido automaticamente E acho que para fazer um loop, primeiro
precisamos carregá-lo
dos três MP de áudio. Então, vamos fechar tudo
no canto inferior esquerdo novamente, ir para Áudio e temos a música de box jump do pacote
The Red Hearts. Então, vamos trazer isso
para o canto superior direito. Na verdade, não é P três. É um OGG de pontos, mas os dois formatos de música
são suportados no KDO, então funcionará bem E então queremos pegar
isso e marcar Loop on. Mas talvez precisemos
fazer isso no canto inferior esquerdo. Então, clique duas vezes no OGG aqui. Ok, e então
verifique o loop aqui. E quando chegar ao fim, deve repetir a
coisa toda. Ok, então isso é bom. Ok, então a última coisa
antes de jogarmos o jogo, vou pegar o volume DB e colocá-lo em menos 20 ,
porque acho que
provavelmente vai
ficar bem alto, caso contrário. Então, vamos clicar em Play
e ver no que vai dar. Ok. Assim, podemos ouvir a música, e
ela ainda está bem alta. Então, vou levar
isso para menos 30. Talvez até menos 40. Sim, isso provavelmente é um
pouco mais apropriado. Então, agora temos o áudio. Temos a música e temos um efeito sonoro de Enemy
Death. Então, esse é
o básico para efeitos sonoros de
áudio e
música dentro do jogo, e podemos
continuar a partir daí
20. Sistema de combate Singleton: Ok, então o tipo básico de dano
e combate por
projéteis funciona no momento, mas não
sabemos realmente quanto dano está sendo causado aos inimigos
no contexto do jogo Então, uma maneira de fazer isso
que também
melhoraria visualmente a jogabilidade
seria o texto de combate flutuante. Então, sempre que um
desses personagens sofre dano na caixa de ferimentos, podemos nos comunicar, digamos,
com
um sistema de combate, por exemplo, flutuando um texto de combate
na posição em que sofreram dano toda vez que sofrem dano. Então, isso significa que
haverá muitos números flutuando
pela tela, mas acho que isso funciona muito
bem para o estilo de jogo. É muito baseado em ação e queremos feedback
imediato sempre que estivermos
causando dano a inimigos E também queremos
ver os benefícios
de aumentar o nível de nossas habilidades, assim
como nosso personagem
ficar mais forte Para criar nosso sistema,
vamos querer
fazer isso como um objeto
Singleton, que
significa que
há uma referência a essa classe ou sistema
em todo o jogo E se o definirmos como carregamento automático, ele sempre estará lá
em segundo plano e
poderá ser facilmente referenciado pelo nome Você também pode implementar padrão
Singleton
no próprio script, mas faremos isso do jeito Gada, que é um pouco mais simples
e fácil Então, aqui no topo,
vou criar uma nova cena. Vamos criá-lo como outro nó, e esse será um nó base. Se vocês são dois aqui, você pode renomeá-lo para sistema
de combate Em seguida, clique com o botão direito do mouse, anexe um script, sistema de combate. Podemos salvar isso
na raiz ou criar uma pasta de sistemas
para salvá-la, que provavelmente
seria minha preferência, e eu a criarei lá. Agora, queremos salvar esse sistema de combate
na pasta de sistemas. Então, o sistema de combate
dot TSC, salve isso. E agora vamos fazer
um carregamento automático para que esse script de nó possa ser referenciado em nosso jogo
apenas usando o nome Então, vou para as configurações
do projeto. Então temos Globals aqui. E queremos adicionar um
novo TSCN como global. Então clique aqui, vá para
Sistemas e depois faça TSCN. Você também pode ver
que pode selecionar um script GD de pontos como
sistema de combate, e o que isso faria seria
criar uma nova instância
do script de nó em seu jogo assim que
o jogo fosse lançado Mas se você usar o ponto TSCN, terá a vantagem de poder usar variáveis de
exportação porque essa é uma
cópia muito específica do sistema de combate Se eu clicar duas vezes aqui e adicionar isso como nome
do nó do sistema de combate
, agora temos esse sistema de
combate como um Singleton global
e um lado do nosso jogo E a diferença
entre carregar automaticamente um script GD de pontos e carregar
automaticamente o SEN diretamente é que, se
fizermos algo como Exportar var spawn count, número inteiro igual a dez
, podemos definir isso aqui Mas se você
instanciar um script que ainda não tenha sido definido como
uma cena ou um nó
, você
não teria a capacidade de realmente personalizar propriedades
como essa com antecedência. Agora, tenho certeza de que existem
maneiras de contornar isso, mas essa é uma vantagem
de usar o dot TSE Ok, então temos
nosso sistema de combate. Vamos querer algum tipo
de função de relatório de danos. Então, vou meio
que redigir isso. Aqui. Digamos que função. Digamos que o relatório tenha sido atingido. Eu
acho que isso faz sentido. Digamos que temos um
alvo que foi atingido e podemos dizer que
dois D não poderiam ser qualquer coisa no jogo
que pudesse ser atingida. Geralmente, isso
seria como um
corpo de personagem ou um corpo estático. Mas usaremos apenas a
classe base para maior flexibilidade. E então temos aqui
a quantidade de dano. Portanto, o dano P é um número inteiro. Isso retornará vazio. E então, neste sistema de combate, criaremos nossa cena
para o texto de combate flutuante. Então, vamos até
o topo e podemos dizer em Export var, cena de texto de
combate flutuante. E essa será uma cena repleta de
tipos. E aqui no Report Hit ,
por enquanto,
vamos dar uma olhada. Ou, se quiser, você pode até mesmo cometer um erro push e dizer
não implementado. Isso lhe daria um
pouco mais de feedback se você
se esquecesse de implementar um script, em vez de
apenas executar a função e passar para que não houvesse nenhum erro, mas também não
fizesse nada. Então eu acho que isso é
um pouco melhor durante o desenvolvimento, na verdade. Agora vamos passar para o
nosso script HRT Box two D. Então, Control P, HRT Box two
D. E aqui dentro, podemos referenciar
o sistema de combate Ok, então o relatório de
pontos do sistema de combate chegou, e queremos o objeto que o
controlador estatístico está gerenciando Então, eu não acho que
o controlador de estatísticas realmente tenha uma
referência a isso ainda Se dermos uma olhada rápida na cena dos
orcs, vamos clicar no
Stat Podemos ver que
não há nada aqui
no lado direito para obter
uma referência ao Oc. Poderíamos simplesmente fazer isso como um tipo de
referência get parent ou podemos
torná-lo uma variável de exportação. Se você quiser ter certeza de que a conexão é mais absoluta
, eu escolheria at export. Porque isso significaria
que se, por algum motivo, você movesse o controlador de estatísticas um nível
abaixo, como se fosse pai
para outra coisa
, Get parent não retornaria
mais o orc Então, se usarmos at export, podemos garantir que ele
retorne o c. Poderíamos dizer algo como
corpo ou personagem, talvez até objeto,
mantendo-o mais genérico. E então esse pode ser
apenas o objeto para o qual
esse controlador está
gerenciando estatísticas, e eu vou atribuí-lo no
canto superior direito ao orc aqui Agora, se voltarmos
para a caixa Hurt, podemos usar o objeto ponto do
controlador de estatísticas aqui, e então podemos transmitir
o dano P de dano Ok, então isso dará
ao sistema de combate tudo o que precisamos saber sobre onde posicionar o texto e quanto dano
atribuir ao texto.
21. Animando texto de combate flutuante: Agora precisamos do texto de
combate flutuante em si. Então, vamos criar uma
nova cena aqui. Clique em mais e faça a interface
do usuário. E vamos
fazer com que o nó base seja
como um texto de
combate flutuante. Mas o texto real será
atribuído como rótulo secundário. E isso nos ajudará quando estivermos usando o reprodutor de animação para animar, porque
não queremos mudar a posição
da raiz Queremos apenas alterar a posição
do texto em relação à raiz do controle de texto
flutuante do Combat. Então, clique com o botão direito aqui, adicione um nó
filho, procure o rótulo. E então vamos clicar com o botão direito do mouse no animação
Adhild de texto
flutuante de combate Ok, acho
que é disso que precisamos aqui, então vamos controlar S. E podemos salvar isso. Talvez
criemos uma pasta para a interface do usuário. Esse é o tipo de interface do usuário ainda. Então, vamos criar uma nova pasta. Vou digitar na interface do usuário. OK. E então, o texto de combate flutuante pontua TSC e pode ir
direto para lá Então, fique seguro. OK. E agora precisamos de um script anexado
à nossa raiz aqui. Vou clicar com o botão direito do mouse no texto
flutuante de combate, anexar um script e
criá-lo na pasta da interface do usuário, ponto de texto de combate
flutuante gD. Vamos querer
uma referência
ao rótulo para que possamos
manipulá-lo aqui Portanto, controle var label label. Então, vamos atribuir o rótulo aqui. E queremos criar algum
tipo de função inicializada. Se você já usou o Gado,
provavelmente sabe que
há uma função de sublinhado
e malha Essa função é usada quando um nó está sendo
criado na cena. Mas, nesse caso,
precisamos esperar até que o objeto já tenha
sido criado. É por isso que precisamos criar. Então, se você já usa o
Gadot há algum tempo, talvez
saiba que há uma função de sublinhado
e
uma função de TI Portanto, essa é uma
função substituível em que ela pode executar o código antes que
todas as propriedades tenham sido definidas para seu sistema Você pode usá-lo para passar parâmetros
opcionais para definir
essas propriedades ao criar um nó a
partir de uma chamada de função em vez de existir dentro de uma cena compactada,
como aqui, que é o que você costuma fazer. Basta
configurar a cena e, em
seguida, instanciar a cena a
partir de uma cena ritmada Então, na verdade, não
é isso que queremos fazer. Não estamos tentando personalizar
a função inicializada. Estamos tentando fazer com que o texto de combate
flutuante seja
executado quando
já estiver em cena. Então, eu só queria fazer
essa distinção lá. Ok, então o que queremos fazer
no script de texto de combate flutuante é ter a opção de definir
o texto no rótulo, e faremos
isso diretamente com uma espécie de função
delegada
aqui com texto de conjunto de funções Então, colocaremos o
texto no rótulo,
mas o faremos operando
por meio do texto de combate
flutuante do nó raiz. Então, defina o texto e
diremos o texto P, que é uma string,
retornaremos void e pegaremos o texto com pontos do
rótulo e definiremos como igual ao texto P. Então, uma razão para fazer isso é
que nosso OK, então, é claro, vamos
querer definir isso sempre que instanciarmos a cena de texto de
combate flutuante. Portanto, você pode fornecer um nome de
classe aqui para que possamos obter facilmente
esse método de texto definido. Então, nome da classe, texto de combate
flutuante, clicaremos em Controles lá. E agora, em nosso sistema de combate, sempre que denunciamos um golpe, queremos exemplificar nossa cena de texto de combate
flutuante. Veja, digamos que o texto Vara seja
do tipo texto de combate flutuante. E obtemos isso instanciando a cena de texto de combate flutuante Então, entre e depois instancie. OK. E então queremos
acrescentar isso quando criança. E agora não queremos
realmente adicionar o texto como filho
do alvo P, porque
quando o alvo P é
excluído da cena,
como acontece com a animação da morte, ele também remove
seus nós secundários como o texto flutuante de combate. Então, como temos
esse sistema global, o sistema de combate
para lidar com o texto, acho que talvez possamos nos
safar de simplesmente adicionar
filho
no próprio sistema
e, em seguida, adicionar o nó de texto. Agora precisamos definir
a posição global para a posição do alvo P. Portanto, a posição global do texto é igual à posição
global do ponto-alvo E se essa parte não funcionar ou tivermos outros problemas, podemos obter uma referência a
, tipo,
uma camada de tela, interface real e
a posição
nela sob algum tipo
de pai semelhante ao que estávamos
fazendo com um projétil, então só precisamos de um pai
para segurar todo o texto Mas a posição
deve ser onde o inimigo sofreu danos,
é a ideia aqui. Agora, queremos pegar o texto
e definir seu texto. Portanto, defina o texto como uma
sequência de P de dano. Portanto, o dano P é um número inteiro. Nós o convertemos em uma
string dizendo STR e, em seguida, colocando o
dano P entre parênteses E então definimos o texto
com esse valor de string. Então, se definirmos a cena de texto
flutuante do sistema de combate aqui, agora estou vendo a cena Singleton,
o sistema de combate, podemos ir até aqui
e
carregar rapidamente nosso texto de combate flutuante Então, temos essa referência à cena
lotada
aqui à direita, então deve ser instanciada vamos clicar em Play e
tentar Ok, então vamos fazer com
que o dano seja atingido. Ok, sim, isso é mais
ou menos o que esperamos. E veja, muito importante quando a orcha é
removida da cena, o texto não se remove sozinho Ok, agora vamos lidar com a animação do texto de combate
flutuante. Então fizemos isso no player de
animação. Crie uma nova animação
na parte inferior. Novo. E vamos ver. Podemos
chamá-lo do que quisermos. Vou usar float up
e, em seguida, precisamos adicionar
algumas propriedades para animar Portanto, adicione a etiqueta da
faixa de propriedade da faixa, especificamente a etiqueta, porque queremos essa posição de deslocamento Então, vamos procurar uma posição aqui. OK. Agora, não podemos ver nada porque não há
texto padrão no rótulo, então vou clicar no
rótulo e dizer DEF como padrão aqui Talvez também queiramos
atribuir um tema com uma nova fonte padrão que se adapte
um pouco melhor ao nosso jogo da Pixar Então, podemos fazer isso clicando
no texto flutuante de combate. Indo para o tema
no lado direito. Faça um novo tema, expanda isso, selecione uma fonte padrão e eu escolherei o que
já instalamos
no início do
projeto cinco x sete, que você pode ver que é
uma boa fonte Pixar Então, se quisermos reutilizar esse tema,
o que provavelmente fazemos Vou clicar com o botão direito do mouse e salvar
isso no projeto, e a interface do usuário soa bem. Então, vamos apenas dizer tema do jogo. Dot TRS por enquanto. Ok, se fecharmos
isso, você pode ver que agora é referenciado
pelo nome do arquivo Ok, agora, algumas coisas. No nó raiz, o texto de combate
flutuante, podemos ver que basicamente
tem essa caixa gigante. Na verdade, não precisamos que
seja tão grande. Então vá para o layout. E então, em vez de
Anchors preset full rect, vamos mudar isso Então, agora o controle
é apenas um pequeno ponto aqui em cima, e a etiqueta tem seu
próprio tamanho quando criança. Depois, outra coisa sobre o texto de combate
flutuante. Eu quero pegar o mouse
e mudar o filtro para
ignorar, apenas para que os cliques
do mouse ainda
apareçam na tela Mesmo que eles estejam tocando
nesse texto flutuante de combate, quero que os cliques
do mouse Portanto, se houver alguma
interface de usuário na tela, isso não interferirá no
pressionamento do botão da interface do usuário. Isso é muito importante. E agora voltamos ao nosso reprodutor de
animação e vamos definir a posição Então, vou ampliar
na parte inferior. Vamos clicar com o botão direito do mouse no
quadro-chave da posição e movê-la para onde quisermos que a posição
inicial esteja Então, o 00 é onde nosso
inimigo sofreu danos. Acho que só quero ter certeza que começa
em algum lugar acima disso. Então, eu vou para w
para mover o texto. Vou movê-lo para cá e, em seguida, definiremos
a posição aqui Então, vá para o layout
no lado direito
e, em seguida, vá para transformar
e quadro-chave da posição Então eu tenho menos
15 pixels no Y. E então podemos ver quanto
tempo queremos que isso dure Talvez meio segundo. Você também pode ativar o snapping,
se isso ajudar Ok, então 0,5 segundos. E então vamos movê-lo para cá. Então, mais ou menos assim
,
enquadre-o novamente no lado direito, usando
apenas o botão do quadro-chave Ok, e agora ele vai ser animado entre
esses dois pontos Então, se eu for para o
início e jogar, você pode ver que ele vai
animar esse movimento de posição Também podemos alterar a duração total
para 0,5 segundos. E então, se
quisermos, podemos resolver isso no
final
fazendo add track track
call method track na raiz flutuante do texto de
combate. E então clique com o botão direito aqui, insira e digite quarre Ok, isso garantirá que o texto se limpe depois concluído nessa cena, sem precisar personalizar o script de mais
nada, na verdade Podemos simplesmente chamá-lo a
partir da animação. Agora, isso provavelmente funcionaria, certo, agora, mas
é muito básico. Vamos testá-lo. Apenas
certifique-se de que funcione. Ok, sim, eu não
toquei a animação. Então é porque eu
não configurei a reprodução automática aqui. Então, no canto inferior direito
do
player de animação , reprodução automática ao carregar Ok, agora clicamos em Play novamente e estamos recebendo nossa animação. Ok, então isso funciona em
um nível muito básico. Não é nada ruim.
Mas enquanto estamos aqui, por que não torná-lo
mais interessante? Assim, posso adicionar uma faixa na faixa de
propriedades do rótulo e vamos fazer, digamos, a escala. Ok, então isso nos
permitirá torná-lo maior ou menor com
o passar do tempo. Então, vamos estruturá-lo
como está no horário 00. Digamos que cerca de
0,15 segundos ou
acho que estou caindo para 0,16 67 Isso realmente não importa aqui. você pode alterar
seu encaixe na parte inferior
direita, propósito, você pode alterar
seu encaixe na parte inferior
direita, se quiser ter
um encaixe de quadro-chave mais personalizável Então, vamos rotular e
depois transformar a escala. Vamos medir seu
tamanho e aumentá-lo. Então, talvez 1,5
ou talvez até dois. Podemos começar com isso e
reduzi-lo, se necessário. Então, vou estruturar isso. Então, agora ele vai passar
do tamanho 1,0 para 2,0. E então, quando estiver desaparecendo, queremos que fique bem pequeno Então, vamos levá-lo para, digamos, o tamanho
0,1 e, em seguida, quadros-chave. OK. Agora, se reproduzirmos nossa animação, é
mais ou menos assim. Talvez a escala seja
um pouco
grande demais neste segundo quadro-chave, então vou levá-la
para, digamos, 1,5 Eu acho que está certo. Clique em play. Ok, isso funciona muito bem. E também podemos pegar a
posição e deslocá-la talvez para
a direita quando ela estiver atingindo
esse ponto de tamanho máximo Então, vamos pegar a posição
aqui com o modo de movimento W e movê-la para
a direita ou algo assim
e, em seguida, enquadrá-la. Ok, e agora vamos jogar novamente. Agora podemos ver
como o texto aparece para
a direita e depois
volta para o canto superior esquerdo Outra coisa que
poderíamos fazer seria
mudar a cor do Alfa
ao longo do tempo. Então, vamos adicionar uma faixa na faixa de
propriedades do rótulo e fazer com que ela se
automodule. Portanto, isso afeta apenas esse rótulo, não quaisquer nós secundários. Então, vou me automodular
na etiqueta. Vamos clicar com o botão direito do mouse para inserir
uma chave no início. Portanto, este será nosso
branco padrão com Alpha completo. Vamos para 0,15 ou onde quer que nossos
quadros-chave estejam encaixados
aqui e insira uma 0,0 1667 para mim. E então vamos mudar
a cor para vermelho ou algo assim, porque
isso é para danificar o texto. E então vamos
até o final aqui. Clique com o botão direito do mouse para inserir uma chave e a alteraremos para,
digamos, zero Alpha. Pode jogar. Então agora
é mais ou menos assim. Acho que faria
mais sentido
trocarmos o primeiro
quadro-chave por este Então, vou arrastar
isso na linha do tempo. Vou puxar a esquerda
aqui até o ponto
0,0 1667. Isso
passa por aqui. Então, agora vai começar em
vermelho e ir para branco. E poderíamos terminar
com uma cor branca também. Então, vou clicar aqui,
ir até o valor e alterá-lo para 255
para o verde e o azul Então, termina em branco, embora
totalmente transparente. Se eu jogar algumas vezes aqui, parece muito gradiente. Quero dizer, na verdade é
porque estamos apenas passando de uma cor para
outra cor durante
um período de tempo Então, o gradiente seria
assim da esquerda para a direita. exemplo, ele vai do vermelho para o
branco à medida que avança
pela tela,
exceto que, em vez disso, estamos
fazendo isso com o tempo Então, depende de você
como você gosta daqui. Você pode simplesmente mudar
isso para vermelho também. Então, é vermelho o tempo todo. A única coisa que muda
é a transparência. Então você também teria que definir
o terceiro ponto
do quadro-chave , mais ou menos assim. Em vez disso, talvez queiramos que fique mais
escuro com o tempo, para que pudéssemos pegar os valores aqui e
torná-lo como um vermelho escuro
, mais ou menos assim, e
ver como funciona Sim, isso parece
muito bom, eu acho. Talvez o vermelho seja um
pouco vibrante demais, então eu poderia pegar o inicial e torná-lo mais ou
menos assim. E talvez possa ser um pouco
mais brilhante no pico. Vamos tentar, ok, do escuro para o claro e depois
para o escuro novamente. Então, isso parece funcionar muito
bem. Eu meio que gosto disso. Isso é puramente uma questão artística de
preferências pessoais. Então, realmente, o que você
quiser, vá com isso. Ok, então vamos jogar
e testar, e
teremos nosso texto de dano assim que atingirmos os inimigos. E me parece que
se move muito rápido. Então, talvez precisemos dobrar a duração dessa animação. Então, se clicarmos no reprodutor de
animação, podemos simplesmente mover esses
quadros-chave, e essa é uma das
grandes vantagens de
usar um
editor de animação de quadros-chave em vez de, você sabe, codificá-lo É mais fácil
iterar e
fazer pequenas alterações para ajustá-lo para que esteja onde
você deseja Então, vamos usar esses
quadros-chave para o Kframe. Coloque isso no final aqui em 1.0. Isso também deve ir para 1.0. E você pode arrastar uma caixa
sobre vários quadros-chave e movê-los todos de uma
vez desse jeito Então eu posso arrastar uma caixa aqui, e movê-la para,
poderíamos tentar 0,5
segundos, qualquer coisa. OK. Agora, isso é muito lento lá. Então, talvez queiramos que isso
seja mais parecido com o carregamento frontal. Vamos trazer isso para lá. Clique em play. OK. Quer
dizer, não tenho certeza. Teremos que tentar e ver como realmente
fica na tela. Parece que demora um
pouco demais para desaparecer. Então, talvez isso pertença mais esse lugar. Um pouco
mais adiante. E talvez 1,0
segundo seja muito tempo. Vou meio que arrastá-lo até lá. Então, qualquer que seja o
ponto do quadro-chave de 0,8 segundos, essa será a
duração do clipe Talvez o texto
também seja muito pequeno. Então, acho que uma
maneira de termos uma ideia é colocar uma cópia no
cenário mundial para que possamos vê-lo
aqui como está. Ok, então aqui está a mensagem do nosso pai. Acho que podemos
realmente escrever, clique aqui e criar filhos editáveis, e então podemos clicar
no reprodutor de animação e
testá-lo e ver aqui Se mudarmos para
flutuar, isso funciona? Sim, meio que sim. OK. Sim, isso ajuda
muito. Então você pode ver realmente como vai
ficar na jogabilidade
real, porque temos a cena
simulada aqui Ok, então talvez vamos
assumir a posição aqui, e eu vou mudar
isso um pouco para baixo. E parece que também
podemos criar um quadro-chave aqui, então isso é bom Então, isso realmente resulta
em 28 menos 31? Vamos fazer com que
desapareça um pouco mais rápido. Então, eu nunca
tentei dessa forma, especificamente. Parece que você pode usar o
quadro-chave no rótulo, mas não pode ajustar o reprodutor de animação diretamente ao editar a
partir dessa outra cena Portanto, há
uma pequena desvantagem aqui. Eu poderia mudar a
automodulação no primeiro quadro. E faça o keyframe lá.
Ok, então isso funciona. Isso atualiza o player de
animação. E então eu posso entrar na cena de texto de combate
flutuante. E eu quero pegar
a cor modular e movê-la muito mais
para a esquerda Então, ele ficará vermelho mais rápido, mas eu realmente não gostei quando estava vermelho o tempo todo. Ok, e então eu vou aqui e adicionarei outro quadro-chave. E nisso, farei com que
seja totalmente transparente. Portanto, ficará visível
na tela por mais tempo. Ele não desaparecerá até o final
da animação completa Vamos jogar e vou
tentar isso mais uma vez. Talvez aqui eu também queira que sua
cor seja branca. Então eu vou fazer isso. Então, basta
ter um flash de vermelho. Uma última coisa
no canto inferior direito se você usar o modo de
interpolação aqui, poderá alterá-lo para E vou fazer
isso para a posição, a escala e
as propriedades de
automodulação Então, se você olhar
bem de perto aqui, ele coloca uma pequena curva nos
lados esquerdo e direito para isso. Então, se isso estiver funcionando como
outros editores de cronograma, que eu acho que funciona,
isso significará
que será uma curva de entrada e
saída, em vez uma transição linear para
a animação Então, vamos testar isso aqui e
ver se esse é o caso. Isso é o que eu
esperaria de
outras coisas, como o editor de vídeo
DaventIrsolt E parece que
há essa flexibilização aqui. Então, vou trocá-lo de volta bem
rápido, só para comparar. Nós levamos isso para linear. Sim, agora a velocidade é
apenas consistente. Então, eu estava escrevendo minha suposição. Então, isso pode nos dar um
pouco mais de força à animação, porque ela tem seus momentos lentos e
seus movimentos rápidos Se clicarmos em play, testaremos
isso mais uma vez aqui, e acho que funciona
bem por enquanto. Então eu vou clicar em play.
Vamos testá-lo. Acho que a animação
é um pouco longa aqui. Só precisa ter
aquele momento em que possamos lê-lo claramente Ok, então,
mais uma vez, vou
encurtar um
pouco a animação aqui Puxando todos os
quadros-chave para 0,7 aqui. A animação termina em 0,7. Vamos jogar mais uma
vez e testar. Acho que vou terminar
depois disso. Ok, então o desbotamento agora
é muito rápido. Ok, e então para a
posição em que está desaparecendo, eu quero movê-la também Então deixe-me arrastar isso até
aqui para que eu possa ver. Clique no rótulo, talvez a carne
de porco esteja lá. Farei o quadro-chave da posição
e, em seguida, arrastarei esse ponto
de volta para a direita Acho que isso só tornará a animação um pouco mais sutil. OK. Sim, então agora,
quando está desaparecendo, não
se move tão longe E eu acho que é um
pouco mais suave de se ver. Então, poderíamos continuar
assim por muito tempo. Acho que você entendeu. Basta
personalizar a animação de acordo com que você
achar que faria ela se sentisse bem em termos de cor, escala, transparência,
posicionamento, etc As principais coisas deste
tutorial, porém, em termos de código, são apenas garantir que você tenha o sistema de combate.
É carregamento automático. Você diz para ele
relatar o dano
e, nesse relatório, você coloca o texto de combate e o adiciona não como filho do nó alvo
que sofreu o dano,
mas como
um nó do sistema ou apenas um nó persistente que nunca se removerá sozinho. E você remove o texto de combate
flutuante em sua animação
chamando Q de free. E essa é basicamente a essência todo o resto é
mais detalhe artístico
22. Movimento do inimigo (P21) com rastreamento de jogadores no Godot 4: Os projéteis já
têm
a capacidade de danificar e matar um inimigo, mas nossos inimigos na verdade não
caminham em direção ao jogador Então, para que os orcs se movam
em direção ao jogador, primeiro eles precisam de uma
referência ao jogador Seria um
pouco complicado ter uma referência direta entre
o orc e o jogador inicialmente, porque eles
não existem na mesma
cena quando o jogo começa Quando geramos inimigos
no mundo do jogo, eles vêm de uma cena
lotada Então, eles não existem
aqui até serem realmente colocados em cena
pelo sistema de desova. Então, o que poderíamos fazer em vez disso
é ter um recurso de referência, podemos chamá-lo de contexto do jogador, em que o jogador usa o recurso
e, em seguida, cada orc referenciará
esse recurso para identificar o alvo do jogador
assim que ele aparecer
no mundo do jogo Isso teria
alguns benefícios extras de poder trocar,
digamos, o
alvo do jogador por todos os inimigos
trocando
o recurso uma vez Poderíamos até mesmo fazer com que
o sistema de combate definisse a referência assim que eles colocassem uma cópia do orc
na cena do jogo Portanto, o sistema de desova
pode essencialmente escolher qual jogador cada orc
escolherá, e isso pode ter alguns benefícios
adicionais em relação a simplesmente torná-lo uma referência
única de dez, que você certamente poderia fazer, neste caso, pelo Mas isso também o vincularia estritamente a um jogo para um
único jogador, o que é bom para este curso. Mas vou tentar
mostrar como você pode conseguir isso com o método de recursos. Então, no canto inferior esquerdo
do nosso sistema de arquivos, vamos derrubar tudo. E vamos entrar nos personagens, e eu vou clicar com o botão direito
aqui, criar um novo roteiro. Vamos chamar esse jogador de contexto. E para heranças, vamos
torná-la um recurso. Ok, crie o novo script e certifique-se de abri-lo no editor de scripts que fornecerá
o contexto
do player ao nome da classe. Ok, então isso é apenas
configurado para ser essencialmente uma referência compartilhada a um
jogador específico dentro do jogo. Então, o que precisamos aqui será var player. E se tivermos uma classe de jogador,
faremos com que ela estenda isso. Então var player é do tipo player, e isso pode realmente ser
tudo o que realmente precisamos aqui. Para esse recurso. Então, vamos ao script do
player agora, e dentro do
player, vou
exportar uma referência para o contexto. Então, vamos fazer um contexto
Export var, e vou chamar isso de contexto do
tipo player context, controles para salvá-lo. E podemos ver no momento que temos um espaço para recursos. Então, vamos criar
nosso novo recurso. E então eu
quero clicar com o botão
direito e salvá-lo no projeto. Vamos salvá-lo em,
digamos, personagens. Poderíamos colocá-lo no player
se quisermos, então por que não? E então eu vou chamá-lo player Context aqui dot TRS,
que é para recursos Você também pode querer
mover o contexto do jogador no GD para o diretório do player com
barra de caracteres Ok. E agora nossos
orcs precisam de um alvo. Então, podemos ir até o NPC orc. Você pode clicar
aqui se precisar. Diremos que em Export var target
é um contexto de player de tipos. Se precisar, você também
pode transformá-lo um contexto de destino se
precisar
dar um passo mais genérico para isso, mas eles sempre
terão um alvo. Então, acho que tornar mais
específico chamando-o contexto
do jogador
pode ser um
pouco melhor aqui para
nosso caso específico. Mas sinta-se à vontade para
torná-lo um
contexto-alvo se
quiser que os inimigos
persigam objetos inanimados,
NPCs ou algo parecido E isso vai
conter a referência
ao jogador alvo que
esse NPC está perseguindo Então, vamos colocá-lo
diretamente no inspetor. Então clique em OC e,
no lado direito, precisamos dar a ele
o contexto do jogador. Então, vou clicar aqui.
Carregamento rápido, contexto do jogador. E você notará
que, embora o orc e o jogador sejam duas cenas completamente
separadas, podemos fazer com que eles façam
referência ao mesmo recurso e ao nosso projeto O recurso existe
no sistema de arquivos, então podemos referenciá-lo nossas cenas individuais empacotadas. Então, quando eles realmente forem adicionados ao mesmo cenário mundial do jogo, ambos
terão
a mesma referência. Então, o jogador
se definirá como jogador
no contexto do jogador
e, em seguida, todo o resto, os NPCs lerão
isso E é assim que eles
vão se relacionar uns com os outros por meio desse intermediário de
contexto Portanto, o script do NPC não fará nada
diretamente aqui Vamos
configurar isso no estado de Chase. Mas a última coisa que precisamos
fazer antes de chegarmos
ao estado de perseguição é voltar
à cena
do jogador e voltar para
dentro do jogador pronto. Primeiro, queremos
afirmar que o contexto não é nulo porque é
meio que necessário para o nosso jogo Portanto, afirme
o contexto para que o recurso precise ser definido aqui
para que o jogador possa se
tornar o jogador
do contexto E então vamos considerar o contexto: dot player é igual Na verdade, isso
vai ao ar qualquer maneira, assim que não
tivermos um contexto, porque
não pode ser nulo Portanto, essa afirmação pode
nem ser necessária. Podemos simplesmente cortar isso
e reduzir a redundância. Então, desde que tenhamos essa linha e o
jogador carregue primeiro, o jogador no
contexto está definido
e, em seguida, carregamos
todos os outros NPCs, podemos fazer com que eles usem
seu estado hace para se moverem em direção ao jogador Então, dentro de Ok,
vamos para o estado de Chase. Então, no
estado de Chase, precisamos
obter essa referência
ao jogador. Então, podemos obter isso como uma
referência ao orc, e então o orc tem o contexto do
jogador aqui Portanto, algumas etapas
foram removidas. Então, vamos ver. Talvez digamos algo como alvo de
VR, nó dois D aqui. Então, temos essa variável local. E então, sempre que entrarmos, no estado de Chase, obteremos uma
referência a esse alvo. Você pode até mesmo fazer isso na configuração,
se quiser que seja uma coisa única.
Vou colocá-lo em Enter. Então, toda vez que
entrarmos no estado, obteremos o novo alvo
do contexto do jogador. Portanto, o alvo sublinhado é igual ponto-alvo
do agente Como não sabemos qual é
o tipo de agente do NPC, não
sabemos se ele
tem o alvo e
não sabemos se o
alvo tem um jogador Ok, então essa parte é um
pouco frágil porque basicamente pressupõe
que o agente é um NPC, pressupõe
que o alvo está definido
e presume que o jogador ainda é propriedade
do contexto do jogador para obter Portanto, essa linha, especificamente,
pode ser quebrada facilmente se você mudar algumas de
suas outras classes. Talvez você queira apenas
configurar algumas afirmações aqui também para serem apenas sinais de alerta
precoce Então, poderíamos dizer afirmar o agente ponto-alvo e talvez afirmar o agente
ponto-alvo alvo jogador Vamos mudar isso de agent dot Target para agent
dot Target é um NPC Ok, e eu acho
que isso é bom o suficiente. Não abrange todos os casos, mas se mudássemos essa classe para
outra completamente diferente, acho que essas duas linhas
entenderiam isso. Vamos clicar em Play e ver se ainda
estamos bem ou se
temos algum problema aqui. Então, esperava-se que
o agente fosse um NPC. Talvez o que eu queira seja o
agente Target como NPC. Talvez eu esteja apenas usando
a palavra-chave vinculada lá. Então, aqui, eu realmente
quero verificar
se o agente é um NPC O agent dot Target
é o contexto do jogador. Portanto, garantimos
que o agente seja um NPC para que possamos
operá-lo nele E não estamos tendo problemas
agora. Então isso é bom. E a última coisa que
precisamos fazer é mover em
direção ao local de destino, e faremos isso na atualização do sublinhado da
função Então, vamos implementar
isso. Ok, então precisamos obter a posição do
alvo. Até agora, posição alvo. Ok, então isso
será atribuído a partir da posição global do
ponto alvo do sublinhado E então temos a
posição do nosso agente. Até a posição do agente. Isso será igual à posição global
do ponto do agente. Então, um agente pode tecnicamente
ser um nó normal, eu acho, e é por
isso que ele não aparece aqui Posição de agente da Savara. O motivo pelo qual não é possível
inferir o tipo é porque não sabemos com
certeza se o agente tem essa propriedade de posição
global Então, precisamos
declará-lo lá como um vetor dois. Ok, e então queremos
obter a direção entre esses dois locais. A direção de
Savara será igual à posição alvo menos
a posição
do agente E então normalizamos
esse vetor para obter apenas uma direção Portanto, ele normaliza o
valor XY para uma escala de 1,0. Não terá mais nada
parecido com a distância. Será apenas a direção
do par, que seria muito
parecida com se você estivesse
inserindo um vetor de ponto a ponto
para a entrada do teclado Isso também estaria em uma
escala de 0 a 1 para X e Y. Ok, agora que
temos a direção, só
precisamos nos mover na
velocidade que estamos atribuindo Então, cada um de nossos
personagens terá uma velocidade no jogo, e vamos
obter essa velocidade nosso controlador
de estatísticas Então, acho que uma boa maneira de configurá-lo seria
usar o Blackboard Então, se eu clicar em Enemy HSM, podemos acessar
o plano Blackboard, vamos gerenciar e
adicionar uma variável Vamos ver as estatísticas. Isso pode ser um caminho de nó
e, em seguida,
atribuiremos o controlador de estatísticas. Então, agora podemos usar isso em, digamos, nosso script Chase
e obter a velocidade dele. Então, na configuração, queremos
obter esse controlador de estatísticas. Portanto, podemos dizer que var,
underscore stats é um controlador de estatísticas, e diremos que as estatísticas de sublinhado iguais a Blackboard dot Git var, e estamos procurando Então, a partir daí,
queremos obter a velocidade. Então, var speed aqui
na parte inferior novamente, que é uma flutuação, será igual a underscore stats dot Get Ou, se quisermos tornar isso
ainda mais simples, podemos dizer apenas a velocidade dos pontos Então, agora precisamos de uma velocidade de tempo de execução
para as estatísticas do nosso personagem. Então, entramos no controlador de
estatísticas e vamos criar uma propriedade
de velocidade aqui. Então, para velocidade, um flutuador
é igual a 100,0. Então, essa é basicamente
a velocidade
de execução do personagem em tempo de execução. Ainda não configuramos nenhum recurso de
definição para controlar basicamente quais serão
as estatísticas iniciais de cada personagem, como o orc ou a dama, que colocarão em um
esqueleto Então, estamos apenas
construindo isso um passo de cada vez. Então, agora no Chase State,
temos nossa direção, temos nossa velocidade,
temos nosso Delta, então só precisamos mover o
personagem uma certa quantidade. Então, quando você move o corpo de um
personagem em dois D, há pelo menos duas
maneiras de fazer isso. Uma seria chamar
Move and slide, e isso seria no NPC Então esse agente é coisa de
NPC aqui em cima, acho que
seria melhor se fizéssemos Var NPC do tipo NPC E, em vez disso, dizemos que sublinhado NPC
é igual E então afirmamos que
esse NPC não é nulo. Portanto, isso garante que
o agente seja um NPC, mas também temos uma referência
ao NPC para que possamos usar
suas funções de classe Então, fica mais fácil
vir aqui e dizer coisas como NPC dot
MOV e slide Você pode usar isso, e
isso também teria a capacidade de deslizar
ao longo de qualquer colisão
que os inimigos Mas vamos fazer com que nossos
inimigos ignorem a colisão neste jogo, parcialmente porque ela permite que você coloque mais
inimigos na tela, e também parcialmente
porque simplifica as coisas, mas na verdade
vou fazer o npc dot Portanto, isso permite que você se mova sem levar
em consideração a colisão Portanto, tem a desvantagem de seus personagens não
conseguirem deslizar bordas como a beira
da água uma árvore ou coisas assim que
estão atrapalhando Mas também tem a vantagem de tornar o movimento o mais
simples possível, o que significa que você
pode colocar mais inimigos na tela ao mesmo tempo E eu acho que talvez
isso se encaixe
um pouco mais no estilo
de um vampiro sobrevivente Então, vamos simplificar a morte cerebral de
nossos inimigos. Então pc dot translate, estamos apenas movendo-o em uma
direção em uma quantidade. Então, fazemos direção vezes
velocidade vezes Delta. Agora, isso funcionaria bem, mas talvez você queira
levar esse bit para
mais uma variável acima
e salvar nosso movimento, que é do tipo vetor dois, e definiremos isso como
igual a esse bit aqui. Então, fazemos a matemática fora
da chamada da função
e, em seguida, a chamamos no vetor de
movimento dois
quando temos isso. Isso também
ajudaria na depuração pois você pode definir um
ponto de interrupção e, em seguida, mostrar
qual foi o valor da movimentação
antes
de você chamar translate Caso contrário, se você
simplesmente colocasse isso lá, você não saberia
o que está acontecendo na chamada de tradução, a menos
que entrasse aqui Então, um pouco mais limpo,
um pouco mais fácil. Ok, então eu vou
clicar em play, e vamos ver
onde estamos. Temos os orcs correndo
em direção ao jogador, e onde quer que o jogador
esteja na tela, eles
tentarão ir até lá, o
que é exatamente o que
esperaríamos Agora, eles se movem
bem rápido, então eu poderia entrar no
Stack Controller e levar a velocidade padrão
para algo como, digamos, 40,0 e em jogo Ok, e eu acho que isso é um
pouco mais apropriado. Na maioria dos casos, o inimigo
deve se mover mais devagar do o jogador para que o jogador tenha pelo
menos
a chance de evitá-lo. Podemos ver que eles estão todos empilhados uns sobre os outros Ok, então clicaremos em
play e veremos que os orcs
correrão em direção ao jogador Essas árvores não têm
nenhuma configuração de colisão, mas mesmo que tivessem,
elas ainda correriam direto
pelo corpo do jogador Agora, o jogador também está
colidindo com os orcs. E isso porque
os orcs ainda
têm a forma e o corpo de uma colisão,
e o jogador está se movendo
usando o movimento e Então, depende de nós para onde
queremos ir a partir daqui. Poderíamos mover todos os orcs para uma camada de colisão diferente
usando a colisão E eu provavelmente
faria isso agora. Vamos configurar algumas camadas de
colisão. Portanto, edite os nomes das camadas. Diremos que um é mundo, dois é jogador, três é inimigo, quatro é projétil, e isso deve ser bom
por enquanto. Vamos fechar isso. Então, queremos mover nossos
inimigos para a camada inimiga e desligar a
máscara para que eles não queiram realmente colidir
com nada no momento Então, agora, se clicarmos em
play, nosso jogador será capaz de
atravessar os inimigos, mas ainda assim colidirá
com qualquer outra coisa. Então, na verdade, eu realmente não gosto que eles
se sobreponham Portanto, embora o
Translate seja a função mais rápida de ser
executada aqui para o estado Chase. E esse é definitivamente
o conjunto de linhas de código que será o obstáculo de
desempenho do projeto porque você terá centenas
de potencialmente até milhares, de inimigos tentando se mover
ao mesmo tempo usando
esse script de atualização. E lembre-se de que quase todos os
inimigos estarão no estado de Chase
o
tempo todo até serem
realmente derrotados, e só serão
derrotados por um segundo. Então você está falando sobre tudo estar no estado Chase
ao mesmo tempo em que a atualização
é executada em todos os quadros. Então, essa é a parte em que, se você precisar otimizar
alguma coisa, seria isso. Vamos adicionar
novamente a colisão para os orcs. Faremos
com que eles colidam consigo mesmos e veremos se isso nos
dá um resultado melhor Os orcs estarem todos em cima
uns dos outros não é realmente o ideal Então, vamos colocar isso de volta. Então, em vez de fazer
NPC dot translate, o que fazemos é dizer que o underscore NPC Velocity será
igual a esse bit Então, vou me
livrar do Delta e vamos dizer nova velocidade Ok. E então ajustamos a velocidade antiga para
a nova velocidade E então, em vez de
chamar NPC dot translate, chamamos npc dot move e slide Mais uma vez, quero
repetir que isso consome cerca de duas vezes mais
poder de processamento dos meus testes Então, se você pudesse ter
5.000 inimigos na tela ao mesmo tempo antes
de perder o atraso, agora serão cerca de 2.500 Mas se você conseguir que
os inimigos se distanciem, talvez não precise de 2.500
inimigos na tela
ao mesmo tempo, porque
todos eles ocupam uma posição completamente
diferente Então, talvez esse seja o caminho a percorrer. Então, vamos até a
orca e faremos com
que ela mascare o inimigo Também colidirá
com o jogador aqui. Então, está olhando para o
jogador, o inimigo. E também vamos fazer disso o
mundo, mas não projéteis. Ok. E então queremos ir
até o jogador agora que na verdade estamos trabalhando com diferentes camadas de colisão, e definiremos a camada de colisão
que está sob a
colisão Objeto dois D E então queremos que ele
colida com o mundo. E, na verdade, acho que é exatamente isso. Pensando nisso
novamente, os orcs, talvez eu não queira que isso
colida com o jogador Quero que o jogador seja capaz
especificamente de
atravessar os inimigos para que
ele possa realmente escapar. Assim, os inimigos
colidirão com os
inimigos e com o mundo, e começaremos a jogar a partir daí Poderíamos até mesmo desligar
o mundo em algum momento. Depende do que
queremos. Ok, então vamos ver. Parece que os inimigos não
estão se acumulando
uns sobre os outros, o que provavelmente é bom Eles não ocuparão
exatamente o mesmo espaço. Se quisermos que eles fiquem
ainda mais espaçados, aumentaríamos o
tamanho dessa forma de colisão Aqui, se eu pausar o jogo
bem rápido e acessarmos o Editor de formas de colisão visíveis, podemos voltar Oh, temos que reiniciar o
jogo para isso, eu acho. Ok, vamos reiniciar e então poderemos ver
as formas da colisão Então, essa aqui embaixo é a forma de colisão do orc O maior deles é o raio de impacto, então podemos atingi-los bem alto, mas eles só podem colidir aos pés, porque foi assim que definimos as formas de colisão Mas sim, com essa configuração,
eles ficarão um pouco mais espaçados um do outro.
E acho que estou gostando.
23. P22 Gerando inimigos em uma curva de tempo: Você pode ver nossos inimigos trabalhando. Eles terão uma pequena colisão
um com o outro. O que, você sabe, depois de assistir esse é definitivamente
o caminho a percorrer, em vez do método de
tradução. No entanto, ainda temos apenas
quatro orcs ao mesmo tempo. Queremos ser capazes de gerar
um monte de caras
e, se quisermos esse estilo de sobrevivente,
queremos
que eles
apareçam fora da tela e
depois sigam em direção ao depois Então, quase em um círculo, precisamos que eles
apareçam fora da tela e , em seguida, coloquem o jogador
no centro da tela Então, precisaremos de um
sistema de desova para fazer isso. Vamos ao mundo e adicionaremos um novo nó
do sistema aqui. Vou clicar com o botão direito do mouse em Adicionar
um nó filho como nó
e, em seguida, renomear
isso para sistema de geração ou
SponnorSystem, se você preferir ou
SponnorSystem Clique com o botão direito do mouse e
anexe um script. Então, vamos chamá-lo de
sponsorsystem dot gD e eu vou salvá-lo
na pasta systems E então, para nosso sistema de geração, precisaremos
declarar várias propriedades diferentes que serão barras de exportação para
que você possa
personalizá-las no Então, primeiro, precisamos
da margem de desova, que é uma flutuação,
e eu vou defini-la como padrão para dez.
Esqueci o carro lá Ok, então a margem de desova é a distância mínima da tela que os
personagens podem gerar Isso está em pixels. Vou receber esse nome
para serem personagens na verdade, e personagens de lá em
cima também. Talvez tenhamos um mundo
onde geramos NPCs, não necessariamente apenas inimigos Portanto, ajuda ser mais genérico
quando você não tem certeza sobre o uso final do seu
script, porque talvez você queira que ele seja mais flexível do que apenas
matar inimigos. Ok, em seguida, queremos
o alcance extra de spawn. Ok, então no Export
VR span extra range, vou fazer com que chegue a 100. Ok, então essa é
a distância adicional que um inimigo pode aparecer longe da borda
da tela, além da margem
de extensão Portanto, se sua margem de desova for dez e seu alcance extra for 100, isso significa que
a distância em
pixels da borda da câmera será de dez a 110 pixels Então, precisamos das definições de nossos inimigos que
vamos gerar Portanto, isso deve ser
basicamente uma configuração que
diz o que pode aparecer
sob quais condições Então, digamos que em export
var random definitions, que é uma matriz de definição de
desova. Ok, agora não
definimos essa classe. Vai ser
um tipo de recurso. É uma definição que configuramos no editor e que
usamos durante o jogo. Portanto, um recurso é o
tipo perfeito para esse tipo de dado. Ok, então isso vai nos
dar um erro
porque não
temos o nome da
classe de definição de geração Vamos fazer isso. Agora mesmo. Vou entrar na raiz do nosso
projeto e do sistema de arquivos. Digamos que talvez isso pertença aos sistemas porque faz parte do sistema de
desova. Vou clicar com o botão direito do mouse,
criar uma pasta e diremos spawning E aí dentro, eu clico com o botão direito do
mouse, crio um novo script e digo aqui gerando a definição de
sublinhado, que é do Ok, crie isso e
depois abra esse script. Ok, e precisamos
dar um nome de classe, definição de geração
aqui no topo, e nos preocuparemos em configurá-la
um pouco mais tarde Então, para continuar com
o sistema de desova, precisamos de um pai para onde
realmente geramos nossos objetos Portanto, em Export var spawn parent
é uma referência do nó dois D, o pai de qualquer objeto
gerado pelo sistema E então queremos a frequência. Então, vou fazer
disso uma curva para que
possamos controlar o cronômetro. Conforme o tempo avança basta usar uma curva e, em seguida, fazer a
amostragem da Então, em vez de definir
dez períodos de tempo diferentes, após 30 segundos, apareça a
cada 0,5 segundos. E depois de 60 segundos, spa a cada 0,4 segundos. Podemos apenas tê-lo como uma curva. E então, não importa
quando esteja desovando, ele obterá a próxima
quantidade de cronômetro a partir Então, se você vai
ter muitos valores, é mais fácil
definir uma curva com
uma inclinação do que
ir uma por uma e ser como se X então Y fosse um estilo mais
de dicionário Então, eu vou dizer export
var span frequency, que é do tipo curva. OK. Voltaremos a
isso no inspetor Ok, a próxima coisa
que vamos
querer é uma variável de tempo de execução. Vou chamá-lo de
var random span stats. E isso vai
ser do tipo dicionário. Quero fornecer o tipo de
chave do dicionário e um tipo de valor. E o tipo de valor
são estatísticas de geração. Portanto, isso corresponderá
ao tipo de desova às estatísticas
da desova em uma proporção de um para
um em tempo para
um Então, isso é específico do tempo de execução, e isso é específico do editor. E as estatísticas
de geração
acompanharão quando
foi a última vez que realmente
geramos um objeto e quantas vezes
geramos usando Então, vamos criar nosso objeto de estatísticas
de geração. Vou clicar com o botão direito do mouse em spawning
e criar um novo script. Vamos chamá-lo de estatísticas de desova. Na verdade,
essa extensão será contada como referência. Agora podemos entrar no span Stats
e, aqui em cima, vou dar a
ele o nome da classe spatts E as duas coisas que
eu quero rastrear aqui são a contagem de spawn, que é um número inteiro que começa em zero e a última hora de spawn, que é uma flutuação, e
vamos começar no Essa será a última vez que o objeto será gerado. Ok, agora em nosso sistema de
desova, temos essa relação Então, quando iniciamos
o sistema de geração, queremos pegar as definições
e criar uma nova estatística de amplitude para
cada uma das Portanto, isso lida com
os dados de tempo de execução. Isso trata dos detalhes do editor para nossa configuração individual aqui. Então, se quisermos
obter as estatísticas de amplitude, podemos apenas referenciar
a definição de amplitude, e ela imediatamente exibirá
as estatísticas de amplitude que
correspondem a ela as estatísticas de amplitude que
correspondem a Em poucas palavras, é assim que os dicionários
funcionam. Você tem uma chave e
ela lhe dará um valor, e é muito
útil para relacionar dois objetos diferentes. Então, vamos configurar nossa função pronta para o
sistema. Então, digamos que a função underscore ready retorne nula E queremos dizer que, para definição
em definições aleatórias, queremos pegar as estatísticas de desova
aleatórias e atribuir a chave de
definição ao nosso valor, que será
uma nova estatística de desova Então, o spawn começa com um ponto em OK. E agora temos um
desses objetos para
cada definição, e eles estão vinculados
em uma definição
de um a um de geração como chave e
estatísticas de amplitude como valor Então, agora fica
muito fácil consultar as estatísticas
de spawn
para obter a definição Ok, digamos que o próximo tempo de desova seja igual
à frequência de
desova,
que é a curva, e
amostramos na curva o tempo
decorrido desde o início
do jogo Então, precisamos de mais algumas
variáveis aqui, na verdade. Vamos precisar
do tempo decorrido,
que é o tempo desde
que o sistema de desova entrou no Podemos criar uma variável de temporizador. Portanto, VarSpawtr é um flutuador
do tipo zero, zero. Como esse
será um cronômetro interno, não há problema em ter um nó gerenciando seu
próprio controle de tempo Então, vamos tentar fazer isso com
um sistema de amplitude em vez criar um
objeto de cronômetro real no mundo do jogo Portanto, o sistema
de desova administrará seu próprio tempo para
essa instância E então, a
próxima hora de desova do spa será basicamente quanto tempo estamos
esperando pelo próximo spa Vamos configurar a função de
cronômetro aqui, processo de sublinhado da
função, e esse será Delta como
parâmetro, retornará Vamos pegar o
tempo decorrido e adicionar o Delta,
que é o tempo desde a última chamada
do processo Então, o tempo decorrido
mais é igual a Delta. E então queremos
pegar o cronômetro de desova e mais também ser igual
ao Delta, já que estamos acompanhando há
quanto tempo E diremos que o
cronômetro de desova é maior ou igual
ao próximo tempo de desova, então vamos
fazer um Então, um intervalo aleatório aqui
e, depois disso,
usaremos o cronômetro de desova E em vez de definir
isso diretamente para Zal, vou ser menos igual
ao próximo tempo de desova, porque pode
haver um
pouco de tempo restante,
especialmente se chegarmos a intervalos de tempo muito especialmente se chegarmos a Então eu acho que é um pouco melhor torná-lo mais
preciso assim. E então diremos que
a próxima hora de desova será uma amostragem
da curva de frequência Então, é igual à
frequência de geração da amostra de pontos, e estamos
amostrando Então, basicamente, na curva XY, é um gráfico em que X é o tempo decorrido desde que o
sistema entrou em cena E então Y é quanto tempo
esperar pelo próximo período. Portanto, seja qual for o tempo decorrido, haverá um novo
valor que podemos obter
da curva para definir
nosso próximo horário de desova Ok, mais algumas linhas, e vamos fazer nossa função de geração
aleatória, até
agora random span Tipo de devolução do vazio. Então, o que precisamos fazer é obter nossa definição de desova
que queremos gerar Então, essa será uma seleção
aleatória com base na ponderação de cada
uma
das definições para determinar qual objeto
será estendido ou não gerado Ok, vou passar por
aqui por enquanto porque a lógica da
desova vai
ficar um pouco
mais complicada Eu só quero fazer com
que possamos
pelo menos vê-lo funcionando no mundo dos
jogos por enquanto. Então, voltando em uma visão em dois D, vamos pegar o
sistema de geração e atribuir esse bom pai ao nó
inimigo. Está bem? Então, desse jeito,
deveriam ser inimigos. Essa frequência de
ligação será uma nova curva. Então, vamos seguir essa curva e podemos definir valores. Então, se você puder ampliar
aqui, isso vai ajudar. O domínio Min no domínio
Max será basicamente quantos segundos
de jogo o temos. Então você poderia dizer algo como 300 segundos ou 120 segundos. Por mais longo
que você ache que o nível deveria ser, isso seria o que você
gostaria de tornar o domínio máximo. Então, se você tiver uma última vez para seu nível e
depois disso, o nível terminar, isso
seria perfeito para o domínio
Max aqui. O valor X Y, o que queremos obter sempre que
amostramos o valor X. Então, quanto tempo
deve demorar entre os spawns? Talvez dois como valor
máximo , então subimos até a curva
e clicamos com o botão esquerdo
para definir um ponto, e meio
que controlamos isso. Então, em geral, no
início de um nível, você gostaria de menos
spawns do que no final Então, se colocarmos
isso aqui e dissermos que, talvez apenas a cada 1,5
segundo, um personagem apareça, e então vamos para a direita e
clicamos com
o botão esquerdo e puxamos
esse ponto do quadro-chave para algo assim,
onde podemos dizer cada talvez não 0,2 Oh, talvez sempre 0,2 segundos. Então, a cada 0,2 segundos,
um inimigo pode aparecer. E nós meio que temos essa
curva daqui até aqui. Você também pode
clicar nos pontos, e há um ajustador de curva se você precisar ficar um
pouco mais sofisticado com Então, agora, se fizéssemos uma amostra, digamos que aos 75 segundos
do início do nível do jogo, isso significaria
que o tempo de desova seria de cerca de 1,2 Podemos ver isso de onde o
XY se cruza na linha. Da mesma forma, se
chegássemos até 225
, seria
cerca de meio segundo
entre a frequência de desova do inimigo Portanto, a dificuldade fica
mais difícil à medida que o nível avança. E podemos simplesmente ajustar
isso. Você pode até definir um terceiro ponto no meio,
se precisar disso. Talvez você precise que fique
achatado por um tempo e
depois fique muito duro Controle E para desfazer. E acho que você
pode clicar com o botão direito do mouse em um nó para
removê-lo do gráfico. Provavelmente, dois
pontos serão bons o suficiente,
porque você pode controlar isso com as
alças se precisar
alterar essa taxa em que fica mais difícil.
Mas
nós poderíamos meio que fazer isso. Agora, vou pessoalmente
seguir esse caminho
aqui à esquerda,
porque em nossos testes, eu realmente não quero
testar depois de 2 minutos. Eu só quero
acelerá-lo para que eu possa
mostrar como isso vai
funcionar mais tarde Mas em seu jogo real, fique à vontade para ter uma curva de
desova
muito mais longa Então, agora, depois de
120 segundos aqui, ele vai ficar
plano para o resto. E isso é bom
para mim agora. Ok, agora vamos criar uma definição de
desova. Aqui em cima. Vamos adicionar um. Precisamos criar um novo recurso para
a definição de desova. Então, nova definição de desova, vamos clicar com o botão direito do mouse e salvá-la Vamos falar sobre
personagens, inimigos. E eu posso colocar isso na
mesma pasta em que o orc está porque vamos
chamá-lo de orc Definição de apenas desova de orcs. Acho que a desova de orcs é boa. Dot TR, sim, nós o salvamos. Mas é claro que isso ainda não tem nada associado. Então, precisamos adicionar qual cena
lotada vamos
realmente
instanciar sempre que
gerarmos Ok, então, na
definição de spawning, script. Vamos adicionar
a exportação do vR à cena, que é um tipo de cena compactada. E também podemos adicionar
um peso variável de exportação, que será uma flutuação de 1,0 Portanto, temos a cena a
ser gerada e a
preferência de selecionar essa cena como opção aleatória de geração Então, quando selecionamos aleatoriamente, podemos ter três tipos, e cada um deles tem
um peso diferente Então, se um tem um peso de três e o outro
tem um peso de um, então aquele que tem
um peso de três tem três vezes mais chances de ser selecionado como aquele que
tem um peso de um. E essa é apenas uma maneira
de torná-lo um
pouco mais distorcido
na aleatoriedade Portanto, não é perfeitamente aleatório. É que cada escolha
tem um peso, e o peso
determina as chances. No esquema da seleção
aleatória. Então, clicamos no sistema de
desova agora. Ok spawning agora terá
uma referência de cena, então carregamos rapidamente nossa cena Ok Ok, agora isso
nos dá o que precisamos. Então, para o
spawn aleatório, vou simplificá-lo o máximo
possível agora,
obtendo a primeira definição na lista e, em seguida,
instanciando-a Até agora, a instância, que
será número dois, D é igual às
definições aleatórias na posição zero. E nós vamos
pegar a cena, e vamos instanciar isso Ok, então agora temos nosso Oc. Essa é a posição zero
e a desova do orc. Então, vamos pegar isso
e adicionar isso ao pai aleatório ou
ao pai
do spawn Então, gere o ponto pai e o
filho da instância, faremos com que a instância vá para a posição 00 por enquanto Nos preocuparemos com seu
posicionamento aleatório mais tarde. E então podemos ver que o gerenciamento
de intervalos já é gerenciado aqui fora
da função de geração aleatória Então, honestamente, isso pode
ser tudo o que precisamos. Para fins de teste,
vou pegar isso e passar cerca de 10
segundos aqui, só para que possamos realmente ver o aumento da desova,
se funcionar, e clicaremos em play.
Então, vamos ver. Temos algum
personagem chegando às 00? Oh, sim, sim, eu posso
vê-los ali mesmo. Ok, então aqui estão nossos orcs. Você pode ver que está surgindo cada vez mais rápido passar do tempo Então, basicamente, já
atingimos o pico de desova de orcs, e nossas lanças podem simplesmente
cortá-los porque nossa lança
não tem contagem máxima de acertos, então é muito fácil vencer este Mas você pode ver como a
curva faz com que possamos facilmente aumentar a
desova com o passar do tempo, e esse é um
recurso interessante que eu realmente gosto muito É muito melhor
trabalhar com isso do que definir em 10 segundos, agora a taxa de desova é 1,0
e, em 20 segundos, agora é 0,9 Então, agora você pode simplesmente todos os
valores de todo o tempo, basicamente, ser gerenciados
por essa curva, e é muito mais
fácil editá-los. Você perde a precisão,
mas fica muito mais simples dar uma ideia geral do que
você precisa para esses valores E você ainda pode,
você sabe, clicar e definir valores absolutos. Então, nos pontos aqui, você
pode ver que pode definir as posições XY exatas para esses pontos se precisar
ser realmente técnico. Mas na maioria dos casos, como eu disse, apenas dois pontos em
uma curva serão bons o suficiente. Portanto, ainda há muito a acrescentar
ao sistema de desova, mas esse é um bom
começo para o que precisamos
24. Parte 23 Gerando a tela com deslocamento calculado: Ok, então já temos
nossa desova funcionando. Mas o problema é
que os personagens estão surgindo apenas
no ponto 00 em que
realmente queremos que eles apareçam
da câmera para onde quer que nossa
câmera esteja olhando Então, sempre parece que eles estão vindo de algum lugar
muito distante, mas, na verdade, eles estão
vindo de um pouco longe do
que podemos ver. E então eles
vão nadar com o jogador em vez de desovar
no ponto Então, vamos trabalhar nisso. Ok, então em nosso script do sistema
Spanner, vamos voltar a
ele em um intervalo aleatório Então, no momento, a desova aleatória não
é muito aleatória. Vamos trabalhar para tirar
o inimigo da tela. Portanto, precisamos obter um novo local para onde estamos
gerando a instância Então, aqui embaixo, vamos adicionar
uma posição de geração var. Então, isso vai
ser um vetor dois. E vamos obter isso em Obter posição de desova fora da câmera Então, queremos gerar uma posição
de amplitude que esteja
fora da câmera. Então, isso
envolverá um pouco de matemática e a janela
de visualização atual da própria câmera. Então, vamos criar nossa função, Get span position, fora da câmera. Então, a primeira coisa que
precisamos fazer é colocar o TD da câmera que está ativo no
momento, o que nosso
jogador humano real está vendo na tela, para que possamos ficar fora dela
quando desovarmos Portanto, nossa câmera
será igual a Get viewport. Então, basicamente, estamos
vendo o que o jogador
pode ver atualmente e vamos pegar a câmera duas D que
o jogador está usando
para ver a janela de visualização Então, temos acesso a
essa câmera talvez até faça
sentido marcá-la ,
talvez até faça
sentido marcá-la como uma câmera dois D. Então, poderíamos fazer um guarda
verificar se quisermos aqui, dizendo que se a
câmera for nula, que provavelmente nunca deveria
acontecer, mas, em teoria, se pudesse, então
queremos enviar um erro dizendo
que não há câmera,
nenhuma câmera 2 D
encontrada na janela de visualização Talvez isso possa ocorrer se,
por algum motivo, você estiver usando uma câmera de três D e simplesmente não
houver duas câmeras D. Acho que isso
faria com que isso desencadeasse um erro. Então, é possível. Ok, então se isso ocorrer, então há um grande
problema no jogo. Vamos apenas retornar o ponto zero
do vetor. Isso acontece e enviaremos o erro e deixaremos o
desenvolvedor descobrir
: Ah, por que não há
câmera no jogo. Ok, mas supondo que
tenhamos uma câmera, podemos realmente fazer as contas Então, primeiro, queremos obter a posição central
da câmera. Vamos fazer com que o
centro da câmera VR seja um vetor dois, e queremos a
posição global do documento da
câmera para isso.
Sim, sem mais nem menos. E então queremos o
tamanho da câmera. Então, qual é o tamanho da câmera
na dimensão X e
na dimensão Y. Então esse deve ser
outro vetor dois. Então, vamos dizer que o tamanho da câmera VR do vetor dois
será igual ao vetor dois, e obteremos o tamanho da janela de visualização Então, obtenha o tamanho do ponto da janela de visualização
e, em seguida, queremos dividi-lo
pelo zoom da câmera Ok, então a razão para
isso é que nossa câmera, especialmente em um jogo de
dois D da Pixar, se eu clicar na câmera
dois D aqui em cima, e depois olharmos
aqui para o Zoom, você pode ver que nosso Zoom pode realmente pegar a
janela de visualização e
escalá-la em quatro ou cinco vezes para que possamos ver bem
nossa Pixar É por isso que precisamos ter certeza que, mesmo que estejamos
vendo, digamos, 12 80 por 720 pixels, se aumentarmos o zoom por
um fator de cinco, tamanho da nossa câmera
será realmente reduzido para esses novos
valores com base no É por isso que precisamos
fazer esse ajuste. Então, a seguir, temos
a câmera VR reta, que é uma reta dois do
tipo D ou melhor, reta dois. E essa é uma forma
retangular que representa os limites
da nossa câmera É baseado no tamanho. Então, para a matemática aqui,
estamos construindo um novo retângulo
fazendo o retângulo dois
e E nosso primeiro parâmetro é o centro
da câmera menos o tamanho da câmera E então multiplicamos
isso por 0,5. E então, para a
segunda dimensão, temos apenas o tamanho da câmera. Então, isso nos dá a caixa retangular
apropriada que representa a
câmera na tela Em seguida, queremos
selecionar aleatoriamente uma borda que usaremos para
gerar os inimigos Então nossa câmera é uma caixa, então ela tem quatro bordas, e podemos basicamente gerar
nossos inimigos acima, abaixo, para a
esquerda ou para a direita Então, queremos apenas escolher
uma dessas arestas
e, como
queremos uma distribuição uniforme, faremos isso aleatoriamente.
E então não há espera. Então, em essência, isso
deve significar apenas que eles estão vindo de todas as
direções de forma bastante consistente. Então, se dissermos var edge, vamos fazer com
que seja um valor inteiro, e será igual
a Rand I para Vamos dar quatro
por cento? O sinal de porcentagem aqui
significa resto, então é o resto
da divisão por quatro, que significa que
será zero, um, dois
ou três, e esses
representam nossas Ok, então precisamos de uma compensação. que distância da
borda queremos
realmente gerar nosso inimigo Não queremos que eles
apareçam diretamente na borda, porque assim ficariam visíveis na tela quando
entrassem no mundo do jogo, e isso pareceria
meio estranho Então, digamos que var offset, e acredito que essa será
uma flutuação,
igual à margem de sublinhado da extensão mais Ok, então estamos basicamente gerando um flutuador aleatório
aqui e vamos multiplicá-lo pelo intervalo extra
de amplitude Portanto, F aleatório pode ser 0-1 0,0. Portanto, um valor de zero vezes o alcance
extra do nosso intervalo nos
dará uma
distância extra de desova de zero E se for 1,0, dará 100 porque é isso que
definimos para a propriedade span extra
range. E se tivermos
algo intermediário
, obteremos
algum valor de pixels de 0 a 100 Além de nossa margem de amplitude, nos
dando a compensação total Ok, então vamos dizer a posição
var spa, e isso será
atribuído a um vetor 20 aqui. Em vez disso, zero é o limite
máximo da constante. Ok. Adicione mais algumas linhas. E diremos que se a borda for
menor ou igual a um, então estamos tratando isso
como a parte superior ou inferior. Então, vamos pegar nossa vantagem e fazer uma
declaração de correspondência com ela para que
possamos calcular a posição do filho com base na aresta que
estamos realmente usando. Então, digamos que match edge
e, padrão,
enviaremos um erro resolvido Número da borda, porcentagem
x vantagem percentual. Então, ter isso é meio que útil se esquecermos
de, por algum motivo, colocar
uma das caixas. Agora, podemos realmente combinar
o número inteiro da borda com um valor Enum se quisermos ser um pouco mais descritivos verbalmente Então, se subirmos até o topo, declararei um
enum, digamos, borda enum, e teremos o topo como zero, o
fundo como um, a esquerda como
dois e a direita como três Ok, então agora, se formos até aqui e combinarmos a
borda com esses valores, poderíamos dizer borda ponto
acima, se eu não estiver errado. Espere um minuto. Parece que há um
pequeno problema aqui. Ainda assim, preciso colocar um sinal de
igual aqui para o reto da câmera. Ok,
então isso vai funcionar. Agora podemos descer até
onde
estávamos fazendo a correspondência do Enum e queremos realmente
inserir o código aqui Portanto, a posição de desova
X para o topo será igual
a uma
flutuação aleatória de um intervalo Então, dizemos intervalo de sublinhado Rnf, e vamos da posição do ponto do
retângulo da câmera ponto X para a posição ponto
da câmera ponto X
mais o tamanho do ponto da câmera ponto X. Então, para um retângulo tutti, a posição X sempre estará
aqui em cima Então, se você adicionar o
tamanho X a isso, você virá aqui
no lado direito. Então,
se vamos para o topo, queremos nos posicionar em algum lugar
entre aqui e aqui. É por isso que pegamos
o valor aleatório
da posição e depois a
posição mais o tamanho. Então isso nos permite chegar em algum lugar entre
essa linha aqui. E então precisamos fazer a posição
Y, é claro. Então, a posição Y do spawn será igual à câmera Rect. Posição do ponto, ponto, Y. Menos o deslocamento Então, estamos subtraindo o deslocamento porque quando você
subtrai um valor Y, na verdade
você está
subindo na tela Então, temos a posição Y, que é o topo
do nosso retângulo Então, deixe-me tirar a
tinta aqui. A posição Y está aqui
em cima, certo? Mais especificamente,
seria o valor Y que nos levaria ao
ponto 00 no retângulo Então você pega o deslocamento, que será algum valor
aleatório aqui em cima Então, nosso inimigo vai meio que aparecer nessa área,
grosso modo, e
isso se baseia em qualquer que seja o deslocamento Y gerado aleatoriamente Então, temos nossa margem de dez pixels, e então temos
110 pixels aqui em cima como nossa área extra de margem positiva, e então nossos inimigos podem aparecer em algum lugar dentro
daqui para obter o valor máximo Ok, espero
que isso faça sentido. E então nós meio
que fazemos a mesma coisa para todas as outras bordas. Então, borda com pontos na parte inferior. Vai ser exatamente
essa formação aqui. E então a posição Y do vão ser um
pouco diferente. Então, queremos que o ponto Y da
posição de geração seja igual reto
da câmera, ponto Y,
mais o tamanho do ponto reto da câmera,
ponto Y.
Então, isso nos leva à parte inferior do retângulo. Então, isso nos leva Porque agora estamos
adicionando o tamanho Y, que nos puxa
para essa área inferior E então adicionamos
o deslocamento a isso. Então, acrescente o deslocamento e
observe que estamos adicionando o deslocamento porque
queremos ir mais abaixo da caixa da câmera,
mas na parte superior, subtraímos o Isso é muito importante. Agora fazemos
a mesma coisa com
a esquerda e a direita. Então, ponto de borda à esquerda, que são nossos dois enum. E isso será a
posição de geração: ponto X igual, ponto reto
da câmera, ponto ponto y menos o deslocamento, porque estamos indo para a esquerda em nossa caixa, então queremos Isso é tudo para a posição X do
spa, e é o POS do spa, não a
posição do spa. Eu o abreviei Então, o poste Y do spa agora
será igual a, e pegamos um intervalo F aleatório entre o retângulo da câmera ou o retângulo da câmera, posição do ponto Y. Então essa será a parte superior
da nossa caixa E então o outro lado do aleatório será
o fundo da nossa caixa. Então isso vai ser a
posição do ponto destruído da
câmera, ponto Y, mais o tamanho do ponto
destruído da câmera, ponto Y. Então, quando adicionamos o tamanho, mais
uma vez, vamos Portanto, nossa posição vertical do vão para a esquerda e para a direita está
em algum lugar nesta linha aqui E, finalmente,
pontuar para a direita em maiúsculas. Ele terá a posição de
amplitude X da
câmera, posição do ponto reto, ponto X mais a câmera, nós dimensionamos o
ponto X mais o deslocamento Então, a mesma coisa.
Temos uma caixa aqui e uma caixa aqui, e queremos
deslocar para a direita
ou para a esquerda se
estivermos gerando para a esquerda Deixe-me verificar
isso. Ok, posição X mais ponto de tamanho X mais deslocamento Ok, isso parece correto. Claro, vamos
testá-lo no jogo. E então a posição
Y do vão deve ser a mesma
porque ainda estamos lidando com essa vertical escolhendo um ponto aleatório
entre aqui
e aqui e aqui
para a geração esquerda e
direita Ok, então esse deve
ser basicamente nosso código de posição de amplitude. E então queremos
retornar a posição do vão. Portanto, essa função
está boa do jeito que está. Não é tão ruim. Se
ficasse um pouco maior, eu provavelmente o
levaria para outra função. Honestamente, poderíamos
porque senti a necessidade de colocar esse
comentário no código Então, se eu quisesse,
poderíamos dizer função, sublinhar, calcular a geração
final, que retornará
em um vetor dois E então colocamos isso aqui em vez de padronizá-lo para o vetor dois e colocar
tudo isso aqui embaixo. E reduzimos isso para
nossas novas funções, então estamos refratando E então, obviamente,
exigiremos que alguns parâmetros
entrem nessa função
para que ela funcione. Então, primeiro,
precisamos, digamos, câmera rect, que
é um retângulo dois, e então precisamos do tamanho da câmera, que é um vetor dois Control S. E então queremos retornar a posição do
filho dentro daqui Portanto, a posição de geração de var
é um tipo de vetor dois. Descemos até o fundo e
retornamos a
posição do spa daqui. Está bem? Aqui em cima, queremos
passar esses parâmetros, então a câmera reta e o tamanho da câmera E então precisamos disso aqui. Finalmente, também
precisamos do deslocamento. Então, passe o offset aqui em cima. Ok. E então precisamos de
offset como parâmetro Então, offset, e acho que também
era um vetor dois. Está bem? Então, o Control S, na verdade,
era apenas um fluxo? Oh, era um carro alegórico. Ok.
Então, um flutuador unidirecional E depois de salvar esse, a maioria desses erros
deve desaparecer. Então, precisamos combinar na borda e depois voltar. Também poderíamos inserir
esse parâmetro de borda. Então, edge, que
vai ser do tipo. Na verdade, poderíamos
usar o enum aqui. Deve funcionar bem
porque o número inteiro pode ser atribuído automaticamente a
um enum, até onde eu sei Então, se
subirmos até aqui e passarmos pela borda, ok, vai entrar
aqui e
vai funcionar como uma enumeração, que é mais ou menos o que
esperamos encontrar aqui embaixo Então, para examinar um pouco
os enums, um Enum é basicamente uma
lista de valores nomeados que correspondem à
posição inteira dentro desse Então, o zero, porque esta é a primeira, é a posição zero. Então, é como o primeiro
item em uma matriz. Você quase poderia pensar
assim. E então o fundo é um, a esquerda
é dois e a direita é três. Acho que algumas linguagens
permitem que você atribua valores inteiros
personalizados a um Eenum Não sei se
você pode fazer isso no GdCrip, mas essa é
basicamente a ideia Se você não mexer com isso
, zero é o melhor. Um fica na parte inferior, dois esquerda e
três na direita. Mas o que isso
lhe dá a vantagem de fazer é que, quando você
cria uma função como essa, em vez de dizer
zero, um, dois, três, que é muito
obscuro para o que isso realmente
representa, o que é um Você pode simplesmente substituir
isso por edge dot top, que é o valor de zero, mas fica muito mais claro
para alguém que está lendo o código o que isso realmente
deveria representar Ok, vamos ver. Então, temos nossa
posição Get spawn fora da câmera, e a tivemos aqui
em um intervalo aleatório Então, agora, na verdade, precisamos definir a posição para a instância. Portanto, a posição
global da instância será igual
à posição de desova Essa parte é fácil. Vamos clicar em Play e ver se
realmente funciona. Porque isso era
um pouco de código. Ok, então nossos personagens não estão
aparecendo na tela. Eu os vejo
saindo da tela. Vamos ver, ou qualquer um vindo
de baixo e da direita. Não vejo nada vindo
de cima ou da esquerda, e isso meio que
me preocupa um pouco. Então, vou ver se consigo encontrá-los. Ok. E acho que o que
devemos fazer para testar isso. Vou fechar o jogo
agora mesmo é descer até aqui e estávamos sentindo falta deles
na parte superior e na esquerda. Então, vamos adicionar um ponto de interrupção
aqui e um ponto de interrupção aqui. Então, se, de fato, os
personagens estão tentando aparecer do topo e da
esquerda, eles devem aparecer. E então podemos verificar os valores que eles estão realmente atingindo. Então eu esqueci de parar no jogo, então ele atingirá
automaticamente esse ponto de interrupção Clique em Play e veja se podemos
obter um da esquerda. Ok, lá eu vi um
vindo de cima, na verdade. Ok, e um está
vindo da esquerda, supostamente. Então parece que está
meio que acontecendo, certo. Talvez se eu aumentar muito a taxa de
desova, seja mais fácil ver com certeza Então, vamos para o mundo. Temos o sistema de chave inglesa? Vou pegar isso aqui
mesmo. Vou me
lembrar do valor. Então, eram 0,66 e 1,5, e vou descer até
aqui para que possamos ter uma
desova muito rápida por enquanto Vamos clicar em Play e
eu vou testar. Então, vamos ver
um monte de caras surgindo muito rápido ou deveríamos E sim, ok, isso
parece quase correto. Podemos pegar um cara do
canto inferior esquerdo aqui? Porque eu quero ver
isso acontecer também. Ok, sim, sim,
finalmente, finalmente. Temos alguns caras lá. Ok, então eu acho que
está funcionando corretamente. Se houver algum problema, é
possível que a matemática não
tenha sido verificada duas vezes
para estar correta, mas acho que está indo
do jeito que deveria. Se não, é um
pouco difícil dizer. Mas sim, eu
os vejo vindo de todas as direções. Então eu
acho que estamos bem aqui. essa matemática
seria algo muito No entanto, essa matemática
seria algo muito
fácil de errar, então vou colocá-la na tela
mais uma vez se você precisar
verificar novamente. Então, temos nossa posição de desova. Estamos obtendo isso da posição G
spawn fora da câmera. Essa é a nossa função aqui. Então, obtemos o centro
da câmera a partir da posição global
da câmera, o tamanho da câmera é
do tamanho da janela de visualização, e então você divide isso
pelo zoom da câmera O retângulo da câmera
é construído a
partir do centro da câmera menos
o tamanho da câmera vezes 0,5
e, em seguida, o valor Y para
isso é apenas o tamanho da câmera A borda é um número inteiro aleatório e você obtém o
restante de quatro, que lhe dará de
zero a O deslocamento é a margem do intervalo mais F aleatório vezes
o intervalo extra do intervalo Então, isso está em algum lugar de 0-1
ponto com pontos decimais, e então adicionamos o intervalo extra de amplitude como uma
porcentagem Calcule a extensão final usando todas as propriedades que acabamos de
configurar: o reto da câmera, o tamanho da câmera, o
deslocamento e a borda Então, vamos colocar isso aqui. Nós combinamos no limite. Então, zero, um, dois e três. E então, para o valor X
na parte superior e inferior, fazemos um intervalo aleatório
entre o lado esquerdo e o lado direito. Usando essa matemática. Para a posição Y, tomamos a posição Y na parte superior e subtraímos o deslocamento
ou, para a parte inferior, adicionamos o tamanho para
chegar à parte inferior
e, em seguida, adicionamos o E então, para a esquerda e para a direita, fazemos a mesma coisa ao contrário. Então, para X, fazemos o
lado esquerdo menos o deslocamento, nos
dando mais para a E então, para o lado
direito, adicionamos o tamanho à posição
X para obter o lado direito
e, em seguida, adicionamos o deslocamento para ir mais para a
direita a partir disso Então, para a posição Y do vão, fazemos um intervalo aleatório
entre a posição, que é a posição zero Y, e depois a posição mais o tamanho, que nos dá a posição do
canto inferior no eixo Y. E isso fará com que o
spa esquerdo e direito estejam em algum lugar entre a parte superior da tela na vertical e a parte inferior
da tela na vertical Mas a posição está
deslocada da tela, então não vamos realmente
vê-los aparecendo. E retornamos
a posição do intervalo que
possamos usá-la
nessa outra função, e isso praticamente
encerrará tudo.
25. Ladrilho 24 — gerador de inimigos aleatório com condições de peso e tempo: Nossa desova fora da tela
está funcionando, essencialmente. Há algumas coisas que
eu quero limpar
e, em seguida, continuaremos adicionando um inimigo esquelético para que
possamos selecionar aleatoriamente
qual inimigo
criaremos com
base em um sistema Então, vamos encerrar o jogo. E primeiro, podemos
ver esse rótulo aqui, a instância de
texto de combate flutuante. Não precisamos
mais disso porque terminamos de editar
a animação. Então, vou
deletar esse nó. E então, no sistema de desova, para a demonstração, eu
baixei esse valor
mais baixo do que era Então, aqui no primeiro ponto, eu queria trazer isso de
volta ao original, que era tipo, acho que originalmente eram 0,66 segundos
e depois 1,5 Vou fazer com que
0 segundos e depois 1,5 segundos seja o período de
desova. Então, na verdade, podemos simplesmente ir
até aqui e digitar 1,50. Pressione Enter, se quiser
ser preciso com a configuração, e você pode ver que
o ponto selecionado mostra 0 segundos
e, em seguida, 1,5 segundo
como o tempo de geração 0 segundos é o
tempo decorrido aqui, se você se lembra. Acho que esses quatro inimigos do trabalho, poderíamos simplesmente remover
da cena. Então, vou excluí-los. Então eu vou
selecioná-los, clique em OK. Você pode clicar em play apenas para
testar se tudo
ainda funciona,
e devemos fazer com que os inimigos saem
da tela
venham em nossa direção Não temos. Você pode
clicar em play se quiser
verificar novamente e apenas garantir que os inimigos ainda
estejam surgindo Nós simplesmente não precisamos
desses inimigos iniciais porque os inimigos
virão depois que o jogo começar. Queremos dar ao
jogador alguns segundos para,
você sabe, se familiarizar com os controles e assim por diante Ok, então para criar
o inimigo esqueleto, vamos primeiro clonar o orc que Então, vou
pesquisar o orc e o projeto. Vamos até Orc Dot TCN. Vou clicar com o botão direito do mouse
e cloná-lo, então duplique. Vou chamá-lo de Skeleton Dot TCN. E então vamos pesquisar
no projeto aquela cena de esqueleto
que
acabamos de criar Clique duas vezes nele. E
então vamos ampliar aqui. Então, vou pegar
o sprite aqui e alterá-lo para o sprite
esqueleto Então, vamos dar
uma olhada rápida na direita, e vamos
procurar o ídolo, e deve haver
um para o esqueleto Talvez precisemos ampliar um pouco. Deveria haver um aqui
para um inimigo esquelético. E então, no canto superior
direito, podemos carregar rapidamente, e talvez você precise ampliar
um pouco para encontrá-lo, mas digite idle e procuraremos a planilha de sprites esqueleto Pode ser um pouco
difícil de ver, mas vou selecionar
esse aqui. Se você não conseguir encontrá-lo,
fique à vontade para navegar pelo
sistema de arquivos e encontrá-lo. Provavelmente está na pasta base do
esqueleto. Ok, agora vamos renomear o nó
raiz para esqueleto. E precisaremos
configurar
o reprodutor de animação para garantir que ele
reproduza as animações de idle skeleton
e, em seguida, Ron skeleton e skeleton death Então, vamos ao reprodutor de
animação. E então, no canto inferior
direito, basicamente
precisamos alterar a textura
de cada um deles. Assim, a textura redefinida irá para o canto superior direito e, em seguida,
carregará rapidamente a
folha de sprite Idle que acabamos No momento, ele
já está pré-selecionado, então podemos selecioná-lo. E talvez você
queira jogar e
garantir que ele ative, reinicie o esqueleto e, em seguida, altere a textura das
outras animações Então, Idle, vamos clicar na textura, ir
para o canto superior direito Carga rápida, escolha a
folha de sprite pela terceira vez. Ok, e clique em Play. E então certifique-se de que está
sendo reproduzido corretamente. Parece bom. Vamos para a animação
da morte. Selecione a textura aqui. E como há muitos
quadros no canto superior direito, é um pouco difícil
realmente ver o que está acontecendo, ainda mais difícil do que
a animação ociosa Então, acho que seria mais fácil simplesmente navegar até
a arte
e depois encontrar o pacote gratuito do Pixel
Crawler, entidade,
multidões, tripulação básica, morte base
e, em seguida, arrastar
a folha da morte
para o canto superior direito desse jeito para o canto superior Ok, aperte play e verifique
se está tocando corretamente. Então, parece que há oito
quadros de animação aqui. Portanto, precisamos ampliar
um pouco assim e
garantir que os quadros H sejam definidos
no canto superior direito para oito. Ok, então clique em Play. Sim.
Ok, isso parece correto. E agora precisamos adicionar o sétimo e
o
oitavo quadros-chave Então, clique com o botão direito no quadro em 0,6
segundos e insira a chave, clique nela, vá
para o canto superior direito, mude para seis, faça
a mesma coisa em 0,7. Você não pode fotografar lá porque
precisamos estender a animação Portanto, faça com que a animação
tenha 0,8 segundos de duração. Clique em 0,7, S nesse
quadro-chave e altere-o para sete, pois a oitava posição é o que queremos.
Ok, vamos clicar em Play. Jogue mais uma vez.
Aqui está nossa animação. Agora mova o
estado de morte concluído até o final em 0,8
segundos, e aí está nossa animação de morte. Ok, então nós
queremos correr. Deveria ser mais rápido. Clique na textura. E então, no canto inferior esquerdo, onde diz base esquelética, escolha a pasta de execução, a
planilha de execução no canto superior direito Deixe isso aí. Clique em play e podemos ver que está
reproduzindo nossa animação de corrida. Tem as mesmas faixas etárias, então é tudo o que precisamos mudar. Ok, esse é o básico
do nosso esqueleto. Podemos ir até o controlador
de estatísticas. Além de atribuir estatísticas, é como velocidade de corrida, HP
e assim por
diante para nosso esqueleto e
valores personalizados para nossos orcs e CD, que
são a configuração básica nossos
dois personagens Então, vamos voltar ao mundo, e então teremos
o sistema de geração, certo Então, temos nossas definições aleatórias
aqui à direita. Queremos adicionar outra definição
aleatória
e, em seguida, vamos
criar uma nova. Então, nova definição de desova. Digamos que o peso
do esqueleto seja 0,5, então teremos metade dos
esqueletos dos orcs E vamos carregar rapidamente a cena do
esqueleto, ok? E então vamos verificar
o script do sistema de patrocinadores. Então abra isso e veremos
a seleção aleatória aqui. Então, no momento, ele
não está gerando a cena de seleção
aleatória. Basta selecionar o
primeiro na matriz. Então, precisamos de
um pouco de código ou de
uma função para escolher qual cena vamos
realmente instanciar. Então, vamos ampliar,
e eu vou dizer que var scene é uma cena lotada, e vamos
querer selecionar spawn aleatório de
uma lista de definições que podem ser distribuídas aleatoriamente
. Então, vamos dizer
definições aleatórias, exceto isso. E então precisamos criar essa função de seleção aleatória de
geração Então eu vou fazer a função Control V para colá-lo. E então vamos
dizer que as definições P são uma matriz de, vamos ver o que eles
chamam de definição de geração. E vamos retornar
uma única cena cheia. Então, se as definições de P estiverem vazias, podemos retornar null porque não há nada
para selecionar Caso contrário, vamos
calcular
a partir de todos os pesos totais e gerar
aleatoriamente um valor entre zero e
o peso total para determinar qual cena
estamos realmente Então isso é seleção aleatória, mas é seleção
aleatória ponderada Então, digamos que se nosso peso total for flutuante, comece em 0,0 E então, para a definição
ou as definições D e P, vamos pegar
o peso total e
aumentá-lo pelo peso da definição. Está bem? Então, fazemos isso
para cada definição. Agora temos o peso total e precisamos gerar um valor entre zero e
o peso total. Até agora, digamos que o
valor aleatório seja um valor flutuante. E vamos pegar um
F aleatório . Então, isso é zero
a um ponto, tudo incluído,
incluindo decimal, e será
vezes o peso total Então, isso
nos dará um valor aleatório entre zero e
o peso total. E então digamos que o fluxo de peso
verificado em V seja 0,0. Então, esse é o valor de peso que
tentamos passar antes de
atingir o valor aleatório Quando atingirmos o valor aleatório, retornaremos qualquer cena ou definição em
que estejamos
atualmente Então, para definição
nas definições P, vamos dizer que
o peso verificado
mais é igual ao peso do
ponto de definição E se o peso verificado
estiver acima do valor aleatório
, retornaremos a cena. Então, retorne o ponto de definição CM. OK. E então, se
chegarmos ao fim e ainda não tivermos
atingido nada, isso é um problema, então
podemos enviar um erro. Ok, então aqui estou
inserindo um erro. Não foi possível
encontrar uma definição em porcentagens do valor de peso, em
que o peso
total verificado era porcentagens que o peso
total verificado era E então eu estou substituindo
essas porcentagens valor aleatório e
pelo peso verificado Então, isso meio que mostra o que estávamos verificando,
onde chegamos, e indica que na verdade não
encontramos um verificado que estivesse
acima do valor aleatório, que sempre deve
acontecer porque o valor aleatório só pode
ir até o peso total. Portanto, isso não deve ocorrer, mas se isso acontecer, temos
uma mensagem de erro. E então, no final
, podemos simplesmente dizer return null porque ele não
foi capaz de encontrar
uma definição adequada Então, isso faz mais sentido. Provavelmente
quebrará algo imediatamente indicando que
algo precisa ser corrigido
na matemática nessa função. Mais uma vez, quero enfatizar que
isso nunca deveria acontecer. Se nossa matemática estiver correta. Ok, então selecionamos o spawn aleatório da
nossa lista de definições, e isso lida com o peso
e os cálculos aleatórios Então, se eu rodar o jogo
agora do jeito que as coisas estão, deveríamos ter metade
dos esqueletos dos orcs Mas vamos ver.
Pegamos os dois? Porque devemos
pegar os dois. Então, temos alguns orcs surgindo. Ok, então, na
verdade, o código estava funcionando perfeitamente bem
para selecionar um spawn aleatório Eu só esqueci de usar a cena. Então, queremos ver
a cena aqui. E em vez de instanciar zero de
definição aleatória,
nós apenas enviamos instanciate nós apenas enviamos Ok, agora podemos voltar ao spawn aleatório e remover
a mensagem de depuração do Prince Está bem? E se jogarmos
, deve funcionar bem. Na verdade, ele deve
usar o que selecionamos aleatoriamente, em vez sempre o
primeiro na matriz Portanto, devemos ter metade dos
esqueletos dos orcs, mas
aí está o nosso E com o passar do tempo, você verá muito mais orcs
do que esqueletos por causa da espera.
Ok, então isso é bom. E essa é basicamente
a ideia. Ok, então a última coisa
nesta parte que talvez você queira
adiar quanto tempo até que uma definição de inimigo possa
realmente aparecer no jogo Por exemplo, no início,
talvez você só tenha orcs, mas depois de um tempo,
você pode adicionar esqueletos Então, já temos
o tempo decorrido. Então, se dissermos um tempo inicial
e final em termos
de tempo decorrido em que uma
definição pode ser gerada, podemos controlar
quando
os orcs podem desovar e quando os esqueletos podem aparecer Então, se eu entrar na definição de
spawning, podemos adicionar uma var de exportação aqui
ou no horário de início um float, e isso pode ser 0,0 E então, o horário de término
também será padronizado como 0,0. Então, o que queremos fazer
com esses dois é começar a criar como um método que pode
ser gerado Então, poderíamos dizer que a
função pode ser gerada,
o que, obviamente,
retornará um verdadeiro falso booleano E para isso,
na verdade, queremos passar o tempo decorrido porque
isso faz parte da condição disso, temos que verificar a hora do jogo ou a hora em que o sistema de geração foi realmente criado E então usaremos
isso para verificar se o tempo decorrido está dentro
da hora de início
ou da hora de término Portanto, se o tempo decorrido de P for
anterior ao tempo inicial,
retornaremos false Se a hora de término
não for igual a 0,0, ou melhor, se a hora de término
for maior que 0,0, acho que é um
pouco mais fácil de ler. Em seguida, queremos verificar se o horário final
realmente foi ultrapassado. Então, se a hora final for
zero, estamos simplesmente ignorando. Então, e o tempo decorrido P estiver
acima do tempo final
, retornaremos false Caso contrário, passamos por todas as condições para que
possamos retornar verdadeiras. Então, isso é basicamente
tudo o que precisamos
fazer para um gerador baseado no tempo,
e apenas verificamos se
ele pode ser gerado e apenas verificamos se
ele pode ser E se não
puder ser gerado, nós o removemos da lista que consideramos para seleção
aleatória Você faria algo
muito parecido. Se você também quiser, digamos, ter um número máximo para
que eles possam ser gerados, basta passar
o número que
foi gerado e
verificar se ele está
acima ou igual ao
número máximo
que a definição de desova
permitiria foi gerado e
verificar se ele está acima ou igual ao
número máximo que a definição de desova Isso seria útil
para algo como um chefe que só pode aparecer uma vez Então você pode verificar: Oh, ele pode aparecer uma vez.
Quantas vezes ele aparece? É um ou maior
do que não gerá-lo. Vamos ver se
voltaremos a isso, mas isso deve ser tudo o
que precisamos para escrever agora. Então, agora, de volta ao sistema
spawner, queremos basicamente filtrar
spawnb a partir das Então, vou
criar um
filtro de função spawnb que
usará
uma matriz de definições
de P definições, e essa é a arma. Essa é a definição de
desova. E então retornaremos
nossas definições filtradas. Portanto, retorne uma matriz de definição de
desova. Então, criamos nossa lista
filtrada aqui. Var filtrou uma matriz de definições
de geração, e isso será
igual a uma E então, para as definições de DF
e P, verificaremos se o DEF
pode ser gerado Acho que precisamos do tempo
decorrido aqui, mas isso é uma variável local Então, podemos simplesmente passá-lo
diretamente para isso. Então, o tempo decorrido, por exemplo,
não precisamos colocá-lo como parâmetro para essa
função porque faz
parte do estado do objeto,
que é o sistema de geração Então, se ele puder ser gerado, nós o adicionaremos
à lista filtrada Portanto, definição de caneta de pontos filtrada. E então, no
final, retornamos filtrado, então aqui em um intervalo aleatório, fazemos var spanable e isso será
igual a filter spanable, que usará nossas definições
aleatórias
como parâmetro E então, em vez de
selecionar a geração aleatória partir de definições aleatórias, selecionamos a geração aleatória da
nossa variável filtrada que pode nossa variável filtrada Ok, agora que isso nos dá a habilidade no sistema de
geração,
se examinarmos as definições de
desova,
podemos dizer hora de início, hora Digamos que os orcs
estejam sempre ativos. Mas então, para a desova de esqueletos, não
podemos gerar esqueletos
até 15 segundos, mas quando conseguimos
gerar esqueletos, temos um peso de dois,
então acabamos vendo muitos esqueletos assim que
eles Então podemos jogar. E se
toda a matemática estiver correta, inicialmente não veremos nada
além de orcs Mas depois de 15 segundos, pode ser útil ter um horário para terminar o
jogo ou algo assim,
veremos se precisamos disso. Depois de 15 segundos, podemos ver que os
esqueletos começarão a
desovar porque
agora podem ser expandidos agora podem ser porque o tempo inicial
de 15 Ok, agora você pode ver os
esqueletos começarem a entrar. Então, temos nossa segunda
onda de inimigos e poderíamos simplesmente tornar
os esqueletos mais resistentes Portanto, a dificuldade
avança à medida que o jogo avança, porque adicionamos
inimigos mais difíceis E, claro,
no sistema de desova, aumentamos a
taxa de desova também, Então você pode ver
como isso funcionaria. Essa é a natureza de
basicamente controlar a desova aleatória do
nosso sistema de desova Isso é a maior parte do que
realmente precisamos aqui. Bom trabalho
acompanhando tudo até agora. Ok, então podemos
fazer alguns ajustes aqui e ali mais tarde, se precisarmos,
mas
na maioria das vezes,
esse é o nosso sistema gerador. Então, agora devemos
começar a trabalhar aprimorar
um pouco mais o combate e fazer com que nossos inimigos realmente sejam
capazes de prejudicar nossos jogadores Seria um bom próximo vídeo.
Então, vamos partir daí.
26. Configuração de Hurtbox para jogadores P25 e Hitbox do inimigo: Parte de nossa
mecânica básica de combate será
configurar a habilidade dos
inimigos atingirem nosso jogador, o que
envolverá a criação uma caixa de acerto para os inimigos quando
eles se depararem com o jogador, e precisamos garantir que o jogador também tenha uma caixa de
Hurt E provavelmente
adicionaremos um
tempo de invencibilidade apenas para garantir que não
recebamos muitos golpes quando
formos atacados por um inimigo
desse tipo Ok, então em nosso player, criaremos nossos nós Hurt Box. Então, vou
clicar com o botão direito do mouse na rota do jogador, adicionar um nó secundário e procurar o HRT Box
two D. Enter, adicione-o Vamos atribuir o controlador de
estatísticas, que ainda não adicionamos
ao nosso player, para possamos clicar com o botão direito do mouse no jogador, adicionar um nó filho, um controlador de
estatísticas Ok. E então queremos
fazer algumas tarefas. Então, o objeto do controlador
SAT será a raiz do jogador. E então, na caixa HRT, queremos atribuir
o controlador estatístico Portanto, nossa caixa HRT, você pode
ver pelo sinal de aviso, também
precisamos de uma forma de colisão Então, vamos clicar com o botão direito do mouse nele
e atribuir a ele um nó filho. Colisão em forma dois D. E
, em seguida, no canto superior direito, faremos isso provavelmente em
forma de círculo Ok, então temos essa forma de
círculo aparecendo. Queremos reduzir isso
até o tamanho em
que queremos causar danos aos nossos jogadores Então, dependendo de como
queremos fazer isso,
podemos torná-lo um pouco menor ou um
pouco maior do que
nossa forma de colisão Vou crescer por enquanto, e depois podemos
reduzi-lo, se necessário equilibrar o jogo ou
para melhorar
a sensação das coisas Então, isso já nos
dá
a capacidade de causar danos ao jogador. Agora precisamos dar aos inimigos
a habilidade de
causar dano ao jogador. Então, em nossa cena orc, vamos clicar com o botão direito do mouse em Orc, adicionar um nó secundário e
clicar na caixa dois D. E então isso vai
precisar de uma forma de colisão. Então, clique com o botão direito,
adicione um nó secundário, forma de
colisão dois D, e
então, no canto superior direito, vamos transformá-lo em um círculo
e, em seguida,
reduzi-lo até onde
queremos que o orc seja
capaz Então, vou torná-lo
um pouco maior do que a forma
de colisão principal da colisão real Então, em nosso RT Box two D,
se verificarmos o script, podemos ver que
obtemos o sinal
de acerto da caixa de acerto
atingindo uma caixa RT Então, para causar dano, na verdade
precisamos de outro script para causar
dano no sinal
atingido e emitido Antes disso, porém, vamos adicionar as camadas de colisão para nossa caixa de
acerto e nossas caixas feridas Então, a caixa de acerto dois D
na camada de colisão vai mascarar a camada
do jogador Então, máscara da camada dois porque
essa é a camada do jogador. Para as camadas em que
essa caixa de quadril existe, podemos simplesmente desativar a camada um
ou definir a camada três
para o inimigo, se quisermos. Mas provavelmente
vou desligar o monitorável porque essa
é uma caixa de quadril unidirecional Ele só precisa detectar. Se encontrar uma caixa no quadril, ela não
precisa ser
monitorada por outros nós dentro do
jogo, pelo menos atualmente Então, vamos
jogar e eu vou fazer o inverso para o
Box two D. Aqui, vamos
desligar o monitoramento e vamos
enfrentar a colisão Vamos criar
a camada como jogador. Essa é uma camada dois muito importante aqui, podemos desligar a máscara. Então, dentro
daqui, vou clicar com o botão
direito do mouse em Hit Box two D e vou
adicionar um novo nó, adicionar nó filho. Este
será um nó dois D. E vamos renomeá-lo para
algo como ataque de colisão. Então, quando o orc colide com outro inimigo usando
essa caixa dois D, ele causará todo o dano
como dano de colisão Muitos jogos clássicos
têm esse tipo de coisa que um inimigo simplesmente corre até
você e você sofre danos. Então, teremos que clicar com o botão direito aqui e criar um novo script. Então, vamos colocar o ataque de colisão nos inimigos. Eu acho
que isso é apropriado. Crie. Vou renomeá-lo ataque de colisão de nome de
classe aqui na parte superior Vamos exportar uma referência
para a caixa de acerto Então Hit Box é do tipo Hit Box
two D. E, em seguida, quando pronto, função em pontuação
pronta, retorna void Vamos pegar o Hit Box e vamos nos conectar
ao sinal de sucesso. Então, ponto é atingido, ponto se conecta, e nós
vamos conectar ao bater. Então, agora precisamos, digamos, do dano at export var aqui, que será um número inteiro Podemos padronizá-lo para dez. Então, vamos obter o
retorno de chamada para o hit com a função on hit
underscore on Agora você precisa
clicar com o botão direito do mouse em Hit e verificar os parâmetros do sinal. Então, temos a
caixa Hurt dois D aqui. Ok, então isso também nos dará
acesso às estatísticas. Então, dentro do
ataque de colisão, vamos recuar. Então, temos a caixa P Hurt, que é do tipo Hurt Box dois D. Isso retornará vazio
e, em seguida, atingiremos
o jogador Ok, então ao apertar P
Hurt Box two D, queremos pegar a caixa P HRT, e queremos causar dano
tridal nela, e vamos
transmitir o E aí está mais ou menos isso, porque já
escrevemos isso na caixa de feridas. Portanto, a caixa Hurt já
lida com relatórios. Eu já manipulo a
configuração do HP, que emitirá o sinal para que o HP mude,
se precisarmos disso E ele faz o cálculo. Também faz a proteção para garantir que
possamos atingir o alvo Então, faz sentido
usarmos essa lógica onde. Enquanto tivermos um ataque de
colisão, colocamos a caixa de ataque
aqui e ajustamos nosso dano Podemos ver se isso vai funcionar. Então, vou tentar encontrar
um inimigo e ver se nosso jogador sofre
o dano acima dele. Ok. Eu só preciso ter
certeza de que Oh, ok, sim. Lá vamos nós. Nosso jogador
foi atingido por dez. Sabemos que é o jogador
e não o inimigo porque a lança
atualmente faz 100 Agora, atualmente,
parece haver um problema, que é que o inimigo
que já está morto parece ainda ser
capaz de atingir o jogador. Já demorou 100. Eu
fui para o Death State, e o ataque de colisão ainda
estava habilitado Então, poderíamos lidar com
isso de algumas maneiras. Uma seria verificar o controlador de estatísticas e garantir que o
controlador pilha do orc,
o HP, esteja acima de zero ou que
o orc ainda esteja Caso contrário, simplesmente
ignoraremos completamente esse ataque. Essa seria uma maneira decente. Outra forma seria
colocá-lo no estado de morte e depois desativarmos
todas as caixas de acerto assim que nosso orc
for considerado morto Acho que talvez seja
muita responsabilidade
pelo estado de morte. Então eu acho que pertence
um pouco melhor aqui no ataque de colisão Então, o que faremos é exportar uma referência para
nosso controlador de estatísticas, exportar V stats stat Então, o que vamos dizer sobre isso é que, se não for stats dot Live,
voltaremos. Caso contrário, causaremos danos. Então, basicamente, enquanto
o personagem
não está vivo, ele não pode atacar, mas se estiver vivo,
consideraremos o dano de colisão válido se
conseguirmos essa conexão Então, agora,
se
voltarmos a jogar aqui, poderemos caminhar
até um inimigo que acabou de ser derrotado
sem sofrer danos. Ok, então eu preciso
cronometrar isso corretamente. Ok, eu me deparo com ele e
vemos que acertamos, mas esqueci de definir as estatísticas Portanto, pode ser um bom
momento para uma afirmação. Então, afirme as estatísticas. Portanto, a estatística
precisa ser definida para que
possamos verificar se o
personagem está vivo. E então, isso
basicamente já
exigirá que tenhamos o erro de refrigerante na caixa de
sucesso, se esquecermos de
colocá-lo no inspetor Ok, então aí perto.
Clique em Ataque de colisão. Vamos atribuir as estatísticas. Vamos entrar em jogo. Vamos fazer isso mais uma vez. Encontre um orc E você pode ver
que não sofremos danos se o orc já tiver sido
derrotado, mais uma vez Sim, parece estar
funcionando muito bem.
27. Cronômetro de invencibilidade de jogador P26 e definições de estatísticas personalizadas: Ok, então a última coisa
neste vídeo que
queremos configurar um período de
vulnerabilidade, especificamente para o nosso player. Então, no Stat Controller, podemos entrar aqui. Portanto, no controlador SC, podemos criar um temporizador de invulnerabilidade Então, digamos que aqui embaixo V Invincible time e
podemos padronizar isso para 0,0 Será do tipo flutuador. Portanto, é o momento em
que o objeto
não pode ser danificado
após ser atingido . Ok, então com nosso
tempo invencível padronizado para zero, isso vai ser
bom para No entanto, para um jogador de quatro horas, queremos ter
nosso valor personalizado para o tempo de Invincible. E provavelmente também
queremos
personalizar coisas como HP,
velocidade, HP máximo, etc Então, estamos realmente chegando
ao ponto em que precisamos configurar algum tipo
de definição de estatísticas, onde podemos definir quais serão
as estatísticas iniciais de cada
personagem. Então, se pudéssemos criar
um novo script para isso, que se pareceria muito
com nossa definição de armas, em que estamos apenas
definindo propriedades sobre o personagem
e seu bloco de estatísticas Então, na
foto do personagem, tudo bem, clique em Criar um novo script, e vamos chamá-lo de definição de
sublinhado estatístico Isso se estenderá do recurso
e clique em Criar, ok? Em seguida, pesquise o script
que acabamos criar a definição Stat, clique
duas vezes nele E chegaremos até
aqui até o topo. Então, definição estatística do nome da classe. Portanto, isso definirá as
estatísticas padrão para um tipo de objeto. Então, as estatísticas
que queremos vão basicamente espelhar o que
temos no controlador de estatísticas Então, vamos entrar
no controlador de estatísticas
e, por enquanto, vou
copiá-los
para nossa definição de
estatísticas Vou remover
todo esse código setter. Porque queremos
apenas definir propriedades editáveis de
exportação que basicamente não executam
nenhum código extra São apenas dados puros que são
salvos essencialmente no
GIDOEditor Portanto, não precisamos estar vivos e queremos um padrão para o HP, o FenciBT HP e o MAX
HP Então, vamos exportar tudo isso na exportação para MaxHP
na exportação para HP Por
aqui, vamos exportar por velocidade
e exportar por tempo de
invencibilidade Talvez você também queira
fazer alguns comentários a eles. Portanto, MaxHP,
integridade máxima para o objeto, HP, integridade inicial para
o objeto atual Ok, e isso será isso. Então, agora precisamos de uma maneira de nossa definição de estatística ser carregada no controlador de estatísticas Você pode colocar uma função de carregamento
na definição de estatísticas, o
que transforma
o recurso em um pouco
mais do que apenas dados de pares Bem, poderíamos colocá-lo
no controlador de estatísticas
e em algum tipo de
método de estatísticas
inicializado onde ele conhece
o tipo de definição de estatísticas
e, em seguida, ele pode
carregar todos os valores de um objeto desse Então, eu vou fazer isso dessa maneira. E isso significa que
precisaremos
criar uma nova função
aqui na parte inferior. Como o controlador
de estatísticas precisará
chamar initialize
na definição de estatísticas de qualquer maneira, porque esse é o
nó que o nó
manipulará quando estiver pronto
para se configurar Então, de qualquer forma,
haveria uma pequena dependência
da definição de estatísticas Então, vou criar a
função, configurar estatísticas, e isso vai usar
uma definição P, que é uma definição de estatística Bem, retorne o tipo void e
deixe-me adicionar algumas linhas aqui. Então, nas estatísticas de configuração,
vamos apenas espelhar a definição nesse nó. O HP máximo será igual
à definição p mxHP. HP será igual
ao ponto de definição p HP. Vamos ver o que mais a velocidade
será igual
à velocidade do ponto de definição p, e o tempo invencível será igual ao ponto de definição
P Invincible
T. Então, agora precisamos fazer
isso quando estiver ponto de definição
P Invincible T. Então, agora precisamos fazer
isso Então, em tempo invencível, adicionaremos o
sublinhado da função pronto e diremos que configuraremos estatísticas
com Então, precisamos exportar uma definição no nó para
que possamos realmente fazer isso. Então, no topo, vamos fazer Export VR Stat
seja uma definição de estatística de tipo Ok. E então usamos
isso assim que estivermos prontos. Portanto, configure estatísticas com
a definição de estatísticas. Isso
carregará todas as estatísticas em nosso valor de tempo de execução. E isso nos permite
personalizar os
valores das estatísticas básicas de nossos personagens usando algo que podemos
configurar no editor. Então, se clicarmos no controlador
Stat, vamos para o canto superior direito Posso criar uma nova
definição de estatística aqui para o nosso Oc. E digamos que o Mx
HP deva ser 40 e 40, e a velocidade seja 25 Então, salvamos isso agora na
pasta onde temos os orcs. Clique na
definição de estatísticas, salve como, e podemos colocá-la na pasta
do inimigo Então, Ok Stats. Parece um
nome perfeito lá. Salve isso. Ok, e essa é a definição do
Ok Stat. Então, quando carregar, ele
será carregado com esses valores assim que
o personagem estiver pronto. Ok, então isso é basicamente
isso para o orc. Agora, eu também quero
copiar essa configuração
de hit box para o esqueleto Então eu vou para o Controle C, vou até o esqueleto,
Controle V, e colo Talvez eu sofra um ataque de
colisão e só vou aumentar
o dano para, digamos, 25 Vamos atribuir as estatísticas
ao controlador de estatísticas, e a forma da colisão
sendo a mesma funciona bem Usa as mesmas camadas de colisão. É uma pedra em mim tentar
acertar o jogador. Então, todo o resto está
configurado e está tudo bem. E então precisamos
configurar o controlador de estatísticas. Então, inicie o controlador aqui,
vá para o topo ou para a direita. E crie uma nova definição
de estatística. Digamos que o esqueleto tenha mais de 50 pontos de vida,
50 de vida, uma velocidade
de 40 está bem Então, clicaremos com o botão direito do mouse em Salvar como e diremos que as
estatísticas do esqueleto pontuam TRS, Agora precisamos fazer
isso para o jogador. Vá até o player, clique
no controlador de estatísticas, vá para o canto superior direito, faça
uma nova definição de estatísticas Agora, aqui eu nos quero
na hora invencível. Digamos que um personagem
seja invencível por 0,2 segundos após ser Daremos ao
personagem uma velocidade base de, digamos, 100 e
o HP máximo tem 100. Acho que vou deixar
isso como o começo. Então, clique com o botão direito
na definição de estatísticas. Salve como e nós o
salvaremos na pasta Player. Playerstt dot TRS, clique em Salvar. E agora,
cada personagem deve ter estatísticas diferentes. A última coisa que precisamos fazer é realmente usar o cronômetro de
invencibilidade Então, no St Controller, precisamos acionar Invincible
com uma chamada de método Então, vamos criar um
conjunto de funções Invincible aqui, que retornará o tipo void E então teremos
uma variável local
para saber se é invencível ou não Portanto, a variável invencível
é um booleano. O
padrão será falso. Se for verdade, o objeto
não pode sofrer danos. Ok, então para que possa ser atingido, queremos dizer
que o personagem está vivo e não invencível Então, estou usando isso com as palavras-chave em
vez do símbolo lógico. Eu acho que isso torna um
pouco mais fácil de ler, em certo sentido. Portanto, se o personagem estiver
vivo e não for invencível, ele poderá ser atingido E queremos que
invencível seja igual a verdadeiro, mas também queremos
iniciar um cronômetro aqui E diremos que isso
é igual a um novo cronômetro, é igual a um ponto novo do cronômetro. E então adicionamos isso como filho
a esse objeto, temporizador de
invencibilidade, e nos
conectaremos ao Então, invincibility timer
dot timeout dot connect
on Invincible Timeout . Então, controle, veja isso e
cole aqui. Função no tempo limite de
invencibilidade. Essa abertura e o vazio. E diremos que
invencível é igual a falso. Ok, agora precisamos iniciar
o cronômetro. Hora da invencibilidade ou início, e diremos que a hora
é a hora invencível Isso deve lidar com a
lógica de saber se
podemos ou não bater porque o personagem
é invencível ou Ok, então para definir invencível, podemos verificar quando o HP está
configurado e, se o HP cair
, queremos acionar
a Mas acho que o que pode deixar
nossa intenção clara é
criar também uma função de sofrer danos nessa definição Então, poderíamos fazer algo
como funcionar, sofrer dano e
passar um dano de P para aqui. Nós marcamos e anulamos, e
isso vai
pegar HP e configurá-lo para P de dano E então queremos definir o
personagem como invencível. Poderíamos até dizer que se o
tempo invencível for maior que 0,0, definiremos Sobre esse objeto. E o HP
, na verdade, será menos igual ao dano aqui, porque
queremos pegar seu
valor atual e atualizá-lo Então, isso ainda vai dizer que o live igual a HP é
maior que zero Se você quiser, você
pode até mesmo fazer get live apenas uma função
que verifica isso, o que também seria bom, em vez de fazer
a configuração anterior. Mas nós já tínhamos isso. Funciona bem.
Nós vamos continuar com isso. Então, agora, sempre que
causamos dano, realmente queremos chamar take damage no controlador de
pilha Então, vamos descobrir onde
estamos causando dano, como se fosse o projétil Ok, então aqui
podemos ver que tudo volta para a caixa Rt. Então, vamos clicar com o botão direito do mouse
e entrar nisso. E em vez de configurar
o HP diretamente, diremos que o
controlador de estatísticas não sofre danos e transferimos o dano P. Então, podemos cortar essa linha
e, na verdade, não precisamos
calcular isso porque
esse cálculo
é
feito automaticamente no controlador de estatísticas Então, isso
ilustra mais ou menos nosso argumento de que, se nosso
controlador de estatísticas sofrer danos, ele pode estar fazendo outras
coisas, como colocar invencível no personagem
porque nosso personagem sofreu porque nosso Não é só porque
mudamos o valor da HP. É especificamente porque recebemos
danos de uma fonte danificada. Ok, então vamos clicar em Play e
ver se tudo se encaixa. Teremos que
sofrer danos de alguns inimigos
e, em seguida, queremos ter certeza que só podemos
sofrer danos uma vez a cada
quarto de segundo. Então, se eu atirar aqui, precisamos de mais alguns
inimigos para que isso funcione. Pode ser até mais fácil se
eu desativar os projéteis. Ok, então eu
vou encontrar esses caras. Eu só deveria ver os
danos ocorrerem uma vez. Ok, 25. Acho que está funcionando. Se eu passar por tudo isso. Só estou vendo danos
surgirem uma vez de cada vez. Para o VLC, com certeza, porém, preciso desligar o
projétil Então, vou deletar
temporariamente a arma de lança da cena aqui. Você não
precisa fazer isso. Só estou demonstrando. Ok, então eu vou caminhar até os inimigos. Ok, então só somos
danificados uma vez. Agora, essa
colisão só ocorre entrar na área Então, se ficarmos em
cima do inimigo, ainda
seremos atingidos apenas uma vez. Está bem? Você pode ver que, embora haja um monte
de caras batendo em nós, só
somos atingidos uma vez cada quarto de
segundo, mais ou menos, desse jeito E nossos personagens já estão prontos, então não podemos ser mais atingidos.
28. Parte 27 Implementando dano periódico para Hitboxes inimigos: Corrija o problema em que a caixa
HIP só pode danificar uma vez após outra área. O HipXTD entra nessa caixa de acerto, mas não quando
persiste dentro dela. Podemos ajustar um cronômetro dentro
da caixa do quadril para D para verificar se a caixa do quadril ainda
está dentro da área, e então podemos continuar causando
danos a ela periodicamente Ok, então, uma vez emitido o hit, eu também posso adicioná-lo às áreas do
trato e ao script Então, digamos que var targets, que será uma matriz de Hurt box two D, que atualmente não
é nada. E diremos que
depois de acertar, acrescentamos os alvos, a área P. Ok, agora precisamos nos conectar
ao sinal esquerdo da área. Então, a área saiu do dot connect. E vamos usar o
retorno de chamada na área saída. Ok. Então, funcione
na área saída. Nós obtemos a área P. Então, queremos verificar
se é uma caixa HIT dois D. Então as áreas do
tipo área dois D. Ok, então verificamos se a área P é Hurt caixa dois D, então
vamos continuar. Agora vamos verificar se o ponto do
alvo tem área P e, em
seguida, vamos
apagá-lo dos alvos Os alvos apagam a área do IP. Ok, agora os alvos
só existirão enquanto a caixa Hurt
do alvo persistir
dentro da área da nossa caixa de acerto Podemos verificar a cada momento se precisamos
danificar o inimigo novamente. Ok, então poderíamos fazer isso
com algo como, digamos que temos um cronômetro
opcional, então em Export var timer timer, e então nos conectaremos
ao sinal de tempo ou tempo Então, timer dot timeout dot Knect e diremos Ok, então vamos colocar essa
chamada de volta aqui, funcionar na hora certa ou TO. Isso retornará vazio e
tentaremos atingir essa área. Portanto, no tempo ou tempo limite
do Target e dos alvos atingimos um ponto em Mt Target Portanto, se os objetos ainda estiverem
na área depois de terem
feito o golpe inicial, depois de cada vez ou período,
eles serão atingidos novamente. Então vamos para Ok e vamos dar uma
olhada na nossa caixa de acerto dois D. Ok, e talvez queiramos
ser um pouco mais claros sobre para que serve
esse cronômetro Então, digamos que isso seja
na verdade um cronômetro de danos, e eu atualizarei a
propriedade quando estiver pronta Ok, agora, para
nosso cronômetro de danos, queremos clicar com o botão direito do mouse no
hipbox two D e adicionar um E diremos que, para isso,
fazemos cerca de 0,25 segundos. Isso será autosrt, e então só precisamos
referenciá-lo no Hip Box two D. Vou renomeá-lo para temporizador de
danos para que os
nomes também coincidam Então clique em Hit Box two. Atribua o cronômetro danificado. Agora isso vai
se conectar ao sinal dentro do script. E para cada objeto ou alvo que estiver na área
quando o cronômetro expirar, ele acionará isso E como essa não
é uma única foto, ela se
repetirá automaticamente. Então, a cada 0,25 segundos, ele continuará
fazendo isso e verificará os alvos
todas as vezes Então isso provavelmente é
bom lá. Só precisamos que o esqueleto
tenha a mesma coisa Vou controlar a cópia C desse cronômetro para o esqueleto E vamos colar
o Control V no Hip box two D. Vamos atribuí-lo no Hit
box dois D e no canto superior direito, atribuir o
cronômetro danificado, salvar e executar Ok, e podemos ver que em
algumas caixas do quadril dois Ds especificamente como o projétil, o
projétil de velocidade, não têm
isso Portanto, precisamos deixar
claro que dizemos: Se o cronômetro estiver danificado, nos
conectamos ao sinal Portanto, isso é opcional,
e eu escrevi um comentário lá para deixar claro
que o cronômetro opcional emite
periodicamente sinais de acerto
nos alvos dentro da área
da caixa do quadril, duas vezes após
um determinado tempo Ok, vamos correr novamente. E vamos ver se um orc pode realmente nos causar dano duas vezes Bem, isso vai ser um pouco difícil com
as lanças lá Vamos desativar a
lança também. Portanto, desative a arma de lança
ou remova-a temporariamente. Vamos voltar para a cena. Ok, e vamos encontrar um orc
para nos prejudicar algumas vezes. Ok, então aqui temos nosso k. Vamos ver quantas vezes
podemos sofrer danos. Sim, definitivamente podemos ser atingidos várias vezes pelo mesmo orc E isso provavelmente é muito rápido, honestamente. Então, vamos
juntar isso. Primeiro, vou controlar Z para adicionar a
arma de lança novamente Vamos até o orc e eu vou definir seu tempo de
peso para 0,5 segundos. E se parecer que
o jogador sofre muito dano quando vários
inimigos se agrupam sobre ele, você ainda pode aumentar o cronômetro de invencibilidade,
para que
o número máximo de acertos
por segundo caia de 5 a 4, dependendo se você
atingir o cronômetro de 0,2 ou
0,25 muito dano quando vários
inimigos se agrupam sobre ele,
você ainda pode aumentar o cronômetro de invencibilidade,
para que
o número máximo de acertos
por segundo caia de 5 a 4,
dependendo se você
atingir o cronômetro de 0,2 ou
0,25 segundos.
No entanto, você deseja ajustar
29. Derrota de jogadores no P28: personagem fica sem HP, precisamos mudar
para o estado de morte, e parte disso também
impedirá que os ataques
continuem E, eventualmente, colocaremos um game over
na tela, mas vamos fazer com que chegue
ao fim do
estado de morte por enquanto. Então, na cena do jogador, temos nosso estado de movimento. Queremos entrar em um estado de morte, e acho que podemos, na verdade
, entrar no cenário organizacional e até mesmo copiar e reutilizar isso Se eu examinar o roteiro do estado de
morte, não
vejo nada sobre
ele que realmente seja um problema,
exceto talvez o trimestre
aqui no final. Talvez queiramos apenas notificar um sistema de jogo de que o
personagem foi derrotado. Então, vou apenas copiar o roteiro. Vamos até o jogador. Vou clicar aqui e adicionar um novo nó de estado do Limbo Digamos que o jogador derrotou o estado. Então, jogador derrotado, clique com
o botão direito do mouse, anexe um script
e, em seguida, o criaremos
na pasta do jogador.
Vou colar isso. Vamos renomear o nome da
classe aqui
para o estado de jogador derrotado Ok, vamos verificar o nome
da animação e garantir que ela esteja no player de animação. Então, a morte do jogador de animação, nós temos isso aí.
Ok, então está tudo bem. Se entrarmos no estado de morte, então vamos querer adicionar uma faixa chamada
Method Track
ao nosso estado de
jogador derrotado. E se formos até o final aqui, vamos habilitar o encaixe
no canto inferior direito
também, se isso ajudar Então, ajuste para 0,6
e, em seguida, clique com o botão direito do mouse
e classifique uma chave, e chamaremos de concluído
no script Ok, então estou tentado a usar o sistema de
combate já existente e depois fazer algo como denunciar a
derrota do jogador A derrota do jogador é mais uma de reiniciar o jogo ou
anunciar o fim do jogo Portanto, não é realmente uma função
do sistema de combate. Então, para
separar as preocupações,
posso, na verdade, criar um novo nó para lidar com o gerenciamento de
jogos, e isso também pode
incluir salvar e carregar. Vamos ver. Então, se
formos até a raiz do nosso projeto e sistemas, eu
gostaria de criá-los aqui. Vou clicar com o botão direito do mouse e
criar um novo
script, digamos , que
chamaremos de gerenciador de jogos dot gD. Acho que isso funciona como um nome. OK. E no gerenciador de jogos, vamos deixá-lo como um nó
porque vamos torná-lo um Singleton de carregamento
automático Por que não usamos um relatório de
funções no final do jogo, para que ele possa ser chamado de qualquer lugar, desde que façamos
referência ao gerente do jogo. E quando denunciarmos o
fim do jogo, vamos apenas imprimir, que imprimirá
sequências de caracteres no console,
e diremos que o jogador foi derrotado no
fim do jogo Posteriormente, substituiríamos
isso pela interface de usuário para que pudéssemos realmente mudar para um novo jogo ou ver as
estatísticas do fim do jogo, etc Mas isso pelo menos
mostrará que está funcionando. Ok, então queremos pegar
o gerente do jogo e criar uma cena para que possamos editar as variáveis de
exportação se
precisarmos delas. Então eu vou escrever
clicando em Sistemas, criar uma nova cena. Este será o
gerenciador de jogos dot TSCn. Vou clicar com o botão direito do mouse aqui, alterar o tipo de nó para um nó. Vamos arrastar o script do
gerenciador de jogos para ele. OK. E então
queremos salvá-lo, vá para Configurações do projeto. Dentro do Globals,
queremos
carregar automaticamente o anúncio dot TCN do
gerenciador de jogos de sistemas, e agora ele é um símbolo de gerenciador de jogos
referenciável globalmente referenciável Então, se quisermos usar isso, podemos simplesmente voltar
para o estado
do jogador derrotado e terminar. Em vez de ficarmos na fila livre,
deixaremos o personagem lá. E vamos dizer que o gerente de jogo
não reporta o fim do jogo, e isso é tudo o que precisamos fazer. Um motivo para não
remover o jogador
da cena é que, do jeito que as
coisas estão agora, todos os inimigos
dependem da existência
do jogador para que
ele possa continuar se movendo. Então, assim que você remover
o jogador da cena, todos os scripts inimigos começarão a ser
quebrados. Agora, se você quiser detalhar isso
completamente e permitir que o personagem seja removido da cena do jogo, basta verificar basicamente cada sequência,
digamos, da cena de perseguição aqui. Você só
precisa se certificar de que o alvo ainda é válido
e, se não for
válido, basta retornar. Então, isso pode ser
algo como se o alvo do
sublinhado fosse igual a nulo, então você retorna, e isso significa que
ele simplesmente não se move Então, você sabe, para nos divertir,
poderíamos realmente ir até o jogador e no estado de
jogador derrotado. Na verdade, podemos adicionar
o agente dot q free e ver
como isso funcionaria. Então, se eu adicionar
essa verificação de que Targets Not null para
a cena de perseguição, ela
vai quebrar ou vai funcionar aqui? Então, vamos tentar. Vamos ver se nossos inimigos ainda
conseguem continuar funcionando sem nenhum jogador na tela. Ok, então vamos
ser derrotados. Na verdade, ainda não configurei a transição para o player HSM Então, no player HSM, vamos criar outra
função, configurar as transições OK. Então, isso exigirá que adicionemos uma transição do estado de movimento para o
estado derrotado, e isso acontecerá
no evento derrotado. Ok, então vamos
defini-los aqui para o jogador HSM no estado
export var move,
que é um estado de limbo no estado derrotado de
export var,
que é um estado de limbo E então criaremos uma
constante para defeated, que
será um nome de string igual a e aspas Ok, agora precisamos atualizar nossos nomes de variáveis aqui
para adicionar a transição. Então, um invólucro de cobra para
essas variáveis. E só devemos ser capazes de passar do movimento
para
derrotá-lo , na verdade, porque não
temos nenhuma
mecânica de ressurreição no Então, uma vez derrotados,
os jogos terminam, e tudo ficará bem. Você sempre pode
adicionar uma transição volta se tiver alguma
forma de ressuscitar. Agora, queremos chamar as transições de
configuração
dentro do HSM de configuração, configurar as transições lá e podemos lidar com
a transição
conectando-nos ao sinal de estatísticas do
player Então, depois de afirmar que
os jogadores não são nulos, queremos nos conectar ao
sinal no player Então esse realmente será
o sinal
no controlador de estatísticas Ele pode referenciar
diretamente o controlador SAT ou
conectar-se ao controlador de estatísticas por meio do player, embora ainda
não tenha essa configuração Então, acho que, neste caso, seria um pouco mais direto apenas
referenciar um extra em Exportar estatísticas de VR do
controlador de estatísticas. Ok, e aqui embaixo diremos que stats Alive mudou dot Connect, e estará em Alive alterado Então, vamos criar essa função
na parte inferior e retornar a chamada. E isso
terá o valor P, o novo valor do live. O retorno S é nulo. Então, se o valor P for igual a falso, então queremos despachar
o evento derrotado Ok, então isso
resolverá
o acionamento da transição do estado de movimento para o estado derrotado se
estivermos no estado de movimento Se você acabar adicionando
vários outros estados, também
há a opção
de fazer qualquer estado aqui. Então, isso fará com que,
se os personagens
forem derrotados, de qualquer
estado, você possa simplesmente fazer transição diretamente
para o estado derrotado. Na verdade, isso pode
ser preferível pensar a longo prazo, porque talvez você adicione algum tipo de estado de
ataque
em que reproduza
uma animação diferente Você ainda gostaria de poder passar
imediatamente para derrotado em vez de simplesmente passar de movimento
para derrotado quando esse
despacho ocorrer Caso contrário, se você despachar quando o personagem
não estiver no estado de movimento, talvez ele nunca vá
para o estado de morte Então, acho que essa
geralmente seria a maneira
preferível de fazer isso Ok, agora precisamos atribuir tudo no inspetor Então, atribua o controlador de estatísticas, atribua o estado de movimento e atribua o derrotado
30. P29 Testando e Aprimorando o Comportamento na derrota de um Jogador: Para tornar isso mais rápido, vou clicar
em Stats Controller Vamos pegar o HP e configurá-lo
para dez, e eu aperto play. Então, se nosso personagem
for atingido uma vez, mudaremos imediatamente
para o estado de morte. Ok, então vamos encontrar um orc. Ok, vamos lá. Ok, então
chegamos ao estado derrotado. Mas podemos ver que o
agente não tem estatísticas porque não exigimos
isso do personagem. Então, se
quisermos apenas ser consistentes, então sim, podemos adicionar
estatísticas ao jogador. Acho que não há problema em referenciar
estatísticas por meio do jogador porque geralmente entendemos que
o jogador terá estatísticas, especialmente em um tipo de jogo de
RPG Além disso, podemos eliminar essa variável de
velocidade aqui. Pode ver que o
jogador ainda está usando a velocidade do script básico em vez
da velocidade das estatísticas. Então, sim, vamos obter uma referência
em Export var stats, que é um controlador de estatísticas OK. E então, quando
temos velocidade, queremos usar estatísticas de velocidade por pontos. Está bem? E vamos copiar isso e substituí-lo lá
embaixo também. Então, use-o de forma consistente em nosso processo físico
para o jogador. Está bem? Se atribuirmos as
estatísticas e o inspetor, podemos fazer isso ali mesmo E então, se olharmos para o HSM, não
precisamos mais de uma referência
direta
às estatísticas porque já as
temos por meio do player Assim, podemos alterar
player.stats.ai
e nos conectaremos à transmissão alterada por meio disso e nos conectaremos à Portanto, basta ser um
pouco mais consistente sobre como fazemos as coisas
em nossos scripts, embora ambas as opções, é
claro, funcionem, seja diretamente no controlador de estatísticas ou
por meio do player Então, vamos entrar no modo de jogo e fazer com que um personagem
seja derrotado aqui. Então, os personagens foram removidos, e o que vai acontecer
é que, quando novos personagens criarem novos NPCs, afirmamos que o jogador alvo precisa existir, mas
ele não Ok, então, na verdade,
vamos
remover essa afirmação
porque podemos personagem apareça no mundo
do jogo e
não ter um alvo Então, se for nulo, acho que ainda
pode funcionar E então
não haverá alvo porque o
personagem já está morto. E então entramos aqui. Quando o alvo é nulo, não
fazemos nada para o estado Chase.
Então eu vou clicar em play. Ok, então tem isso. Os
inimigos meio que param. Sim. Ok, então você pode ver
que está tentando atribuir uma instância
liberada anteriormente Então, o que precisamos aqui
é de mais uma verificação. Diremos que I agent dot target dot player não é igual a null,
então vamos atribuí-lo Ok, isso parece estar bom agora. Sem mais erros.
Agora, os personagens ainda
estão funcionando. Então, podemos até mesmo colocar
os inimigos
em um estado ocioso se quisermos que
seja um pouco mais crível, porque
eles terminaram seu trabalho, então agora eles estão apenas Então, o que realmente poderíamos
fazer aqui no Update é enviar um evento Digamos que esse seja
o evento ocioso. Ok, então vamos despachar o Idol do
estado de Chase, Então, agora, se formos para o Ok Enemy HSM, queremos adicionar uma transição do estado Chase
para um estado ocioso Então, digamos que adicione transição. Do estado de Chase ao estado ocioso. E isso será
no evento Idle. Ok, então precisamos de um estado ocioso. Então eu vou fazer em Export
var Idle state, que é um estado Limbo Vamos clicar com o botão direito do mouse em Adicionar em um
novo estado Limbo do nó secundário. Ok, e isso vai ser muito parecido com
o estado de morte. Vou entrar no
Death State e copiar tudo aqui para
o novo estado do limbo Então, esse
será o estado ocioso aqui. Clique com o botão direito, anexe um
script, Idol State. E vamos controlar a pasta
V em apenas renomear esse estado inativo Se eu fosse
criar mais estados, provavelmente começaria a
pensar em criar um
estado básico de animação neste momento. Mas, na verdade,
não é muito código. Estamos duplicando aqui, então não
é realmente um grande problema. E essa é a
maneira mais simples de lidar com isso. Pelo menos falando a curto prazo. Ok, então com o AlpiPasted
for the Idol state, eu só quero renomear a animação aqui para A animação já é
reproduzida no Blackboard. Queremos parar com essa
parte sobre fazer com que
o agente não esteja mais
vivo, porque isso não é verdade. Basicamente, é só isso.
Temos uma animação. Recebemos a reprodução
da animação no Blackboard
e, quando entramos,
reproduzimos a animação E a animação
está ociosa aqui. Então, agora no Enemy HSM, queremos apenas atribuir
o estado ocioso Além disso, isso deve
lidar com a transição. Queremos fazer a transição para
o estado de
morte e mudar
isso para qualquer estado. Então, quer os personagens estejam
ociosos ou perseguindo, podemos fazer a transição para a morte se o evento da morte ocorrer.
Isso é importante. E então só queremos
ter certeza de que
copiamos o estado ocioso para
o esqueleto Cole-o aqui e
atribua-o ao HSM inimigo. Portanto, atribua à
direita, estado ocioso. Além disso,
deve ser bom. Então, vou clicar em
play e
veremos se conseguimos derrotar nosso
personagem. Ok, então vamos
lá. Nosso personagem mudou para o
ídolo e pronto Então, eles não precisam mais de um alvo. Eles não estão mais
perseguindo um alvo. Eles estão apenas ociosos
em seu estado ocioso.
31. L30 Criando uma cena Pickup2D: Agora vamos começar a
criar captadores de
EXP para que
nosso jogador possa ganhar
pontos de experiência e subir de nível Portanto, haverá algumas etapas
envolvidas nisso. A primeira será
criar nosso script básico de coleta,
um script de coletor de coleta, um script de coletor de coleta, e depois garantir
que nosso personagem possa realmente
adquiri-los e, em seguida atribuir o aumento de XP à experiência atual do
jogador Então, vamos começar criando a verdadeira pickup mundial do game two
D. Então, vou criar
uma nova nota aqui. Vamos usar duas cenas D, e eu vou
renomeá-las para pegar duas D. Tudo
bem, clique com o botão direito nela, e vamos mudar o
tipo para ser uma base da Área dois D. E agora, se clicarmos no botão de script em
anexo, obteremos uma captura
dois D que estende a
Área dois D.
Digamos a pasta Objetos, e então eu vou criar uma nova
pasta dentro Vamos chamá-lo de pickups. Então eu posso salvar o
captador abaixo do quadrado dois pontos D GD dentro
daqui, criar E na parte superior,
vamos dar a ela o nome da classe pickup two D. Vamos salvar isso nas captações
da pasta Objetos Pickup tdt TACN. Então
guarde isso aí. Então, esse será um nó
físico mundial que representa um objeto geral
que pode ser
captado e aplicado a um personagem de uma
forma ou de outra. Então, isso pode significar aplicá-lo
diretamente
às estatísticas ou, em
outras circunstâncias, pode
significar que você o
pega e adiciona ao inventário de um
personagem. Não teremos um
inventário para o jogo, mas poderemos adicionar níveis ao
carregamento armas ou criar
um novo carregamento de armas para
um novo tipo de arma Para pegar dois
D, queremos criar
uma função T para que possamos tirar o objeto do mapa do jogo e aplicá-lo aos personagens Então, digamos que a função Tr take, que precisará de um alvo. Portanto, o alvo P não é dois D,
e queremos retornar um booleano se isso foi
bem-sucedido ou não Ok, então vou
inserir um erro aqui que diz que é
uma função virtual, implemente um script estendido. Agora, no Gudo 4.5, eles terão classes
abstratas, que torna a configuração mais concreta, pois
adicionam algumas palavras-chave extras para isso Mas como estamos no Gudo 4.4, que é a versão
estável atual, faremos isso da maneira antiga, o que basicamente
significa que precisamos lembrar que, quando estendemos nossa classe
D pickup two, precisamos
substituí-la manualmente por uma nova versão da função Com os mesmos parâmetros
e tipo de retorno. Para TriTek, retornaremos false porque estamos tentando pegar um objeto
nessa classe abstrata, que é o pickup two D. Então, para os diferentes
captadores no mundo do jogo, queremos que todos tenham
sua própria forma personalizada de
se aplicar ao jogador
ou nó se aplicar ao jogador
ou Portanto, precisaremos implementar um script de extensão
personalizado
para cada um deles, L um para EXP e
outro para coleta de armas,
ou pode haver
um captador ou pode haver
um Então, todos eles
funcionarão de forma um pouco diferente, então todos precisam de seu
próprio método tritak Ok, então temos nosso script
Pickup two D aqui. Vamos clicar com o botão direito do mouse e
adicionar um nó secundário. Precisamos de uma forma de colisão. Então, para a forma de colisão aqui, vou até essa
forma no canto superior direito e vamos transformá-la em
um círculo Então, você provavelmente também deseja usar
o sprite padrão aqui. Então, vou clicar com o botão direito
aqui, adicionar um nó filho e queremos obter um sprite Então, para um objeto
que vai
reproduzir apenas uma animação
repetidamente, sem trocar nem nada,
acho que
Sprite two D animado é a
melhor opção Por exemplo, se uma moeda está
girando no mapa repetidamente e
você só quer que ela reproduza automaticamente aquela animação, então o Sprite two
D animado é perfeito para Então, vamos selecionar isso
e clicar em Criar. Agora, para os ícones do jogo, eles podem nem ser
realmente uma animação. Mas se vamos fazer
disso o modelo padrão, quero
abrir isso como uma possibilidade. Então, para o nosso Sprite animado, vamos até a
animação aqui Criaremos um novo
recurso de molduras Sprite e o abriremos. Portanto, temos uma
janela de animação diferente no canto inferior esquerdo. Então, eu poderia simplesmente renomear
isso para Idol, se eu quiser. Vamos entrar na arte. Queremos ver os ícones do
Raven Fantasy e a planilha completa do Sprite, vamos dar uma olhada nisso e ver
se há algo que queremos Então, para acessar isso corretamente
a partir desta janela de animação, há este ícone Ad
frames da Sprite Sheet Então clique aqui. Em seguida,
vá para Art fantasy icons, fall Sprite sheet, 16 por 16 Realmente, você poderia usar um
maior, se quiser. Talvez eu
use apenas o 32 por 32. Então, com um pouco mais de
resolução, abra-a, basta selecionar
os ícones desejados. Ok, agora, para
que isso seja dividido corretamente, precisamos do
número certo de linhas e colunas em nossa planilha de
sprites Ou se você sabe o
tamanho de cada ícone, acho que você pode simplesmente
ir até o tamanho
aqui e colocar 32 30 Sim. Ok, essa é definitivamente
a maneira mais rápida de fazer. Quando você altera um, ele calcula
automaticamente o outro. Então, temos 16 horizontais. Realmente, essas são as colunas
e, em seguida, 128 verticais
são as linhas. Então, em vez de calcular isso, sabemos que cada
um tem 32 por 32. Está bem? Agora podemos facilmente escolher
o ícone que queremos a partir disso. Então você pode usar o que
quiser como EXP Gem, acho que
no projeto de modelo, eu estava usando este aqui Então, meio que uma joia azul.
Nós adicionamos esse único quadro. E isso seria reproduzido automaticamente se verificássemos a
reprodução automática lá embaixo, mas você pode ver que isso nem
precisa ser reproduzido E provavelmente terá um
desempenho um pouco melhor se
desativarmos a reprodução automática Então, está apenas mostrando
esse quadro e não está tentando
nem mesmo repetir nada. Pura suposição da minha parte, mas vamos colocar
isso aí E esse será nosso
pico padrão para o Pickup two D. Então, para o nó raiz do Pickup
two D, provavelmente também queremos
configurar as Então, acho que não temos uma camada
específica para captadores. Então, vamos adicionar uma
nova camada de colisão. Basta fazer a camada
cinco e dizer captadores. Ok, perto. E então
queremos, é claro, colocar o captador na camada cinco e desligar a máscara Vamos desligar o
monitoramento porque isso será
detectado por alguma coisa. Não é monitoramento de captações. Ele permite que o jogador que está pegando o objeto
faça a detecção Então, isso é apenas monitorar
uma tigela com a camada cinco. E essa é a
cena base da nossa picape.
32. L31 Como implementar um sistema de captação de experiência com herança: O que podemos fazer
no canto inferior esquerdo é procurar a coleta novamente. Isso deve mostrar
a pasta de pickups, e queremos
clicar com o botão direito do mouse em Pickup two D e fazer uma cena
herdada Então, isso está no topo aqui,
nova cena herdada, o que significa que estamos criando uma nova cena
com base nessa cena, então ela herda todos os mesmos
padrões Então, criamos essa nova cena, e você verá que alguns
desses nós ficam laranja, o que significa que eles são na verdade, baseados na cena principal. Você pode entrar em contato com o pai
clicando aqui. Assim, você pode ter
cenas dentro de cenas. E queremos renomear o nó
raiz para, digamos EXP pickup two D. Porque queremos ser específicos
sobre o que estamos E vamos salvar isso
como uma nova cena. Então XP pickup tod
dot TCN, guarde isso. E então vamos clicar com o botão direito
do mouse no nó raiz e
estender esse script. Ok, então isso
vai nos dar nosso script EXP Pickup two D, que se estende da coleta dois D. E então
vamos até o topo e diremos o nome da
classe EXP Pickup two D. Então, queremos
dar uma variável para a quantidade de EXP que
realmente vamos obter
sempre que o personagem usa
Tri take sempre que o personagem usa Então, no Export VR, será um número inteiro, e nós o padronizaremos para um E agora, se olharmos para
o script D pickup two, queremos pegar essa
função e
implementá-la adequadamente em nosso script de
herança Então, vou copiar
isso e
vamos até o
EXP Pickup two D. Vou colá-lo
e
escrever nosso verdadeiro método tri take Portanto, o captador EXP aplicará
a experiência ao alvo se
o alvo
realmente tiver Então, digamos que se ptarget
dot stats for igual a null, retornaremos false
aqui Caso contrário, podemos dizer que var stats é igual a ptarget dot stats E como não
sabemos o que essa
variável de estatísticas realmente significa
no contexto de cada script, vamos atribuir a ela diretamente o hype do
controlador de estatísticas Então, quando a condição for atendida, que esse é um alvo
que tem um bloco de estatísticas, podemos dizer que experiência com pontos de estatísticas
mais experiência é igual a experiência
e, em seguida, retornaremos verdadeiro Então, depois de
adquirirmos a experiência, não
queremos que o captador
possa ser usado novamente, então direi que monitorável
é igual a falso
e, em seguida, avisaremos o objeto. Então, quando você ficar livre,
vai passar algum tempo até que ela seja finalmente
removida da cena Por isso, queremos ter certeza de que nada mais que entrar nele
nesse quadro singular possa acidentalmente captar o captador
EXP Então, estou tornando o monitorável falso aqui para que
nada mais possa detectar Apenas como uma salvaguarda, e então removemos completamente da
cena Então, essa parte
aqui, eu provavelmente quero reutilizá-la
em todas as minhas picapes Vou cortar isso no
captador dois D e, em seguida,
dizer a função remove, que retornará nula, e vou fazer
essa etapa de encerramento Então, agora, se eu
voltar para o EXP pickup, eu apenas chamo remove, que é
proveniente da Portanto, essa função
já está escrita
na classe base e
podemos reutilizá-la aqui Então, tipo, sim,
sempre que implementarmos o banal, se
quisermos refazer isso, podemos simplesmente remover aqui E para que isso
funcione, precisamos adicionar as estatísticas experientes
ao nosso controle de estatísticas Então, no controlador set, vou criar
essa propriedade EXP. Ok, então vamos
ter a experiência de Vara e o solo padronizar
para zero como um número inteiro Ok, e meio que de acordo
com o take damage,
em que chamamos o conjunto invencível separadamente
da configuração do HP, talvez
eu prefira
não criar um setter Em vez de usar a função
e a experiência, daremos uma quantia. Então, o valor P é um número inteiro
e retornaremos vazio aqui. Então, queremos aproveitar a
experiência mais a quantidade de P. E então, para fazer isso,
verifique se há aumento de nível. E também podemos dizer que a
impressão é uma experiência aqui. Então, obteremos a
experiência total coletar itens
do mapa no console. E então, para atualizar o captador de
EXP para isso, quero fazer estatísticas para adicionar
experiência e experiência Ok, então estamos sendo
um pouco mais explícitos. Portanto, essa função implica que
qualquer coisa relacionada à experiência que
precise ser alterada ao adicionar experiência
ocorrerá, o que significa que verificaríamos se
havia um aumento de nível e assim por diante. E eu acho que isso
teria algum benefício. Como se pudéssemos alterar o valor da
experiência sem acionar
ou verificar
automaticamente uma subida de nível, se
precisássemos disso mais tarde Em vez de sempre fazer
isso, não importa o que aconteça, como fizemos com o HP setter, onde ele sempre
atualiza sua vida Ambas as formas de fazer as coisas
são válidas até certo ponto. É mais ou menos sobre como você deseja expressar
sua intenção aqui E você quer esconder o fato de que definir a
experiência
também desencadearia uma subida de nível ao colocá-la em um criador de
experiências, ou você quer
ser mais explícito
com a função de adicionar experiência
33. L32 Configurando o Collector2D e corrigindo animações do player: Para colocar a experiência em nosso controlador
de estatísticas a partir do Pickup two D, precisamos do nosso nó coletor
two D, que coletará
captadores para captadores Então, vamos para a cena do jogador. Vou clicar com o botão direito no player. Adicionamos um nó secundário. Vamos procurar uma Área dois
D. Então, essa área dois D, eu vou renomeá-la
aqui para ser coletor dois D. E então vamos
clicar com o botão direito do mouse em anexar um script Então, o roteiro vai
ser em personagens, então eu vou realmente
colocá-lo em personagens. Pode haver um caso
em que realmente façamos com que um inimigo consiga
pegar objetos, mas não quero que seja
totalmente específico para um jogador. Então, vou colocar o roteiro lá. Vamos criar.
Em seguida, no canto superior esquerdo, daremos a ela o nome de
classe collector two D. O que nos
importa com a área
coletora dois D é quando um captador
entra no espaço Então, diremos que a função underscore ready retornará void, e diremos que a área inserida
dot connect na área inserida Em seguida, criaremos a função de
retorno de chamada. O sublinhado na área inserida receberá uma área P, área dois D como parâmetro
e retornará Portanto, se a área P for um captador de dois D, faremos com que o ponto
Tri da área P pegue em nosso nó raiz Portanto, nosso nó raiz é nosso jogador. Poderíamos exportar nosso nó
raiz aqui na raiz do objeto de
exportação é o
nó dois D, eu suponho. E então enviaremos
essa raiz do objeto aqui. Como o objeto TriTek, aquele
pelo qual queremos passar Agora, em nosso inspetor, assine o jogador aqui, e isso pode realmente
ser tudo o que precisamos Então, vamos adicionar uma cópia do nosso captador EXP ao mundo
do jogo Vamos colocar alguns, na verdade.
Então, vou clicar com o botão direito do mouse em Mundo. Vamos criar um nó dois D.
Vou renomear esses captadores e depois adicionarei alguns
captadores ao mundo do jogo Então, um, dois, três, e depois vou
colocar tudo isso no pai da picape Podemos ver que
são bem grandes. Por
enquanto, tudo bem, mas provavelmente
vamos reduzi-los
pelo resto do jogo. Então, antes
que eles funcionem, lembro que não
configuramos o colisor no player Para o coletor dois D,
clique com o botão direito do mouse em um nó filho e queremos a
forma de colisão dois D Então, à direita, adicione uma nova forma de círculo e reduza-a para talvez
exatamente ali, um pouco maior do que a forma
normal de colisão Vá até o coletor TD e
pegue a colisão. Vamos mascarar a camada de
captação e depois
desativar a camada de máscara um mundo e a camada de
colisão um Esse deve ser um script somente de
monitoramento. E acabei de
notar que essas molduras brilhantes
têm
tamanhos diferentes para nossas animações, elas não estão alinhadas corretamente
no centro Tipo, o ídolo parece bom, mas correr talvez esteja um
pixel para a direita, e então a morte também está um pouco
incorreta Então, uma maneira de corrigir isso para garantir que estejam
todos corretos é
atribuir uma propriedade de posição
a cada um dos SprikeFrames, o que parece que eu
já fiz aqui para a Portanto, Idle tem seu próprio valor. Deixe-me ver o que acontece se eu realmente remover essas propriedades de
posição. Então faça isso para o Death
Idol e fuja, ok? Em seguida, também
o removeremos para reinicialização, se estiver lá. Ok, então, sim,
parece precisamos personalizar isso novamente. OK. Então, vamos
começar com a corrida. Vou posicioná-lo
aqui em menos
30 e enquadrá-lo
nessa animação Vamos para Idle. Vou
pressionar W e mover isso para baixo. Então, é mais
ou menos 13 e o quadro-chave. Ok,
vamos correr. Vamos para Idle. Parece que o Idle
ainda está com um pixel de altura, então vou movê-lo
para menos 14, no quadro-chave Acho que era isso que
tínhamos antes, mas também vou fazer a
corrida e movê-la para a esquerda e enquadrá-la. Então, agora, se alternarmos
entre ocioso e executado. Ok, isso realmente
parece correto agora. Vamos morrer
e movê-lo
aqui para a direita
e enquadrá-lo. Então, são dez pixels
para a direita. E agora passamos para o modo inativo. Ok, a morte é um pixel
à direita a mais. Então, isso precisa ir para
menos nove, quadro-chave. Então, temos ociosidade. Ok,
então precisamos colocar mais
dois pixels para a esquerda para a morte e enquadrá-la. Então isso é um oito, e então
o inativo é zero para X. Ok, tudo isso
parece que está se alinhando OK. Então, aqui estão
os valores reais. Oito menos 14 pela morte. O ídolo é zero menos 14. A corrida é menos um
e menos 30. E então o reset, que
deve corresponder ao ídolo, que é zero, menos 14 Portanto, o reset
diminuirá para menos 14. O negativo 14 está
aí, Keyframe it. Ok, e isso deve resolver
todos os problemas de animação que estamos tendo com
essas planilhas de sprites Ok, agora de volta ao coletor
dois D. Certifique-se de
desligar a camada um e a máscara
da camada um também Ok, e agora podemos clicar em
play e ver se podemos realmente pegar
esses pequenos ícones. Então nós pegamos esse. Vamos verificar a saída. Conseguimos a experiência? Sim, nós fizemos. Temos uma experiência
lá. Vamos descer até aqui. Temos a experiência dois. Agora, essa experiência é três, para que possamos confirmar que
nossos captadores estão funcionando com base na
saída do console E nosso personagem foi
derrotado em segundo plano. Mas isso é bom,
isso mostra que esse sistema de game over também estava
funcionando.
34. L33 Criação de mecânica de solta de inimigo e redimensionamento de captadores: Nossas picapes. Agora,
queremos garantir que os inimigos realmente os derrubem
quando forem derrotados. Provavelmente também
queremos redimensionar rapidamente o captador dois D porque ele tem o
dobro do tamanho do nosso player neste momento Então, no EXP pickup two D, posso mudar
o sprite animado para a versão 16 por 16, que é conveniente porque já
temos isso, ou posso pegar o nó
e reduzi-lo Então eu posso fazer isso como 0,50 0,5. E então essa seria uma
forma de fazê-lo encolher. Mas se já sabemos que o tamanho não será
consistente em nosso jogo, talvez
faça mais sentido
entrar na cena base
de pegar dois D trocar o sprite animado E então adicionamos o mesmo ícone, mas do pacote de 16 por 16. Então, entre na folha
Sprite completa dos ícones de arte, 16 por 16. Dimensione como 16 por 16 porque essa é a folha de sprite
menor E então controlaremos o rolo
de mouse de metal, aumentaremos o zoom, encontraremos o sprite, adicionaremos e removeremos o grande Então selecione zero e exclua isso, e então ele descerá para o
quadro zero. Guarde isso. E então, nessa cena,
você também pode salvá-la, e ela deve ser boa para a visão
de mundo Ok, agora é o tamanho
apropriado. Ok, então vamos
entrar na cena dos orcs e adicionaremos a
habilidade de soltar itens Então, aqui, queremos um
script que manipule itens que
podemos colocar no jogo, e talvez queiramos
selecionar aleatoriamente de uma lista de itens, e podemos pesá-los
da mesma forma
que fizemos quando esperávamos a aparição
do inimigo. Então, vou clicar com
o botão direito do mouse no estado de morte, pois isso
estará diretamente ligado ao estado de morte no sentido de que
soltamos itens após a morte, e adicionarei um nó filho. Então, faça um nó regular aqui. Em seguida, vamos renomear isso para
algo como drops. Clique com o botão direito, adicione um script
e, em seguida, aqui,
vamos criá-lo. Então, daremos a ela o nome da
classe drops. Então, daremos a ela o nome da
classe drops. Ok, e em nosso script de descarte, vamos querer basicamente uma lista de itens que podemos descartar. Então, digamos que, no Export VR, usaremos as definições de drop, e essa será uma matriz
de definições de drop. Então, seguindo o
mesmo padrão de antes, onde temos um recurso
definido pelo editor,
podemos repetir isso novamente, então, no sistema de arquivos,
vamos querer
ir a algum lugar como a pasta
de coleta de objetos, clicar com
o botão direito do mouse e
criar um novo script E vou chamar
isso de definição de queda. E isso se estenderá a partir do
recurso. Crie isso. Agora podemos abrir a definição de
drop, dar a ela o
nome de classe drop definition. E vamos querer
uma cena de Export VR, que é uma cena lotada. Então, o que estamos
colocando no mundo do jogo, a entrega real do item Então, como é uma cena lotada
, pode realmente ser qualquer coisa que tenha um nó em sua raiz. Você poderia derrubar inimigos
se quisesse. Portanto, essa embalagem apenas a
torna flexível. Ok, e depois
queremos um peso. Portanto, o peso da barra de exportação está flutuando. Vamos padronizar isso para 0,1, e esse é um começo decente. Então, entraremos no script de
descarte novamente e teremos nossa matriz de definições de descarte para que
possamos clicar em descartar. E se você não consegue ver a matriz aqui e o
inspetor aqui, basta ir ao Projeto
e recarregar o Ok, agora se você
verificar o inspetor, ele deve aparecer lá,
desde que você não
tenha nenhum erro Então, criaremos nossa
primeira definição de gota. Então, nova definição de queda, e podemos fazer dela uma
academia EXP com um peso de um, se quisermos. Carga tão rápida. E vamos procurar
o captador EXP dois D enter, e isso configura isso Então, nosso orc
só
conseguirá soltar as joias de EXP, e isso é perfeitamente bom
para nosso Então, se quisermos funcionar, podemos
invocar nosso estado de morte ou nossa animação que
seria capaz de gerar as
quedas no mundo do jogo. Então, poderíamos dizer que a função
drop se você quiser, você pode passar várias vezes aqui,
como P vezes é um
número inteiro, e isso pode ser padronizado para um, e isso retornará void Então, poderíamos dizer quatro vezes no
intervalo de zero a P vezes,
incrementando em um a cada vez Então isso significa que começamos do zero, subimos uma vez até
chegarmos a P vezes. Então, se P vezes for um, isso será executado uma vez
porque fará zero
e, em seguida, atingirá
P vezes e parará. Então, vamos fazer o cólon lá. Ok, e depois de
fazer o loop, precisamos gerar
uma queda a cada vez. Portanto, provavelmente
seria melhor calcular o peso total uma vez e depois
usá-lo aqui. Então, vamos gerar o peso. Então, antes de gerarmos as quedas, vamos dizer quatro definições de DF e
drop Vamos acumular
o peso total, então precisamos de uma
variável acima disso Até agora, o peso total, há um flutuador que
começa em zero, zero, e esse
será o peso total mais
igual ao peso do ponto DF.
Está bem? Então nós temos isso. Agora, dentro desses quatro circuitos na parte inferior, estamos
passando por eles todas as vezes. Queremos obter nosso peso
selecionado entre zero e
o peso total. Então, está meio que repetindo
a mesma lógica outras randomizações que
fizemos neste curso Então, digamos que o peso
selecionado de var seja igual a rand F, que é 00-1 0,0, e multiplicaremos esse
valor pelo nosso peso total, que
nos dará Então, agora, para cada uma das quedas para definição nas definições de
gota, adicionaremos o peso até agora. Até agora, o peso atual, que é flutuante
e começa em zero,
zero, diremos que o peso atual mais
é igual ao peso Ok, então isso nos dá
o que estamos fazendo até agora. Se for maior que
o peso selecionado
, queremos retornar essa gota ou adicioná-la a uma matriz de gotas. Portanto, se o peso atual for maior ou igual
ao peso selecionado, esse é o que queremos
acrescentar a uma matriz Então, vamos criar uma matriz
aqui acima do loop de quatro, e vamos dizer que var drops é
uma matriz de definição de queda. Agora, o principal aqui é que isso pode ter várias cópias da mesma definição de descarte. É uma matriz, não
algo como um conjunto de hash. Portanto, podemos ter a mesma queda duas ou três vezes, se necessário,
o que é importante. Digamos que drops dot
acrescente a definição, e então saímos
desse loop de quatro, e então ele voltará aqui Então, quando chegamos ao ponto em que
o peso atual é igual ou maior que
o peso selecionado, escolhemos a gota e
fazemos um loop novamente cada vez que precisamos
para essa configuração de queda. Agora temos todos
os itens suspensos aqui, então queremos
instanciá-los no mundo do jogo. Então, digamos que quatro gotas em gotas. Vamos criar uma
instância que será igual
a drop dot
seen dot Instantiate E então vamos
adicionar isso quando criança
a algum pai dentro
do nosso mundo de jogos. Então, no mundo, poderíamos simplesmente reutilizar esse
nó de captação, se quisermos Então eu posso pegar picapes. Vamos até o nó
aqui no canto superior direito e adicionarei um novo grupo. Então, vamos dizer pickups. Vou tornar isso global. Então, para qualquer coisa que seja um item a
ser retirado do mundo, vamos adicioná-lo
como seu grupo de nós. Então, quando está em um grupo de nós, é muito fácil encontrá-lo
dentro do nosso script E podemos realmente
obter esse
nó de captação assim que nosso orc for carregado, então saberemos se
há algum problema Então, vamos dizer var pickups parent, e esse será
o nó dois D,
e já diremos a
função underscore e esse será
o nó dois D,
e já diremos a
função underscore
. Deixe-me ampliar aqui. O
pai da coleta será igual a
Gtree dot Obtenha o primeiro
nó no grupo,
e estamos
procurando essas captações.
Portanto, nos grupos Gtree dot Obtenha o primeiro
nó no grupo, de nós aqui nos grupos
de nós do
inspetor,
você pode ver que de nós aqui nos grupos
de nós do as captações já
existe uma,
e ela está atribuída
a esse nó de coleta e ela está atribuída
a esse Portanto, enquanto o nó de
captação existir em nosso mundo de jogo atual,
ele funcionará muito bem Poderíamos dar um pequeno
passo adiante
e transformar isso em uma variável
constante. Então, vamos dizer que
grupo de captação aqui, tudo em maiúsculas, e então grupo de captação constante
é um nome de string igual a, e eu direi e comercial,
Controle V, cole Controle V Portanto, desde que você tenha um nó
no grupo de captadores
para isso e tenha atribuído esse nó
ao grupo dentro do seu projeto de jogo e
ele exista na cena
, isso funcionará
perfeitamente bem Você não precisa obter
nenhuma referência direta, o que seria complicado
porque o orc não existe na cena até ser
gerado Portanto, essa é uma maneira decente de obter
aquele nó pai para o qual podemos criar. Se quisermos ter certeza de que
podemos até mesmo dizer, tipo, afirmar que pickups parent
e não é igual a null, então diremos que deve haver um pai para que os itens
sejam Ok, isso está bem
claro. Ok, então instanciamos cada uma
das cenas e, em seguida,
queremos
adicioná-las como crianças ao pai
da picape Então, pega a mãe de uma criança Stance. E a localização em que queremos que a
entrega esteja
será baseada no
nó dois D. Então na verdade, precisamos pegar as gotas e alterá-las para um
nó dois do tipo D. Então, aqui embaixo, podemos dizer que a
posição global da
instância será igual à
posição global do script. Ok, então isso significa
voltar ao nosso cenário organizacional. Então, agora que queremos
alterar esse tipo de nó, vou clicar com o botão direito do mouse
e alterar o tipo, pesquisar por gotas, e
você deve vê-lo aqui. Clique duas vezes. Ok,
clique em Drops. Certifique-se de que, no
inspetor, você ainda tenha sua definição de descarte
para o EXPJM lá E provavelmente precisamos
tirar isso dos nós
do HSM aqui Como esse é um nó dois D, queremos que seja filho
do nosso nó principal dois D, então vou trazer isso
aqui como filho do trabalho. E isso
provavelmente deve ser bom. Então, temos o item ou qualquer outra coisa que estamos lançando
no mundo do jogo Ele se torna filho do nó
do grupo de captadores
e, em seguida, atribuímos a ele a
posição desse nó de descartes, que é apenas um deslocamento,
se houver, da posição dos orcs Não precisamos
alterá-lo, mas poderíamos simplesmente ter um padrão como zero, zero
aí. Tudo bem. E agora podemos
chamar quedas da animação
da morte
ou do estado da morte. Então, se eu for até o player de
animação aqui e abrirmos a
animação da morte, vamos ver. Estado de morte. Então, vamos ver. Estamos chamando de estado de morte
acabado. Poderíamos simplesmente colocar as gotas assim que o orc começar a morrer Acho que essa pode ser mais
a forma como a maioria dos jogos acontece,
em que você vê o loop
antes que eles saiam em que você vê o loop da cena Então, em uma faixa, chame o
método no nó de descarte. Então, aqui embaixo, no primeiro
quadro. Vamos ampliar. Tudo bem, clique em Inserir
uma chave. Nós fazemos entregas. Você pode ver os parâmetros
funcionarem no reprodutor de animação. Então, no canto superior direito, temos nome do
nosso método drop.
Tenha a discussão. Portanto, o primeiro argumento e o
único argumento é o valor int. Então, quantas vezes
queremos ligar para o Drops? Poderíamos dizer 50 por diversão, e vamos clicar em Play e ver
se isso realmente funciona. Então, isso colocará muitas
dessas joias de EXP em
cena se estiver funcionando, mas pelo menos
definitivamente saberemos se funciona Então, vamos ver o que
acontece. Ok, eu acho que todos eles simplesmente
aparecem no mesmo lugar Então, vou repassar isso. E sim, você pode ver que
pegamos 50 gemas
35. L34 Gerando posições aleatórias de itens: Bem, quando o orc derruba
50 desses itens, eles ficam todos empilhados
uns sobre os outros, se eu
verificar a saída Então, temos 50 XP lá. E acho que o que
gostaríamos de fazer é que, quando o objeto aparecer, façamos
um deslocamento ou façamos com que ele se afaste do Está caindo um pouco. Então, acho que a
maneira mais rápida de fazer isso seria gerar uma posição de
deslocamento aleatória, e isso estará a um
certo número de pixels de distância do personagem
em uma direção aleatória Então, podemos simplesmente adicionar isso
ao script drop. No topo, vou
exportar
nossa distância máxima de queda,
que será um flutuador E vamos usar dez
pixels por padrão. Isso representará a
distância do nó de descarte. Esse é um
nó específico em que estamos trabalhando, no qual o
objeto pode aparecer, e essa é uma quantidade máxima, então pode ter de 0 a 10
pixels Então, aqui embaixo,
vou criar uma nova função. Vou chamá-lo de function, underscore, get span, offset E isso passará
em uma distância P max, que é uma flutuação, e podemos
padronizar isso para a distância máxima de
queda. Portanto, não precisamos
passar um parâmetro. Pode ser que seja isso por padrão. E então queremos retornar
ao vetor dois como o deslocamento. Então, para obter um deslocamento final,
precisamos da direção
e, em seguida, da magnitude,
a magnitude está aqui
na distância P max. Então, digamos que a direção
var seja um
tipo inferido do vetor dois, e vamos
criar um novo vetor dois, então coloque-o entre parênteses
aqui, precisamos de um X e um Y.
Então, para obter isso,
basicamente precisamos gerar uma direção aleatória entre
menos um Então, vou dizer rand F, e acho que precisamos de um intervalo
aqui porque queremos
ir menos 1,0,
não zero a um Portanto, o intervalo aleatório de F em
menos 1,0 a 1,0. E então precisamos fazer isso
uma segunda vez para que possamos simplesmente copiar essa linha para
o valor Y até aqui. E então eu quero normalizar o vetor para que
seja uma direção pura Ok, então agora temos nossa compensação. Então, o deslocamento var será igual à direção
vezes a distância P max. E então retornamos o deslocamento,
e é basicamente isso. Então, pegamos Get
spawn offset aqui
e, quando definimos a posição global,
vamos fazer
a posição global mais
GitSpawnOfset O padrão é a distância máxima de
queda, então podemos
usá-la como padrão aqui. Então, na verdade, você não
precisa passar pela distância máxima de queda,
mas você poderia. Então, seria apenas o
valor se sobrepondo. De qualquer forma, será o mesmo, mas você tem a opção
de deixá-lo em branco
e, em seguida, esse valor
será o padrão aqui
embaixo. Acho
que é tudo o que precisamos. Então, vamos entrar no modo de
jogo e ver se esses 50 itens realmente
caem em locais diferentes. Então, vamos clicar em play
e entraremos aqui. Vou atirar uma flecha
ou lança no orc. E podemos ver que todos eles aparecem em direções aleatórias Mas eu realmente cometi um erro. Portanto, não queremos normalizar
o vetor porque quero que a porcentagem da distância
seja capaz de ir de 0 a 100% Ok, então, como eu normalizei o vetor para a direção, ele sempre
fornecerá a distância
máxima total aqui Essa será apenas a direção
pura. Mas o que eu realmente quero é que,
quando tomar essa direção, seja uma porcentagem
da distância. E talvez
queiramos chamar isso mais como um vetor aleatório. E então vamos descer para
compensar aqui e depois disso. Então, quando está tomando o X, ele estará em algum lugar de
0 a 100% da distância no X multiplicado pela distância máxima de P e
o mesmo para o Y. Então, isso dará a
ele uma posição mais aleatória dentro
de um Se você criasse
uma forma de colisão, seria mais ou menos
assim para os possíveis locais de extensão Então, vamos entrar no modo de jogo, e deve estar mais correto agora, quando derrubarmos todos os 50
itens ao mesmo tempo. Então aí está. Eles são todos gerados
aleatoriamente
dentro desse círculo Na verdade, nunca vamos
descartar 50 itens ao mesmo tempo. Então, isso
parece meio estranho. Mas se houver
duas ou três gotas, acho que funcionará muito bem. Então, para demonstrar,
vou até o player de animação
e, quando morrermos,
usarei a
função drops aqui e
mudaremos o valor do argumento de
quantas gotas para algo
mais parecido com três. Acho que isso é mais realista. Vamos clicar em play e depois
entraremos aqui. Na maioria dos casos,
acho que a maioria dos inimigos só vai derrubar um item. Mas se decidirmos
descartar três, então pelo menos podemos ver que eles têm posições
diferentes, e é óbvio
pelo menos ver onde eles estão. Ok, então eu quero
encerrar isso trocando
as gotas por uma. Cada um ou só
aumentará uma EXP.
36. L35 Implementando uma área de gravidade de captação: É um pouco entediante
se o jogador precisar passar por
cima de cada picape que você deseja pegar,
especialmente quando você vai se esquivar de
todos esses inimigos orcs que
se estendem todos esses inimigos orcs que Então, o que queremos adicionar será uma área de gravidade de
captação Então, em nossa cena de jogador, em vez de adicionar
a área de gravidade ao nosso coletor de dois nós D, vou criar um nó
separado de duas áreas D para gravidade especificamente A razão para isso é porque a forma de colisão de dois D
aqui para realmente
pegar os itens será uma área diferente daquela
que está aplicando gravidade Então, isso seria meio
confuso com o
coletor dois D,
tendo duas formas de área aqui Então, vamos
criar um novo nó. Vou clicar com o botão direito do mouse no
jogador para adicionar um nó secundário. Isso seria na área dois D. Vamos adicioná-lo
aqui na parte inferior
e vou renomeá-lo
para, digamos, gravidade de captação dois D, porque isso é especificamente para itens no
mapa que podem ser coletados Ok, então vamos clicar com o botão direito do mouse
no jogador para adicionar um nó filho. Vamos
procurar a área dois D, e eu poderia
chamá-la de algo como gravidade, área dois D. Pensei em
chamá-la de gravidade de captação dois D, mas queremos tornar o script um pouco
mais genérico, porque pode
haver casos no futuro você realmente
queira que a gravidade se aplique
a algo
que não é um captador e lidar com a gravidade específica do captador é gerenciado apenas
pela forma de colisão. Lidar com o fato de
ser para atingir
captadores é gerenciado apenas
pelas camadas de colisão Então, tudo o que você precisa
fazer para que ela atinja os captadores é
escolher a máscara cinco aqui
para a camada de captadores, e vamos desativar a camada um para onde ela existe e
torná-la apenas monitorada Ok, então essa é a nossa configuração. Então, só precisamos,
na área de gravidade aplicá-lo a todos os objetos dentro
daqui que ele detecta. Então, dentro da
área de gravidade, clicaremos com o botão direito do mouse. Antes de deixarmos
o inspetor, porém, se olharmos para esta seção de
gravidade, há uma gravidade D embutida na área
dois, mas o fato é que isso se aplica
ao corpo rígido de dois Ds, que são
objetos físicos completos no jogo, e não queremos 1.000 corpos
rígidos flutuando
pela tela Então, em vez de usar
a física padrão para controlar a
gravidade em nossos captadores, queremos apenas um script
simples façamos com que ele
chegue a em que façamos com que ele
chegue a qualquer lugar onde esteja o centro do
jogador E não lidar com dois Ds de
corpo rígido. Então, essencialmente, é uma otimização
de desempenho. Não precisamos de física completa
para cada um dos nossos itens de coleta. Eles só existem para serem
pegos pelo jogador. Portanto, sugá-los
diretamente para o player é perfeitamente normal Então, vou clicar com o botão direito
em Gravity Area two D e anexaremos um script. Claro, vou chamar
essa área de gravidade dois D. Vamos criar
esse nome de classe. Claro,
área de gravidade dois D. Ok, então enquanto um objeto
está dentro da zona, queremos rastreá-lo e aplicar
consistentemente
um movimento a ele, basicamente traduzindo
outro nó dois D
pela tela em direção ao
ponto central dessa área dois D, a área de gravidade dois D. Então,
vamos ter uma variável local Vou chamá-lo de alvos, e isso será uma matriz
do nó dois D está bem. função estiver pronta, queremos nos conectar
ao sinal
dessa área dois D. Então,
vamos dizer área inserida, ponto conectar, sublinhado na área inserida Também nos conectaremos
à área de saída da área conexão pontual
na área saída Precisamos criar
essas funções agora. Sublinhado da função
na área inserida, e isso nos dará a
área dois D como parâmetro Então, área P área dois D, estamos tentando anular aqui Ok, então o que vamos
fazer com a área aqui? Vamos movê-lo em direção ao ponto central
da
nossa área de gravidade dois
D. Isso vai funcionar bem com o
captador porque as áreas de captação estão na raiz na
área dois D. Então, qualquer coisa abaixo dela se moverá automaticamente em direção
ao centro, então exigimos que tenha esse tipo de Caso contrário, você
precisaria de uma referência ao nó pai da cena. Qualquer que seja a base da sua cena de captura é
o objeto ou nó, em vez disso, que precisa se mover Portanto, esteja ciente disso.
Como estamos fazendo todos os captadores
especificamente dessa forma e os captadores são
exclusivos da camada cinco, funcionará perfeitamente do jeito que Se você quiser ser mais seguro
e quiser limitá-la apenas
aos scripts de coleta
, é claro que você pode verificar se a área P
é do tipo pickup dois D. Não parece ser
necessário, como é agora,
mas é algo que você deve
estar ciente Então, vou colocar
um pequeno comentário lá sobre o que acabei de dizer. Ok, e já que a
área P aumenta assim. Vou funcionar bem do jeito que está. Então, direi que os alvos
pontilham uma caneta, área P. Lembre-se de que a área P área dois
D é do tipo nó dois D, então isso funciona bem aqui. Não há necessidade de ser
mais específico do que isso, porque só precisamos acessar as funções D do nó
dois. Então, na área saída, função, sublinhado na área área P, área dois D, retorna vazia, então
vamos dizer que os alvos apagam a área P. Agora, para observar
a função de apagar, se o objeto que você está
tentando apagar da matriz não existir na matriz,
isso não fará Se ele apagar,
ele o removerá. Portanto, na verdade,
não há necessidade verificar se ele já está
na matriz. Porque se não
existir na matriz, isso já
não fará nada. Portanto, não há necessidade
de verificar novamente. Certo. E então precisamos de
um processo físico. Então, digamos que a função
sublinha o processo físico, e digamos que, para o
alvo nos alvos, queremos
traduzi-lo pela tela direção ao ponto da área de
gravidade central Precisamos de uma velocidade no topo na exportação. A
velocidade da gravidade é um flutuador Se bem me lembro,
isso vai chegar a pixels por segundo. Então, vou tentar algo como 50,0. Em seguida, precisamos
calcular a direção entre o alvo e o ponto central
da nossa área de gravidade. Até agora, a direção será igual
à posição global do
ponto alvo , direção do ponto,
direção do ponto, posição global dois. Está bem? E então só precisamos
calcular nosso valor de movimento. Então, o movimento var será igual à direção vezes gravidade,
velocidade, vezes Delta. Como estamos usando translação, precisamos fatorar
isso diretamente aqui para o vetor de movimento final. Podemos dizer que esse é
um fator dois D, se isso deixar tudo mais claro. E então queremos
pegar o alvo e traduzi-lo pela
tela com o deslocamento do movimento Este é essencialmente o nosso script de
gravidade ali mesmo. A última coisa que acho que
precisamos é adicionar uma forma de colisão à
nossa área de gravidade Então clique com o botão direito na área de
gravidade até D, adicione uma forma de colisão a
D. Vá para o canto superior direito, uma nova forma de círculo
e torne-a bem grande para que tenhamos grande para que tenhamos
a área onde ela
realmente
aplicará a gravidade
em direção ao centro Ok, então eu posso jogar, e vamos entrar aqui
e você pode ver que nossos objetos
são sugados para o centro Então, agora, a
gravidade é linear. Talvez queiramos
fazer uma curva para
que, quanto mais perto ela
chegar do ponto central, mais rápido ela realmente anime essa translação
em direção ao centro Então, se formos para a área de gravidade
dois D, e dentro daqui, direi na exportação, digamos curva de efeito do
tipo curva. Vamos guardar isso. Então, no inspetor, vamos editar essa
curva de efeito, nova curva E então queremos que X ou o domínio
máximo aqui seja basicamente a
distância do centro. E então o valor aqui
será a porcentagem
da velocidade máxima que você deseja
aplicar com base nessa distância. Então, digamos que
a distância seja como 100 aqui para
o domínio máximo. Quanto mais próximo estiver, mais perto
queremos chegar de 1.0. Então, vamos pegar o primeiro ponto
e movê-lo aqui para 1,0. Vou ampliar aqui
para que você possa ver. E então eu vou puxar um
segundo ponto para baixo assim. OK. Então, se
chegar a 100 de distância,
ficará muito
fraco nesse ponto. E isso seria medido
em pixels, é claro. Então, com essa curva, queremos voltar
aqui e ajustar o movimento amostrando essa curva Então, vamos pegar o modificador de curva, que será igual
à amostra de pontos da curva de efeito E precisamos amostrar
com a distância do nosso alvo até o centro de
gravidade. Então, a distância vara
será a posição global do ponto alvo, a distância do
ponto até a posição
global Ok, então
passamos essa distância para a amostragem do
modificador de curva
e, em seguida, pegamos
o modificador de curva e multiplicamos isso Então, esse será um valor
entre 0,0 e um. E isso deve afetar a
gravidade com base nessa curva. Quanto mais perto estiver,
mais forte será. E aqui, fica mais fraco. Sinta-se à vontade para personalizar
uma curva
se precisar alterar um pouco a forma da
animação. Ok, então vou clicar em play aqui e
vamos testar isso. É um pouco difícil de
ver porque talvez eu tenha tornado a
distância máxima aqui muito grande. Então, o que você pode fazer
é verificar a forma da colisão e
ver qual é seu raio Então, 27 pixels. Então, estamos basicamente fazendo uma
curva de até 100 pixels, mas o máximo desse raio
é 54 pixels, 27 aqui Ah, sério, não, não, não, 27 pixels porque é o centro
do ponto externo, certo? Não é o diâmetro, é claro. Sim, talvez eu queira pegar o raio aqui e
torná-lo em 30 pixels, um bom número par, e depois vamos para
a área de gravidade E então vamos pegar
o ponto da curva aqui e movê-lo para
30 pixels também. Ok, então isso será como nossa distância máxima
nesta forma aqui. Não precisa
ser perfeitamente 30. Tipo, mais ou menos aqui, para que possamos ver a forma um pouco melhor. Ok, agora se eu apertar play
e formos até aqui
, deve ser um pouco
mais preciso. Ok, agora você pode
ver a gravidade realmente aumentando
à medida que se aproxima, então é lenta por
fora, quase lenta demais. Então, eu poderia realmente aumentar
isso um pouco, e você pode ajustar a forma da curva puxando
as alças,
o que quer que você precise fazer.
Veja, eu meio que gosto disso. Vamos tocar em play mais uma
vez só para testar. E sim, eu acho que isso é
certo para a gravidade. Então aí está.
Escalando a gravidade Quanto mais perto seu objeto estiver de
ser jogado, mais rápido ele se moverá e absorverá todos os itens
coletados ou, na verdade áreas
que você
marcar na camada da máscara aqui marcar na camada da O que, neste caso,
agora são apenas captadores, mas você pode fazer isso
com outras áreas
37. L36 Como criar uma UI de player com barras de progresso HP e EXP: Ok, então, embora o
combate principal esteja funcionando no jogo, podemos pegar itens
como captadores de EXP, mas não temos nenhuma indicação na interface do usuário
do que está acontecendo Não podemos ver o nível do nosso
personagem, nosso HP, nossa barra de EXP. Então, vamos
começar trabalhando na barra de
EXP e adicionando
um contador de nível, digamos, no canto superior
esquerdo da tela E vamos fazer
isso em um novo nó. Então, vou subir até
a seção intermediária e
adicionar uma nova cena. E queremos que isso
seja uma interface de usuário. Então, vou chamar
esse player de UI. Vamos salvá-lo na
pasta UI. E guarde-o lá. Em seguida, vou clicar
na interface do player
e adicionaremos, digamos, um contêiner de painel. Então, esse
será essencialmente o fundo
da
nossa interface de jogador principal. Agora, você diz que a interface do player se estende por
toda a tela por padrão Então, queremos entrar no
layout à direita
e alterar a predefinição de âncoras de
totalmente destruída Ok, agora, isso
reduzirá o tamanho aqui para basicamente nada E então queremos
fazer o dimensionamento do contêiner, expandir no
preenchimento horizontal e vertical Em seguida, em nosso contêiner de painel, queremos clicar com o botão direito do mouse
e adicionar um novo, digamos, um contêiner de caixa V. Um contêiner VBox organiza
seus filhos verticalmente. Então, se você colocar dois itens aqui, o que está diretamente
abaixo dele ficará em cima do outro em
termos de layout visual. Então, vamos clicar com o botão direito do mouse
no contêiner VBox e agora eu quero um contêiner HBox Portanto, nosso contêiner HBox, o primeiro,
irá da esquerda para a direita, e estará em cima de qualquer outro contêiner
HBox infantil Então, isso nos ajuda
a organizar as
coisas quase como uma
grade, mas não exatamente. Ok, e então, como filhos
do contêiner HBox, queremos adicionar uma barra de progresso de
textura para que você possa pesquisar Progress
e encontrará aqui Isso permite que você,
no canto superior direito, defina texturas para
a textura inferior, a textura superior e
a textura progressiva Assim, à medida que os valores forem preenchidos, ela mostrará mais ou menos da textura de
progresso
e, abaixo dela,
estará a textura base, que sempre aparece em
segundo plano. Ok, e
além disso, queremos um rótulo
à direita disso. Então, vou clicar com o botão direito do mouse no
contêiner HBox e adicionar um rótulo. Um rótulo básico deve
estar bem aqui. Sempre podemos alterá-lo para
um rótulo de rich text posteriormente. Ok, e agora, para essa barra de progresso de
textura, queremos encontrar a
arte da nossa barra de progresso. Então, vamos minimizar tudo
no canto inferior direito e
expandir a pasta de arte. Vamos para a GUI do Crimson Fantasy. E eu acho que foi
sob o GI Sprite aqui. Então, no canto superior direito para baixo, vou criar uma nova
textura de atlas e depois expandi-la E vamos arrastar o GI Sprite
para o atlas aqui. Assim, podemos ver o atlas completo, estilo de arte gótica
muito legal acontecendo aqui E podemos selecionar o que
queremos que seja nossa subtextura. Portanto, a textura
inferior será basicamente nossa barra, onde estará completamente vazia. Então, se eu editar a região, posso ampliar aqui e selecioná-la,
mas aqui, dessa
forma, essa pode ser nossa textura
inferior ao toque de perto. E então, para o
rótulo, digamos que zero em 100 HP por
enquanto, apenas como uma maquete Portanto, agora faz sentido
renomear esse contêiner HBox, algo como o monitor HP E vamos duplicá-lo
e, em seguida, renomearei o
segundo para ser EXP Vá até a barra de progresso da textura. E nas texturas, vamos
selecionar uma diferente na região Editar Então, vamos ver o que
gostamos aqui como barra de EXP? Poderíamos usar esse
básico aqui, mas acho que seria
útil se pudéssemos
ver partes diferentes Então, com este, podemos
ver em sete o quão
perto estamos de realmente subir de nível Mas você notará que, assim que eu alterar o valor
aqui para este, o primeiro também será
atualizado automaticamente porque estamos usando um recurso compartilhado de textura de
atlas Então, o que realmente
temos que fazer aqui,
vou fechar, é clicar com o botão direito do mouse
nessa textura e
, em seguida, torná-la única. Então, quando você fizer isso, essa
textura será única. Precisamos voltar ao
primeiro e corrigi-lo, clicar com o botão
direito
do mouse e, em seguida, criar Exclusivo, e precisamos mudar o HP
de volta para sua textura HP. Então, aqui,
selecionaremos essa barganha da HP e agora podemos ver que essas
são duas coisas distintas Ok, agora vamos também fazer
o preenchimento do primeiro. Vou progredir
aqui, nova textura do Atlas, e então podemos carregar rapidamente, a partir
do menu suspenso,
nosso sprite da GUI E agora queremos editar a região e pegar a barra de saúde
preenchida aqui. Ok, então vai ficar mais ou menos
assim e clique em Fechar. Agora
que temos esse conjunto de texturas, se você acessar, digamos, valor aqui e digitar 50, verá que parte da barra de
saúde agora está preenchida. Mas você também vê que,
com essa configuração, isso pode ser parcialmente porque o coração está escondendo coisas, mas na verdade não
parece que esteja
refletindo com precisão 50% de
sua saúde total aqui quando o valor é 50 Então, para contornar isso,
o que eu estava fazendo
era mudar o valor dos homens algo como menos 20 para algo como menos 20 para compensar isso para
a direita Então, agora você pode ver que há quatro de saúde
visíveis em oito Então, esse valor de 50 faz muito mais sentido quando você tem esse deslocamento negativo de 20 Então, talvez você
precise personalizar isso. Então, obviamente, quando você
caracteriza zero saúde, vai mostrar que zero é o valor que
estará aqui Mas o que realmente importa
é como os 50 de 100 aqui e
os 100 de 100 ali. Então, só para garantir que valemos 100 para uma barra de saúde totalmente preenchida
, e isso parece bom.
Podemos dizer 20. Ainda podemos ver nossa saúde. E mesmo às cinco ou dez, bem, acho que às cinco, não
precisamos ver isso necessariamente. Mas, aos dez anos,
ainda podemos ver uma pequena lasca. Eu acho que, do jeito que está
agora, é muito bom. Então, na verdade, podemos
deixar esse padrão como 50. E vamos trabalhar na textura da tela
EXP. Vamos clicar com o botão direito
na base abaixo da textura aqui, copiar e
clicar com o botão direito do mouse no
progresso vazio e colá-lo. Em seguida, queremos
clicar com o botão direito do mouse aqui e torná-lo único e alterá-lo
para o valor de que precisamos. Então, edite a região, e queremos pegar essa
versão preenchida dessa barra. Está bem? E podemos digitar 50
para o valor do teste. Ok, e então podemos ver que está meio preenchido.
Então, tudo bem. Não precisamos fazer
um valor mínimo negativo nessa versão da textura. Há um pequeno
problema aqui em que
nossa barra de progresso
para o XP está vermelha, assim como a que está no topo. Então, o que realmente
queremos fazer é que essa parte de metal seja
tingida com uma cor diferente Então, como podemos fazer isso é ir
até
a tonalidade de progresso e
alterá-la para mais
verde, mais ou menos assim Mas você pode ver
que isso realmente tinge toda a textura Então, o que queremos fazer é
clicar com o botão direito na textura inferior, controlar a cópia e, em seguida
, colar na textura superior. Ok, agora apenas os pixels que não existem
na parte inferior e superior serão afetados pela alteração da
textura do progresso. Então, seja qual for a cor que você
quiser que o progresso seja, você pode simplesmente alterá-lo para essa simplesmente
manipulando a tonalidade aqui. Pode mudar a
escuridão, e isso
provavelmente é bom o suficiente
para sua barra de XP, para ser honesto, a solução
mais simples sem usar um
sombreador nem nada Então, se formos para o rótulo agora, queremos mudar
isso para dizer EXP. Então, zero em 100 EXP. Ok, e então
queremos
centralizar verticalmente essas barras de
progresso de textura Acho que você pode selecionar
os dois ao mesmo tempo mantendo
a tecla
Control pressionada, clicar com o botão
esquerdo do mouse e seguida, ir para o
tamanho do contêiner de layout e alterá-lo de preenchimento vertical para centro de redução Sim. OK. E então isso
basicamente pega esses e se concentra em relação
aos outros elementos como esse rótulo aqui
à direita . Então, isso vai ficar bem. Então, só
queremos reduzir o texto. Então, o que talvez
queiramos fazer, na verdade, é acessar a interface do jogador
na raiz aqui e alterar o tema se
carregarmos rapidamente do
menu suspenso o tema do nosso jogo. Então, ele terá
aquela fonte de pixel art, que já é por padrão,
um pouco menor. Ok, a última coisa para
finalizar nossa maquete que provavelmente queremos um contêiner de
margem
tão aparente quanto o contêiner do
painel Então, clique com o botão direito nas raízes, interface
do jogador, adicione um contêiner de
margem. Então, pesquise a margem e, em seguida puxe o recipiente do painel por baixo dela. Agora, no contêiner de
margem, você pode acessar as substituições de tema
nas constantes corretas e personalizar Então, vou escolher cinco para
todas as margens de direção. Ok, mais ou menos assim. Então, essa é provavelmente uma margem
suficiente, mas na verdade eu errei
no pedido. O contêiner do painel fica
abaixo da interface do player
e, em seguida, o contêiner de margem fica abaixo do contêiner do painel
e, em seguida, o
contêiner do VBox fica abaixo dele Ok, então a questão é que
queremos que o contêiner do painel estique a
imagem de fundo até as bordas aqui, e então queremos que todo o resto esteja
contido nele. É por isso que o contêiner de
margem
precisa estar dentro do contêiner do
painel, que o
contêiner do painel possa se
estender mais do que o contêiner da
margem. É só uma
coisa de pedir. Então, isso vai ser bem decente. Vamos colocá-lo em nosso mundo. Então, em nosso cenário mundial, vamos criar uma
camada de tela para colocar a interface do usuário. Então, clique com o botão direito do mouse em adicionar um nó de camada
Canvas agora. Ok, e a razão pela qual
você teria uma camada de tela aqui é que ela fornece uma área
de renderização separada de
tudo o mais na cena Portanto, a interface do usuário é renderizada de forma
totalmente independente do mundo do jogo Toti E isso seria importante
se você tivesse, digamos, luzes de jogo
Toti e
não quisesse que isso
afetasse a interface do usuário Você quer que eles sejam
renderizados separadamente. Portanto, as luzes para o
mundo são diferentes de se você tiver alguma luz para a interface do usuário, isso
seria uma coisa diferente. E você meio que os
gerencia separadamente. Então, agora vou querer
adicionar a interface do player aqui, então filtre seus arquivos, pesquise a interface do player Underscore .
Se foi isso que você
deu como nome, Dragon solte a cena
na camada Canvas e ela aparecerá no canto superior esquerdo da nossa interface Antes de clicarmos em Play, certifique-se de que interface
do player esteja abaixo
da camada Canvas. Isso será importante
para que não seja renderizado
também no mundo do jogo, mas sim como parte
da tela. Então está lá no canto superior esquerdo. Na verdade, é bem pequeno. Isso é muito hilário,
se eu for honesto. Podemos aprimorar a interface do usuário aqui ou
aumentá-la na cena base Então, talvez o que eu
queira fazer seja pegar a camada de tela aqui e
vamos transformar, aumentar a escala
para, tipo, quatro X. Você pode diminuir o zoom.
Procure a caixa forrada de roxo. Você pode realmente
ter que esconder, tipo, o mundo terrestre para
que ele realmente o veja. Ok, aí. Então, temos
a caixa roxa aqui. Esta é a área de visualização completa da porta. Então, sua interface
de usuário aqui é meio que relacionada a isso. Então, em uma escala de quatro vezes, acho que funciona muito bem. Agora vou mostrar a sujeira
e a grama novamente. Vamos clicar em Play. E vamos ver se a interface do usuário está
bem no canto superior esquerdo E eu acho que esse tamanho
é realmente bastante decente. Estou gostando muito disso Vamos continuar com isso por enquanto e depois trabalharemos na
criação de um script.
38. L37 Implementando um sistema de UI baseado em estatísticas com sinais: Então, para que essa interface realmente funcione, precisamos conectá-la
a sinais relacionados ao bloco Sp do nosso
personagem. Isso significa que precisamos de um sinal
alterado de EXP ou de um sinal alterado de
HP Queremos ter certeza de que
atualizaremos isso. Também temos outro
pequeno problema, que é que basicamente essa interface de usuário é muito grande na
área da tela em que está atualmente. Então, quero adicionar rapidamente
um script em que eu possa fazer com que a camada Canvas seja exibida automaticamente
quando o jogo começar,
mas, opcionalmente, podemos simplesmente desativá-la quando formos Portanto, não
quero sempre ter que ativar
manualmente a visibilidade. O que vou fazer é
clicar com o botão direito do mouse
na camada Canvas
aqui e anexar um script. Então isso seria apenas
canvaslayer dot GD. Vamos salvar isso na pasta Bin da
interface do usuário. Criar. E vou apenas dizer que a função
sublinhado está pronta. Ele retornará vazio
e, em seguida, diremos
visível, igual E isso é tudo o que
precisamos para isso. Então, agora podemos escondê-lo
quando estamos
vendo nossa visualização do mapa
aqui e clicar em Play. E ainda deve aparecer
assim que o jogo começar. Então, agora podemos escondê-lo
da nossa visualização do mapa aqui, clicar em play, e ele
ainda aparecerá assim que o jogo começar. Então, no
canto superior esquerdo, lá está. Então, isso será útil
enquanto estivermos editando. Outra maneira de lidar com
isso seria ter uma cena completamente separada para sua interface de usuário do Canvas ao
editá-la, depois sua cena mundial
e
combiná-las em
uma cena principal. Quando você realmente carrega o mundo do jogo,
tudo bem. E talvez essa seja
a solução a longo prazo. Mas essa é uma solução muito
boa, rápida e fácil. Então, vamos trabalhar para conectar nossa interface de jogador às estatísticas
do jogador. Então, vamos entrar na cena
da interface do jogador. Vou clicar com o botão direito na interface do jogador. E anexe um script. Assim, o playi dot gD pode estender o controle
e o interior daqui Vamos apenas
exportar R e
diremos o contexto do
jogador. Como já
criamos esse recurso, ele é muito fácil de usar. E o inspetor
aqui no canto superior direito, basta carregar rapidamente o contexto do
player E se você se lembrar do
início do curso, o jogador se
instalará automaticamente lá, então podemos simplesmente pegar o ponto de
contexto, as estatísticas de pontos do jogador e pronto, temos uma
referência às estatísticas. Só precisamos de sinais para
atualizar a tela HP
e a tela EXP. Ok, então podemos
consultar as estatísticas. Vamos ver, ponto do
controlador de estatísticas GD. Se entrarmos nesse roteiro,
teremos uma vida alterada. Vamos criar alguns
sinais de que a HP mudou, Max HP mudou e a
experiência mudou. Ok, então o sinal Mx HP mudou. E você pode ver que são
muitas estatísticas que
vamos mudar com
um tipo muito semelhante. Talvez queiramos passar o
objeto que estava sendo alterado, o valor antigo, o novo valor e o valor da alteração. Então, podemos realmente criar
uma classe para encapsular todas as nossas estatísticas
que vão mudar E esse é um sistema de jogo muito
baseado em estatísticas, tipo
Survivor,
certo, porque você pode reduzir o tempo de resfriamento, pode ter velocidade de
movimento do jogador,
HP, poder de ataque, todo
esse tipo de coisa extra E todas essas são estatísticas que
podem ser representadas dentro de um objeto que
podemos passar para um evento. Também é muito mais fácil
se você tiver apenas um parâmetro para
enviar esse parâmetro
e, em seguida, eles receberem como uma peça,
em vez de três ou quatro. Então, para mostrar o que quero
dizer, vamos criar um novo script em nosso sistema de arquivos. Então, vou
derrubar tudo
e, em seguida, entraremos, digamos objetos porque
objetos têm estatísticas. Então, vou clicar com o botão direito do mouse e
criar um novo script. Então, esses
serão dados que emitirão
um sinal sempre que
uma estatística for alterada Portanto, um nome bem claro
seria stat changed data dot gD. Nós criamos isso. Ok, e
vamos abrir esse script. Então, os dados foram alterados por estatísticas. Nome da classe, dados alterados por estatísticas. E isso, na verdade,
se estenderá a partir de ref count, que é um objeto que, quando
não
for mais referenciado, será automaticamente
excluído do jogo Então, referências. E em vez de estender não, isso na verdade
se estenderá a partir de ref count, que é um objeto Gadot que monitora quantos
objetos estão fazendo referência E quando nenhum objeto faz mais
referência a
ele, ele basicamente
se enfileira para ser excluído, então você não precisa
liberá-lo manualmente Ele será simplesmente coletado
e excluído pelo motor. A propósito, isso também
é o padrão para quando você não
se estende de nenhuma classe, essa também é a
classe padrão. Ok, então nossa estatística mudou os dados, queremos dar a eles uma função de
inicialização,
para que a função sublinhe E quando criamos
um NIT para um objeto, podemos transmitir quaisquer
parâmetros de que precisamos Então, vou dizer objeto P,
o objeto que estamos
afetando com nossa mudança de estatísticas Então, sem TD, o valor P Nu, que eu acho que será um
número inteiro no momento Pode haver uma
estatística flutuante. Nesse caso, você pode alterar esse
tipo para uma variante
para suportar
números inteiros e Mas acho que, no momento, não
haverá realmente nenhum carro alegórico acontecendo
no jogo para estatísticas como
experiência e HP Nós os transformamos em números inteiros
concretos, que provavelmente é
preferível Então, o novo valor
que estamos passando
e, em seguida, queremos o valor antigo. E quando temos o valor
novo e o antigo, podemos
calcular automaticamente a alteração. Então, vamos inserir as
propriedades de estado desse objeto. Eu direi que o objeto var
será um nó dois D, o var new será um inteiro O var old será
um número inteiro. A alteração de var
também é um número inteiro. Então, quando inicializamos
a função, simplesmente
pegamos os
parâmetros e
definimos as variáveis locais
com esses valores Então, o objeto
será igual ao objeto P. Um novo vai
ser igual a P Nu, velho vai ser
igual a P antigo. Agora que temos o
novo e o antigo conjunto, nossa mudança será igual
ao novo menos o antigo,
acho que é a menos que
eu o faça ao contrário Ok, então se o valor antigo for
30 e o novo valor for 20, a alteração será menos dez, que é o que queremos aqui. Então, sim, novo menos antigo. Então, basicamente, o que estamos
fazendo aqui é passar esses quatro parâmetros para o sinal como um objeto de dados St
alterado. E então, no receptor de sinal,
a função de retorno de chamada, podemos acessar tudo
dentro de St alterado para teta apenas fazendo St
changed data dot object, dot new
dot dot CAGE E talvez não
precisemos de tudo isso, mas temos tudo acessível. Além disso, se adicionarmos outra
coisa aqui, como var Cookie, que é um tubo de textura
ou algo parecido
, não precisaremos adicionar
isso como um parâmetro extra. Está contido
nesta classe. Assim, você pode modificar esse objeto
sem precisar alterar seus retornos de chamada ou o parâmetro do sinal de
envio porque está
enviando apenas um objeto Espero que isso faça
sentido. É mais fácil modificar
à medida que você avança. De qualquer forma, nossos dados
estatísticos foram alterados. Então, se voltarmos ao nosso script
de controlador de estatísticas, agora podemos criar nossos sinais Portanto, Max HP alterado
fará com que os dados da
estatística sejam alterados Ok, e então nós apenas sinalizamos para o outro
sinal, HP alterou os dados, as estatísticas alteraram os dados, a
experiência do sinal mudou Dados estatísticos alterados. Agora, a razão pela qual eu
colocaria um sinal para cada um
deles é porque,
no script de recebimento, podemos escolher com quais estatísticas realmente
nos importamos. Então, por exemplo,
a tela EXP aqui só se
preocupa com a mudança de experiência Então, vamos nos
conectar apenas ao sinal de
mudança de experiência e talvez também a um sinal de
mudança de nível para atualizar o rótulo de nível, se ele estiver
na mesma área de exibição. Então, temos esses sinais.
Só precisamos emiti-las. Então, o que eu estava fazendo
antes com, tipo, o configurador HP aqui, se você vai apenas
emitir o valor alterado, acho que é aceitável o uso de um conjunto, então emitimos que o valor mudou e apenas o tornamos uma
propriedade observável tornamos uma
propriedade Então, vou dizer aqui
que, sempre que configurarmos o HP, diremos que o HP
mudou de ponto em HP. Agora, se estamos configurando para HP 100 quando já está
100 repetidamente, talvez
queiramos pular
essa emissão de sinal, para que possamos dizer que se a HP
é igual ao valor
, retornaremos porque não
precisamos
atualizar ao vivo Não precisamos atualizar o HP porque é o mesmo valor. Então, seguindo esse padrão, vou basicamente fazer a mesma coisa com
o MAX HP. Então, vamos fazer cólon.
Próxima linha, defina o valor. Se Mx HP for igual ao
valor, retornaremos. Caso contrário, Max HP é igual a valor, e emitimos Max HP alterado Ah, mas aqui embaixo, esqueci que esse não é
apenas o valor da HP aqui, mas na verdade precisamos criar o objeto de dados alterado por estatísticas Os dados são iguais aos dados
alterados por estatísticas, ponto novo. E vamos passar
essa referência de objeto aqui
para o controlador de estatísticas Então, objete, e então fazemos o novo valor de HP e o valor antigo, que
precisamos obter primeiro. Então, antes de definirmos o novo valor
em HP, logo antes disso, fazemos var Old é igual a HP, e agora colocamos o antigo aqui e passamos os dados para a emissão
do sinal Então, a HP mudou o ponto MMI com os dados, e isso é
tudo o que precisamos fazer E agora ele terá
essas quatro propriedades de dados dentro desse objeto
em vez de apenas uma, mas ainda parece
super limpo porque estamos enviando apenas um objeto. Ok, agora no MX HP, queremos fazer isso de novo. Então, vamos dizer que var
Old é igual a Max HP, e então vamos fazer far data equals stat
changed data dot u. acontece com o objeto,
o Max hP e o antigo, e então emitimos o
sinal HP alterado com os dados Ok, então seguindo
o mesmo padrão, mais
uma vez,
aqui na experiência, dois pontos definidos, ainda
podemos evitar se a experiência for
do mesmo valor, por precaução Então, se experiência é igual a
valor, nós retornamos. Caso contrário, obtemos o
antigo igual à experiência
e, em seguida, a experiência é
igual E então os dados de Vara são
iguais ao
ponto de dados estatísticos alterados w. A experiência do objeto é antiga, e emitimos a experiência
alterada com os dados. Está bem? E eu poderia acrescentar isso. Oh, sim, ok, esqueci o D lá
na parte superior do sinal Controle o STA, e
isso deve ser bom.
39. L38 Criação de scripts para exibições dinâmicas de HP e EXP para a interface do usuário: Então, temos a configuração do sinal, e temos nosso contexto
aqui e a interface do jogador, que nos permitirá
pegar esses sinais
do bloco de estatísticas. Mas, na verdade, não precisamos
fazer isso diretamente
na interface do jogador. Precisamos fazer isso na
tela HP e na tela EXP. Então, eu quero criar scripts para a tela HP e a tela
EXP aqui embaixo Então, clique com o botão direito do mouse na
tela HP, anexe um script e podemos colocá-lo na interface do usuário, então hp display dot GD. Ótimo. Podemos simplesmente fazer
isso se estender a partir do contêiner. Nós realmente não nos importamos com
o tipo de contêiner porque você pode criar uma
tela usando outros tipos. Talvez você exiba seu HB verticalmente em
vez Portanto, você pode usar uma classe base
diferente, como contêiner em
vez de contêiner HBox, e ainda pode criar
o nó real no contêiner
HBox Então, manter as coisas
flexíveis é a ideia aqui. E eu vou dizer o
nome da classe HP Display. Ok, então em nossa tela HP, precisamos de uma referência às estatísticas do controlador do jogador. Poderíamos exportar o contexto do
player e, em seguida, obtê-lo
diretamente aqui
para cada uma das telas. No entanto, se configurarmos
coisas dessa forma, para cada um dos componentes da
subinterface do usuário, se cada um deles tiver uma
propriedade de exportação que você precisa definir, fica muito
difícil arrastá-la para a cena para
reutilizá-la a cena para
reutilizá-la , porque então
você precisa clicar com o botão
direito do mouse nela e torná-la
editável e certificar-se de
atribuir todas as propriedades
individuais, clicar com o botão
direito do mouse nela e torná-la
editável e certificar-se como o contexto do como Para cada nó da subinterface do usuário diretamente. Portanto, outra opção, que
pode ser preferível, é fazer
com que a interface do usuário raiz injete o contexto
do jogador
ou o que é relevante a partir dele,
o controlador de estatísticas, em
cada um dos nós da subinterface do E então você só precisa se
certificar de que a interface do player
conheça seus subcomponentes, como a tela HP
e a tela EXP. Mas então você deixa a
interface do jogador lidar com o trabalho pesado. Então, como isso seria
no contexto de nossa tela HP, seria que precisaríamos de nosso controlador de estatísticas
local Então, se nosso sublinhado iniciar o
controlador de estatísticas. Então, tornamos isso local, certo? Em seguida, criaremos uma
função setter para que possamos definir o controlador de estatísticas a
partir da interface do player Então, digamos que as estatísticas do conjunto de funções, e isso exigirá um controlador de estatísticas de
sublinhado P. Qual é o tipo de controlador
estatístico. Vou voltar vazio. Eu coloquei o sublinhado P
como parâmetro para que
fique bem claro que essa variável é um
parâmetro da função Caso você tenha outro controlador de
estatísticas aqui, não
haverá confusão entre nossa referência local ao
controlador de estatísticas e
nosso escopo de função,
P underscore stat controller P underscore Então, vamos usar essa função de definir
estatísticas para fazer isso. Então, as estatísticas de sublinhado são iguais ao controlador de
estatísticas de sublinhado P. Ok, então temos nosso método
de estatísticas definidas. Ele atribui as
estatísticas às estatísticas, que são privadas aqui
por causa do sublinhado mouse, esse é um script GD, então não é verdadeiramente privado Está apenas marcado que você
não deve acessá-lo de
fora da classe, mas tecnicamente você ainda pode Então, temos nosso
definidor de estatísticas aqui. Queremos nos conectar
ao sinal agora. Então essa é a tela da HP. E eu quero dizer que as estatísticas
Hp mudaram dot Connect, e vamos dizer que no HP mudou E também podemos dizer estatísticas de
sublinhado mxhpHanged E isso pode ser apenas um
sublinhado em Max HP alterado. Então, tecnicamente, os dois sinais
têm os mesmos parâmetros, então poderíamos usar apenas uma função de
retorno de chamada, se quiséssemos Mas, para mantê-lo flexível, talvez haja algum código que queiramos
fazer de forma diferente, dependendo se é
MaxHP ou se o HP foi alterado, terei apenas dois retornos de chamada aqui, então sublinhado da função No Max, o HP mudou, o que
terá os dados P, a estatística mudou os dados, essa reviravolta E o que queremos
fazer é atualizar a LUI. Então, vou apenas criar uma função de
atualização aqui
e, em seguida, faremos a mesma
coisa com o HP Changed Então, podemos simplesmente copiar isso
aqui e depois
remover o bit Max. Portanto, exclua quatro vezes.
Ok, é isso. Agora precisamos de uma função de atualização. Então, vamos dizer atualização da função. E o que queremos
fazer na tela da HP? Sempre que o HP muda? Queremos atualizar o valor do controle deslizante e
atualizar o rótulo do texto Então, queremos basicamente
obter a porcentagem
saudável por porcentagem de saúde, e isso será uma
flutuação igual a, digamos,
sublinhado estatísticas ponto HP, sublinhado estatísticas ponto HP, dividido por sublinhado
estatísticas ponto Ok, então com a
porcentagem de saúde, podemos atribuir isso à barra de progresso da
textura. Então você pode ver agora que precisamos de uma referência para a barra de
textura aqui embaixo. Então, a única vez que vamos configurar
a referência à barra de textura é
como a primeira vez que estamos criando essa cena de exibição da
HP. Talvez salvemos isso em uma cena
separada em nosso projeto, e a cena principal que realmente
colocamos no mundo é
a cena da interface do
jogador. Mas acho
perfeitamente razoável exportar
a
barra de textura e o rótulo aqui. Também há outras maneiras de
pegá-los. Mas esse é o método que vou usar. Então, direi que em
export var progress é uma barra de progresso de textura. E então, na exportação,
var label é um rótulo. Então, quando estamos nos atualizando, podemos pegar o progresso
e usar o rótulo,
e diremos que o valor do ponto de progresso é igual Então, deixe-me ver. Isso deve
estar em uma escala de 0 a 100 E esse cálculo
na verdade vai
te dar 0,021 0,0 Então, queremos multiplicar
isso por 100 para obter uma porcentagem real multiplicada por 100 E não tenho certeza sobre a
ordem das operações aqui. Então, vou apenas embrulhar
essa parte para garantir que ela seja executada antes
disso com certeza Ok, e então o
valor do progresso será nossa porcentagem de saúde de
0 a 100 como flutuador Em seguida, precisamos definir o valor do
texto no rótulo. Portanto, o texto do ponto do rótulo será igual à string. Poderíamos simplesmente dizer
entre aspas HP, porcentagens, saindo com uma
barra para frente e porcentagens, e então substituirmos
esses valores por um sinal de porcentagem e os
passamos em
uma Então, os valores que vamos
usar
serão o HP atual e o MX HP Então, em outras palavras,
sublinhado estatísticas ponto HP e sublinhado
começa ponto MAX Então, se você quiser que isso
seja personalizável, podemos cortar isso
com o Control X e substituí-lo por algo
como um modelo de texto de saúde Então, aqui no
topo, poderíamos dizer que na barra de
exportação o modelo
de texto Health será igual a, e então o Control V cole isso. Isso ainda tem esses percentuais
como símbolos para substituição. Portanto, ainda fazemos a porcentagem do modelo de
texto de saúde
e, em seguida, a matriz
dos dois valores em ordem,
que é sublinhado, estatísticas, ponto HP,
e, em seguida, sublinhado,
estatísticas, ponto máximo Ok, então isso
atualizará a barra e atualizaremos o texto. Então, também queremos chamar isso
sempre que definirmos as estatísticas. Então, vou dizer que atualize aqui para garantir que,
depois de definirmos as estatísticas, também
atualizemos imediatamente
esse texto Precisamos de dois pontos aqui
para finalizar essa função, e isso é muito bom Agora, no
lado direito do script, precisamos atribuir o
progresso e o rótulo. Então, atribua a
barra de progresso da textura e atribua o rótulo. Certifique-se de selecionar
os que estão abaixo da barra HP. Agora, isso vai ser
bom para a tela da HP. Quase queremos o mesmo
script para a exibição EXP, mas há
algumas diferenças Então eu vou controlar A, Control C para copiar
tudo neste script. Vamos até
a tela EXP. Clique com o botão direito, anexe o script. Exp display dot gD
parece bom para mim. entanto, alteraremos o tipo de herança
aqui para contêiner
e, em seguida, basta selecionar tudo e substituí-lo por um
Control V colando-o Agora precisamos alterar o nome da
classe para exibição EXP. Nosso modelo HealthText. Vamos selecionar
esse Control R para substituí-lo pelo modelo de texto
EXP Neste modelo de texto de saúde,
selecione o texto. Você pode clicar duas vezes nele
para selecionar tudo. E então faça o Control R. Aqui
embaixo,
vamos substituir o modelo
de texto
Health pelo modelo de texto EXP, substituir tudo e, em seguida,
queremos mudar esse HP aqui para EXP como
nosso modelo padrão A última coisa que precisamos fazer
é alterar a conexão do sinal para
que a
experiência seja alterada. Podemos nos livrar completamente
do Max HP alterado
e, em seguida, substituir o nome dessa
função aqui mesmo na alteração de
HP para que você possa
selecioná-la, Control R, e aqui embaixo,
queremos substituí-lo na EXP alterada ou experiência alterada, o que
fizer sentido para você Vamos substituir isso.
Livre-se dos dados alterados do
Max HP aqui
para finalizar esta parte. Ainda não vamos atualizar a barra de
progresso, então vou comentá-las. Então, por enquanto,
ampliaremos aqui e eu substituirei o modelo de texto de experiência experiência de
pontos
com sublinhados, e também colocarei a experiência aqui
novamente. Então, dirá como um em um ou dois em dois, mas pelo menos podemos
ver isso funcionando. Agora, no canto superior direito,
certifique-se de atribuir o progresso. Para a barra de progresso da textura, o rótulo para o rótulo. Então, precisamos apenas da
tela HP e da tela EXP para
chamar a função de estatísticas definidas a partir da interface do jogador Então, dentro do script de interface do
player, vamos exibir ExportVRHP
do tipo HP Display em Export var EXP display
of type EXP display E então a função
underscore está pronta, vamos chamar hp display dot set Stats para
contextualizar dot play dot stats, e precisamos obter isso
duas vezes para que possamos até mesmo dizer var stats do stat Controller, então definimos isso como
igual a esse bit Então eu vou cortar
isso, ir até aqui, sinal de
igual, colar. Então, definimos estatísticas nas estatísticas. Fazemos a mesma coisa
com EXP display
XP display dot set Stats E depois fazemos estatísticas. A última coisa que precisamos é
atribuir a tela HP a tela EXP e o inspetor para que
tenhamos essa referência Então clique na interface do jogador, vá para o canto superior direito e
atribua a tela HP. E atribua a exibição EXP. Agora, na verdade, a tela HP e a tela EXP podem
e provavelmente devem ser suas próprias
cenas independentes, das quais
instanciamos uma cópia
na interface do usuário do player Então, vou
clicar com o botão direito do mouse na tela HP e
salvar a ramificação como uma cena dentro da nossa interface de usuário
e, em seguida, clicar com o botão direito na tela
EXP e fazer
a mesma coisa Salve a ramificação de uma cena
dentro da interface do usuário. Então, agora podemos entrar neles
e personalizar individualmente essas pequenas telas conforme necessário no contexto de nossa
maior interface de usuário de jogador. Então, temos cenas dentro de cenas
e, em seguida, pegamos a cena da interface do
jogador e a colocamos no mundo
do jogo, que está invisível
agora porque a interface do Canvas foi atingida.
Mas sim, aí está. E se estivermos jogando, veremos se alguma coisa
está conectada corretamente. Ok, então defina as estatísticas
e a exibição do HP é nula porque esqueci de
atribuí-las no inspetor Você pode ver aqui que
eles são nulos quando prontos, o que significa que esqueci
isso na exportação Além disso, como isso é uma verificação, não
precisamos de nenhuma afirmação
porque está implícito aqui que
isso é necessário Então entre na cena do jogador, clique na interface do jogador, atribua a tela HP
e a tela EXP De qualquer forma, agora podemos jogar
e vamos testá-lo novamente. Portanto, temos dez de 100 HP. Se bem me lembro de ver
as estatísticas, nosso HP máximo era 100 e
nosso HP básico era dez, o que obviamente é atingido aqui. Você pode ver as
atualizações da HP para zero. A barra de progresso do EXP ainda
não está funcionando porque
precisamos configurar nossos
requisitos de experiência de nível E, o que criará, tipo, toda
uma hierarquia
de subida de nível Mas vamos tentar rapidamente, configurando o HP para
50 em nosso player. Então, vou para a cena do nosso jogador e depois vou dar uma olhada
no controle de estatísticas aqui E vamos definir o HP
para 50. Deixe-me ver. Se eu fizer isso ali mesmo,
posso voltar ao jogo? Não, porque os jogadores
já foram removidos, eu acho. Mas ao clicar em play, devemos ver a atualização da barra de HP aqui com o
valor de progresso correto, mas isso não acontece. Ele mostra o valor correto da HP, mas temos que consertar a tela da
HP bem rápido. Ok, então na tela da HP, deixe-me ver o que
estava acontecendo aqui. O valor do progresso é igual
à porcentagem de saúde. Deixe-me definir um ponto de interrupção
aqui, clicarei em Play e veremos o que realmente
está configurando isso para
que a porcentagem de
saúde seja 0,0. Ah, certo, porque estou
dividindo com números inteiros. Então, quando
dividimos
por dois inteiros, obteremos um inteiro, que vai
automaticamente
para o piso zero. Mas não é
isso que queremos. Na verdade, queremos que ele
retorne um fluxo. Então, o que poderíamos
fazer como uma solução rápida aqui é simplesmente flutuar no Mx HP Então, agora isso vai ser um número inteiro dividido por um flutuador,
que retornará um flutuador que retornará Se clicarmos em play, veremos o valor
certo ir para lá. Então, agora podemos ver uma
porcentagem de saúde de 50. Se clicarmos em play, a barra está
aparecendo corretamente. Menos a compensação do valor
. Então, deixe-me ver. Eu compensei o valor
lá, monitor HP? Temos a
barra de progresso da textura e, por algum motivo, é até 00 aqui, mas quero que seja menos
20 para que, quando o valor for 50, apareça corretamente
no meio. Você pode ver ali mesmo que isso
é como quatro de 8 barras. E o valor aqui é 50. Devo ter desativado
isso em algum momento, mas o tipo de solução idiota
para isso é fazer com que o valor mínimo fique mais para
a esquerda para que 50
acabe no Porque se isso for
zero aqui, então 50 na verdade acaba
como, tipo, a terceira barra. Veja, eu me certifico de que seu
valor masculino seja negativo 20, e isso deve funcionar
para a tela HP. Ok, então no teste final aqui,
clicamos na
barra de progresso do jogo, configurada para 50. Eu posso desfazer esse
ponto de interrupção, apertar play. E podemos ver que nossa barra de progresso de
saúde está corretamente no
meio, ali mesmo. Nosso HP está nos mostrando 50
de 50. Vamos ser atingidos. Você pode ver nossa queda de HP A interface
reflete isso imediatamente, incluindo a barra de progresso. Portanto, todos os nossos sinais estão se
conectando corretamente. Estamos definindo a
experiência e só precisamos adicionar
nossas definições de aumento de nível para que
possamos aumentar o nível
de nosso personagem Antes de terminarmos completamente o vídeo em nossa função de estatísticas
definidas, há uma falha aqui: se algum dia redefinirmos
as estatísticas com estatísticas definidas, e uma já estiver definida aqui, acabaremos com sinais
duplicados Então, queremos dizer aqui que, se as estatísticas de sublinhado não
forem
nulas antes de chamarmos set Stats, queremos nos desconectar
dos sinais, para que possamos dizer sublinhado stats dot mxhPhanged dot O sublinhado no MAX HP foi alterado. E a mesma coisa para
o HP normal. Então, nós apenas copiamos isso
e fazemos o SATS. A HP mudou, e depois a HP mudou Isso é mais do que apenas
torná-lo robusto. Nunca pretendo configurar o controlador SATS para algo diferente, mas
caso você o faça, isso garantirá
que não cause um bug horrível em que você tenha dois sinais conectados a dois controladores
de
estatísticas diferentes,
mas em mas em Agora, faça a mesma coisa no EXP também Então, se você olhar
a tela EXP, vou colar isso e mudar
o nome do sinal Então, a experiência do sats mudou
e, em seguida, a EXP mudou aqui. Ok, então é assim
que deve ser. Sublinhe que a
experiência do SATs mudou desconexão na Ok, então isso deve ser bom se você já trocou
o controlador SATS Só queria mostrar
que um pouco mais completo.
40. L39 Depurando e otimizando scripts de UI e Pickup: Eu queria esclarecer
alguns avisos e erros. Estou entrando no console
com o projeto até agora. Portanto, se você estiver copiando
o código palavra por palavra, talvez
tenha se deparado com
esses mesmos problemas. Portanto, escolha dois D
onde diz que você não
pode usar monitorável
igual a falso,
normalmente porque está bloqueado
e você precisa esperar pela
configuração não
pode usar monitorável
igual a falso, normalmente porque está bloqueado e você precisa esperar pela Então, se você clicar duas vezes
nisso, mostrará que,
na função de remoção, eu estava tentando definir
monitorável como falso Bem, na verdade, vou
remover o que é monitorável igual a falso aqui, porque
quando você libera o Qu, ele é removido no final
do quadro atual Quando você chama set deferred, ele é removido no final
do quadro atual Portanto, torná-lo não monitorável
ao mesmo tempo em que você o libera não vai realmente
ajudar em nada O objetivo era
fazer com que, se dois objetos tentassem
pegá-lo ao mesmo tempo, ele não pegasse duas vezes. No entanto, o que podemos fazer se
você quiser estar mais seguro. No entanto, se você quiser ser
ainda mais seguro e pegar dois D, vamos escolher entre eles. E esse será um booleano
definido como falso por padrão. Então, estou apenas insinuando que
é um booleano lá. Quero dizer, se você quiser
declarar isso com certeza, então você pode fazer isso.
Então, isso é escolhido. E se tentarmos entender quando isso é verdade, então vamos permitir. Caso contrário, retornaremos false. Então, o que vou fazer com o Tr take é fazer
com que ele realmente proteja, e então teremos uma função de captura
separada, que será o que os
captadores realmente implementarão, como a função virtual, o
que eles fazem atualmente Então eu quero fazer a
função, sublinhar T, e isso não vai
retornar nada,
então esse é um tipo de retorno de vazio E vou pegar esse erro de push
e trazê-lo aqui. Então, vou
voltar à verdade aqui agora. Vou mudar isso para sublinhado T. Então, chamamos
a função virtual
e, em seguida, vamos nos
proteger
contra voltar aqui
pela segunda vez Então, vamos dizer, eu
escolhi, retorne falso. Ok, então aí está nosso guarda. Caso contrário, chegaremos aqui. Depois de tirarmos,
escolhemos é igual a verdadeiro. E estou colocando
isso aqui para que não precisemos nos preocupar com esse booleano
e com as classes herdadas Só precisamos nos preocupar implementar a função take. Então eu acho que essa é
uma configuração melhor. Funcionará bem
com o Ir Quarter
e, desde que definamos
a opção como verdadeira após a ligação temos certeza de que ela não
atenderá pela segunda vez porque
temos esse guarda aqui. Então, agora só precisamos atualizar
nossos outros scripts de coleta. Então, pesquise e pegue. Acho que
só temos captador EXP até agora Então, vou clicar duas vezes nisso. Vamos renomear
isso para sublinhar Take the return type is E em vez de
retornar false aqui, se as estatísticas forem nulas,
enviaremos um erro Então, erro de push. A porcentagem não tem controlador
de estatísticas. Essa será a meta de
porcentagem P. Então, substituímos isso por
um nome de nó. E então não
voltamos ao fundo. Nós apenas chamamos de remove.
E precisamos ter certeza de que combinamos com a assinatura
dos pais. Então, provavelmente preciso passar o alvo P para
o script pai. Ok, então vamos subir. E sim, queremos ultrapassar a meta P. Então, como alvo P,
removeremos o sublinhado
porque , na verdade, o estamos
usando agora E aqui sublinhamos que o alvo
P é um nó dois D. Agora, isso deve eliminar os erros em nosso
EXP Pickup dois D. E só para verificar,
entraremos Ok, então os outros
avisos, vamos ao que interessa. Na maioria dos casos, esses são
apenas parâmetros não utilizados. Então, no caso de algo
como pegar dois D, você vê que o alvo P não é usado, então você só quer marcá-lo
com sublinhado para que seja marcado como Vamos para o próximo aqui. O tamanho da câmera nunca foi usado. Portanto, o tamanho da câmera foi usado , na verdade, para criar
o reto da câmera. Então, na verdade, não é
necessário aqui porque nesta função de cálculo
final de geração, usamos para o sistema de geração. O reto da câmera é criado
e, em seguida, o tamanho é
retirado dele Então, podemos realmente remover tamanho da
câmera como
parâmetro e cortar isso. E então, quando
chamamos isso aqui, basta remover o tamanho da
câmera como parâmetro e simplificá-lo
para três parâmetros. Então, esse seria um
bom caso em que esse
aviso realmente nos ajudasse. E então, a seguir, se você tiver uma atualização que
não usa o Delta, o que seria o caso se você movesse e deslizasse porque
mover e deslizar não
precisa fazer o Delta,
você define a velocidade e, em seguida, move
e desliza automaticamente as
alças com o Delta Então, destacamos o Delta
e pronto. E esse script de drop,
o nome drop aqui está sombreando
o nome da função Então, poderíamos mudar o nome aqui para algo
como drop instance. E então, sempre que
usamos drop under it, como aqui, dizemos
drop instance em vez disso. Você só quer ter certeza de que se usar uma variável localmente, não
tenha essa variável
declarada fora
do escopo na base da classe, como as variáveis locais. E você também não quer que ele tenha o mesmo nome de uma
função. Então, em cada um desses sinais de alteração de
estatísticas, os retornos de chamada, eu estava apenas atualizando
sempre que o valor mudava
e, na verdade, não precisava usar os dados P diretamente para essas
funções Então, eu apenas
sublinharia os dois mais uma vez no script de exibição do
EXP. Clique aqui e sublinhe isso, e isso deve eliminar
todos os avisos e erros atuais E eu vou clicar em Play.
Ok, sem erros para.
41. Sistema de classificação P40 com experiência e progressão de estatísticas: Saúde e experiência Agora, precisamos adicionar algum
tipo de mecânica de nivelamento e precisamos ter
uma estatística de nivelamento
em nosso controlador de estatísticas para gerenciar
o aumento de nível de
nosso jogador e possivelmente de outros personagens, mas Então, vamos entrar
no controlador de etapas e vou adicionar
uma nova variável aqui. Diremos que será
um número inteiro igual a zero
e teremos uma configuração semelhante
à experiência aqui embaixo, onde teremos
apenas um onde teremos
apenas saturação em que diremos que o nível
I é igual ao valor que retornaremos,
caso contrário, repetiremos
o mesmo padrão emitindo
o sinal de
alteração de nível para que possamos
responder a isso em nossa interface do usuário nível
I é igual ao valor que retornaremos,
caso contrário, repetiremos o mesmo padrão emitindo
o sinal de
alteração de nível para que possamos
responder Então, diremos que var
old é igual ao nível e diremos que o nível é
igual Diremos que var data
é igual a stat
changed data dot u
object level old e emitiremos um sinal de alteração de
nível Com os dados. Agora, precisamos
criar esse sinal, é
claro, então o nível de cópia
mudou na parte superior. Vamos criar dados alterados
no nível do sinal, dados alterados
nas estatísticas Então, agora podemos
assinar isso, se precisarmos. Agora podemos
implementar totalmente a adição de experiência. Então, sempre que adicionamos experiência, também queremos verificar se estamos
prontos para o próximo nível. Eu coloquei isso aqui, em vez definir
a experiência,
porque não
quero muitos efeitos colaterais
aleatórios ao definir a experiência.
Por
isso, quero chamar explicitamente
o método de experiência publicitária, que aumenta de nível se o
limite Ok, então para fazer isso, precisaremos criar um objeto de definição de
nível. Então, vamos criar um
novo script para isso. Tudo vai entrar,
digamos, nos personagens. Clique com o botão direito aqui,
faça um novo script, e nós o chamaremos de definição
de nível. Então, ponto de definição de nível gD. Vai se estender a
partir do recurso, criar. Clique duas vezes para abri-lo e forneceremos uma definição
do nível do nome da classe. Isso ampliará os recursos
e
definirá um aumento de nível
para um personagem. Então, o que precisamos aqui será o limite de
experiência Então, na Export VR, diremos que é necessária experiência. E isso será um número inteiro. Poderíamos usar como padrão
algo como dez. E provavelmente também queremos algumas estatísticas para
subir de nível. Então, por enquanto,
vamos começar
com a HP e simplificar, mas você criaria estatísticas
extras aqui mais tarde, à medida que descobrisse que
elas se tornaram mecânicas Então, em Export var HP, diremos que é um
número inteiro, padronizado para dez E podemos dizer que esse é o
bônus de HP por subir de nível. Então você atinge esse nível, seu
personagem recebe tanto HP. Agora, como aplicamos nossas
mudanças de estatísticas ao personagem? Você poderia fazer isso um
de cada vez manualmente, mas uma maneira mais inteligente seria criar um método
para fazer isso por você Então, digamos que a função se aplique, e vamos aplicar isso em um controlador de estatísticas, digamos. Então, as estatísticas P de um controlador de estatísticas. Então retornaremos
vazios com isso. Então, queremos basicamente
atualizar os conjuntos. Portanto, P stats dot HP plus
é igual à quantidade de HP. E antes disso, também
queremos aumentar o MX HP. Então p stats dot MX
HP plus é igual a HP. É importante que você
faça o MAX HP antes do HP porque o
HP atual está limitado ao MAX HP. Portanto, se um personagem com saúde completa
aumentar seu HP em dez, na verdade
ele não
ganhará a saúde a menos que o HP MÁXIMO seja atualizado primeiro. É muito importante fazer o pedido lá. E essa pode ser nossa definição básica
de nível por enquanto. Portanto, no controle de estatísticas,
seria um lugar decente para definir nossas definições de nível Então, vou dizer que na exportação, aumente as
definições de VR. E isso é uma matriz
de definição de nível. Ok, então
para verificar a subida de nível, precisamos obter o próximo
nível na sequência. Então, vamos criar uma função para obter nosso próximo nível, se houver um. Então, aqui embaixo,
digamos que função,
sublinhado, chegue ao próximo nível O que retornará uma
definição de nível ou nula. E isso retornará
as definições de nível superior do Git, e
chegaremos ao nível do índice Então, a razão pela qual estamos
chegando ao nível do índice é porque o nível é, na verdade, o
segundo lugar na matriz. Então, se nosso personagem
está no nível um, estamos atualmente
no índice zero e queremos ver
o índice mais um, que é o nível porque o
nível começa em um. Ok, então, para lidar com nossa subida de nível de
experiência
adicional, primeiro precisamos obter a definição do
próximo nível para o próximo nível Então, como o nível mais um, precisamos colocar essa
definição de nível no topo. Então, vamos ao Export, não de certa forma, mas na verdade
um dicionário aqui. Então, em Exportar
definições de nível de VR, diremos. E isso será um dicionário de números inteiros que são atribuídos
à definição de nível Portanto, o número inteiro é o nível
que estamos tentando alcançar, e a definição do nível as mudanças de estatísticas que
ocorreriam se existissem Portanto, antes de subirmos de nível
ou
tentarmos subir de nível, precisamos primeiro ver se há
realmente um nível definido. Então, na parte inferior, criaremos outra função de
função privada underscore get next level, e isso retornará
uma definição de nível ou nula Então, retornaremos nossas definições
de nível dot GET no nível mais um. Nosso nível atual mais um, queremos obter isso e
queremos retornar nulo Se não conseguirmos encontrá-lo. Então, se retornarmos null
, pularemos a subida de nível Então, nessa experiência,
vamos fazer VR. A
seguir será uma definição de nível
igual à obtenção do próximo nível. Então, se o próximo for nulo, nós simplesmente retornaremos ou você
pode até mesmo enviar um aviso Na verdade, sim, vamos
dar um aviso. personagem não pode subir de nível
até uma porcentagem mais um porque esse nível não
tem uma definição definida. Então, poderíamos dizer uma sequência de
níveis mais um aqui
no final e finalizá-la com outros parênteses.
Ok, isso vai funcionar. Então, pegamos o nível mais um. Estamos tentando subir de nível para o
nível dois se estivermos no nível um, e notamos que não
podemos subir de nível porque
isso não está definido. Então, talvez você queira
ter isso como um aviso
ou, se tiver certeza de
que não quer,
pode simplesmente comentar ou remover. Vou deixar isso aí por enquanto para que
possamos pelo menos ver quando falhamos em definir
uma definição de nível. Então, o próximo nível é nulo, então se o próximo for nulo, retornaremos porque não
podemos subir de nível Não há um próximo nível definido. Então, simplesmente pulamos completamente. E então queremos verificar se o requisito de
experiência do próximo nível é menor ou igual à
nossa experiência atual. Então, podemos colocar isso como parte
de uma função de três níveis. Então, sublinhe três níveis acima, e diremos no próximo Então, viemos até aqui e
teremos nossa função. Sublinhado. Tente subir de nível. Sublinhe porque é privado e passamos para a definição do próximo
nível Ou na verdade, você sabe,
eu sinto que isso deveria estar contido
nessa função, na verdade. Então, isso retornará um booleano, e
teremos isso aqui Então, acabamos de obter o próximo nível
dentro dessa definição. E então não precisamos
passar um parâmetro. Nós apenas tentamos
subir de nível depois de adicionar XP, certo? É exatamente assim. Então, se não conseguirmos
subir de nível, retornamos false. E então queremos verificar se
a experiência é maior ou igual à
experiência necessária no próximo ponto. Se for esse o caso
, subiríamos de nível. Mas eu vou reverter isso.
Eu vou dizer que se for menos do que a experiência necessária
, retornaremos false. Ok, então estamos fora
da declaração if novamente. E então, se chegarmos até aqui, passamos pelas verificações de guarda, então podemos dizer que nível
mais é igual Subtrairemos a experiência necessária da experiência
atual Então, experiência menos é
igual ao próximo nível. Oh, desculpe, a seguir, não é necessária
experiência. E então aplicaremos as estatísticas do próximo nível
às nossas estatísticas atuais. Então, depois de subtrair o XP, aplicamos o próximo ponto a si mesmo porque estamos trabalhando dentro do script
do controlador de estatísticas
e, em seguida, retornaremos verdadeiro
porque subimos de nível com sucesso Agora deixe-me pensar sobre isso.
Acho que realmente quero que o nível aumente após a
aplicação das estatísticas, dessa forma. Então, se vamos dizer, que um personagem suba de
nível e, em seguida damos a ele as opções
de recompensas. Então, escolhendo uma atualização
na subida de nível, que é uma mecânica básica
e como a de nosso sobrevivente, queremos fazer isso depois que as estatísticas
básicas se aplicarem, para que
a interface ainda seja atualizada
basicamente no mesmo quadro, mas pouco antes de subirmos de
nível e emitirmos nosso sinal de mudança de
nível,
fazendo com que a interface reaja e nos mostre Acho que é importante mudar o
pedido lá. Ok, então sim, então o
nível do sinal de mudança será emitido
aqui por causa do configurador E isso é basicamente
nossa subida de nível. Se, por
algum motivo, você quiser obter a definição do
nível atual, isso pode ser útil
fora do script. E esse pode até ser
útil fora do script. Então, vou pegar o próximo nível, e removeremos
o sublinhado para
girar , mover esse sublinhado
e tentar E vamos adicionar uma
função G nível atual. Definição ou talvez apenas esclareça os níveis
atuais o suficiente. E então retornaremos a definição
do nível. Então, retornaremos as definições de
nível dot GIT e queremos retornar
o nível ou nulo OK. Portanto, eles
podem ser úteis para outros scripts que desejam analisar o que está acontecendo
com o controlador de estatísticas Portanto, faz algum
sentido torná-los públicos. Ao não ressaltar É por isso. Ok, então
temos essa propriedade de estatísticas e podemos subir de nível
sempre que nossa EXP aumentar, que deve ser automático,
pois essa experiência
publicitária será chamada de
nossa coleta, nossa coleta de EXP Então, tudo vai fluir bem se estiver funcionando bem Só que agora precisamos
ter certeza de que estamos nos conectando à estatística de nível e
ao aumento de nível ou ao sinal de alteração de
nível, em vez disso E vamos fazer isso
dentro da tela EXP. Então, precisamos procurar EXP em um projeto e rolar
para baixo, encontrar nossa cena xp display
dot TSCn e abri-la Ok, agora que nosso
nivelamento deve estar funcionando, precisamos entrar
na tela de EXP e
garantir que ela mostre quanta EXP
precisamos para o Então, vamos entrar aqui. E quando atualizamos, queremos obter o
próximo nível de XP Queremos mudar essa parte
aqui para o XP máximo das estatísticas, se as estatísticas tiverem um próximo nível que
possamos realmente acessar Então você se livra dessa parte e
diz que VarnNxt será
igual a underscore
stats Então, obtemos o próximo nível
e, se não houver um próximo nível, diremos que I next
é igual a nulo e, em
seguida, queremos alterar o texto do ponto do
rótulo para ser igual a, digamos, nossa string de nível máximo Ok, então precisamos
definir isso aqui na string de nível máximo de exportação var, e isso será
igual a algo como o nível máximo em maiúsculas. Ok, senão, vamos
definir o texto para nossa EXP,
nosso número atual a partir do número
do próximo nível Então, confirmamos
que next não é null, então podemos substituir esse bit pela
experiência next dot, Ned Agora, se eu executar o jogo, provavelmente
dirá apenas nível
máximo porque
não definimos nenhuma definição
de nível. Se estivermos no nível MAX
, também quero
pegar a barra de progresso e definir esse valor como 100. Então, agora, se rodarmos o
jogo, atualmente, isso nos dará um
erro porque eu não configurei o progresso,
então vamos fazer isso. Então, em nossa tela XB, vá para a direita e
atribua a barra de progresso Ok, agora podemos correr e devemos ver uma barra de progresso
completa. Estamos no nível MAX. Ok, então pegar o XB não importa mais Ainda tenho uma boa experiência, mas ela nunca mais subirá de
nível. Porque as definições de nível são atribuídas no editor,
não durante o jogo. Embora você pudesse fazer isso, mas isso seria
muito estranho, certo? Como definir
no final do jogo que você pode subir de nível até agora o nível 31, onde antes 30 era o limite, não, isso é algo que
você faz no editor. 99,99% do tempo. Portanto, temos o
valor do progresso sendo definido aqui. Queremos obter uma porcentagem
entre nossa experiência e
a próxima experiência necessária e, em seguida, atualizaremos o valor
do progresso aqui para quando pudermos subir de nível. Portanto, nosso progresso está aumentando
e definiremos isso como igual
à experiência necessária no próximo ponto
dividida pela experiência de pontos nas
estatísticas de sublinhado Agora lembre-se de que estamos dividindo
um inteiro por um inteiro, mas na verdade queremos que seja um
flutuante Então, precisamos pegar
um desses e lançá-lo como um flutuador.
Então diga flutuar. E então, em stats
dot experience, terminamos de colocá-la
entre parênteses Então fazemos isso, e isso agora
deve nos dar algo entre
0,0 e 1,0. Mas isso precisa ser
basicamente convertido em uma porcentagem porque
nossa barra de progresso por padrão, tem um valor
máximo de 100, então estamos analisando porcentagens Ou isso, você precisa reduzir
o valor máximo para um. Ambos são realmente válidos. Então, aqui podemos simplesmente colocar outros
parênteses e multiplicar por 100, e isso deve nos
dar nosso Então, ainda não vamos chegar
a isso porque
precisamos definir algumas definições de subida de
nível. Então, vamos até o player e clicaremos
no controlador de estatísticas Temos nossas
definições de nível aqui. Assim, podemos adicionar alguns valores-chave do
dicionário. Queremos que o próximo nível de
dois seja definido aqui. Então, adicione dois e uma nova definição
de nível. Dentro daqui, podemos
dizer que o XB precisava de dez HP e dez. Isso é bom para começar.
Adicione o par de valores-chave. É importante que você
se lembre de bater nisso. Caso contrário, não estará
no dicionário. Portanto, temos nosso dicionário
com uma chave no nível dois e uma definição de nível para aumentar o
nível de nosso personagem. Ok, um último pequeno
ajuste que precisamos fazer é garantir que nosso jogador passe para o
nível um. Então, vamos
ao controlador de estatísticas e
onde temos o nível Precisamos ter
certeza de que é um. Dessa forma, quando
verificarmos o nível mais um dos dois, encontraremos essa definição de
nível e ela deverá ser exibida
corretamente na interface do usuário. Então, vamos clicar em Play e
teremos nosso XB necessário aqui. A barra de progresso não foi atualizada, mas vamos ver quando
obtemos uma EXP, ela aumenta e
aparece em dez E sim, erro simples. Esqueci de atribuir o progresso ao valor do ponto de progresso Então, talvez realmente faça sentido mudar isso
para um nome diferente. Estamos sombreando uma variável. Aposto que se eu verificar
os erros aqui, você pode ver que sim, eu sombreei isso com o nome da barra de textura de
progresso Então, digamos que percentual nivelado
seria um nome muito melhor. E então diremos que o valor do ponto de
progresso é igual à porcentagem E agora tenho
certeza de que deve funcionar. Vamos jogar. Vá lá. Podemos ver por que o EXP
não adorou lá, e agora está dizendo que é
um em cada dez Isso é interessante. Então, eu
preciso definir um ponto de interrupção aqui para ver o que isso está mostrando E vamos entrar no modo de jogo. E podemos ver que está
dizendo 0,0 agora, mas vamos
pegar um e obtemos 1.000. Outro erro lógico simples, eu deveria estar fazendo a
experiência dividida
pela experiência necessária.
Então, revertemos isso. Vou pegar a experiência
necessária e colocá-la aqui, e depois vou cortar a experiência de pontos de
estatísticas e colocá-la
aqui à esquerda. Ainda poderíamos fazer a
fundição flutuante à
direita. Isso é bom. Ok, então vamos jogar mais uma vez. Testar isso? Então, ok, agora está mostrando 0% subindo de nível Pegamos um item.
Temos 10% lá, dois, três, mas deve
estar indo até o fim. Então, quero verificar o valor da
parada de progresso aqui e ver
por que isso está ocorrendo. Ok, então aqui
temos 40% de subida de nível. Portanto, a porcentagem nivelada está correta. Então, talvez
precisemos verificar
a interface do usuário fora do jogo. Então, vamos entrar na tela
EXP aqui. Vou testar a configuração
do valor como zero. Ok, está correto.
100 está correto. Vai até
a extrema direita. Digamos que 25, 50, 75. Ok, isso parece correto. Então, vamos levar o valor para zero. Tudo bem, jogue. Vamos
testar isso um pouco. Ok, remova o ponto de interrupção. Entre no modo de jogo e
vamos fazer um, dois, três. Então isso é 30%? Talvez esteja correto, na verdade. Ok, então obtemos quatro de
dez e depois cinco de dez. Ok, sim, estava funcionando bem. Vamos pegar sete de
dez. Na verdade, vamos apenas nivelar nosso personagem
para provar que ele funciona. Ok, então temos nove de dez, e então temos o
esqueleto desovando Podemos obter mais um,
dez em dez. Ok, você viu que
acabamos de obter dez HP aqui, então passamos para zero em dez para a EXP necessária Então, a parte sobre o próximo nível deveria ser devolver
alguma coisa, mas isso não aconteceu. Então, a razão pela qual
isso ocorreu é que nossa experiência
é definida como zero. Ele emite um sinal, e então nosso nível alterado
não se conecta aqui Então, depois que o nível é alterado,
ele não é atualizado novamente. Ok, então a solução
mais simples é apenas sublinhar que o nível de
pontos das estatísticas foi alterado e nos conectamos ao nível
alterado para atualizar novamente Então, podemos copiar isso
aqui e desconectá-lo. Então, criaremos nossa função de
retorno de chamada
na função inferior, sublinhando o nível alterado Não vamos usar os
dados, então sublinhe os dados P. Os dados foram alterados,
retornamos nulos e apenas atualizaremos Ok, dessa forma, depois que a
experiência for definida como zero, logo antes de
aumentarmos nosso nível, isso atualizará a interface do usuário, mas depois o nível mudará
e nós atualizaremos a interface novamente Então, vamos mostrar mais uma vez que tudo está funcionando conforme o esperado. Então, vou ter
experiência suficiente para subir de nível aqui. Então, para e depois, cinco, seis, sete, oito, nove. Na verdade, os Skillsins ainda não
derrubam nada. Vamos corrigir isso
em breve. E depois dez. Ok, agora ele mostra o nível máximo, mas também aumentamos nosso HP. Então, isso atualizou nossa interface do usuário duas vezes. Uma vez quando mudamos nossas estatísticas, diminuindo a experiência e outra vez quando
aumentamos nosso nível, que agora mostrará que o
próximo nível não existe Então, mostramos o nível máximo em nossa barra de
EXP, como seria de esperar. Então, tudo
parece estar funcionando.
42. Ladrilho 41 Configurando limites de XP e conexões de sinal para recompensas de aumento de nível: Indique agora onde
gostaríamos de adicionar um sistema de atualização semelhante a
um desonesto Então, aumentamos o nível de nosso personagem quando ele atinge
um determinado limite de XP
e, em seguida,
selecionamos uma das três opções de como queremos
aprimorar nosso personagem E isso é escolhido em uma
lista aleatória de opções disponíveis. Então, por uma questão de conveniência,
antes de entrarmos nisso, quero alterar
o requisito de XP, ajustando o Nível dois para um, que
possamos
acioná-lo rapidamente Então, se eu for para o player SAN, abriremos o player dot TCN
e, em seguida, vamos para
o controlador de estatísticas, acredito que foi onde o
definimos E a definição do nível, temos o primeiro nível
aqui definido em dez XB necessários Vamos mudar isso
para um bem rápido. E então talvez eu adicione
alguns níveis extras. Então, podemos fazer um nível três
aqui como a nova chave
e, em seguida, vamos fazer
uma nova definição. Vamos fazer com
que esse precise de dez. Então, adicionaremos esse par de
valores-chave. Você pode adicionar
quantas quiser aqui. Então, isso é
basicamente uma lista gigante dos
níveis que estamos tentando definir aqui à esquerda e
a definição
de aumento de
nível de estatísticas à direita Então, no nível quatro,
podemos obter, eu diria, 20 XP necessários, e isso
aumenta o HP em dez E continue
como quiser. Então, nível cinco, digamos
30 X P e L nível dez. Vou detalhar isso para
que eu realmente não
precise me preocupar com isso muito
mais tarde. Vamos fazer o nível sete. Então, nova definição de nível. Digamos 50 XP,
adicionaremos o par de valores-chave, sete, e faremos uma nova definição de
nível com 100 XP e adicionaremos isso. E acho que isso deve
ser bom principalmente para nosso protótipo com
sete níveis diferentes Definitivamente, é o
suficiente para testar as coisas. Então, temos essas definições de nível
configuradas ao subir de nível, emitirão o
sinal de alteração de nível
do nosso controlador de estatísticas Então, queremos nos conectar
a isso em nossa nova interface de usuário, que nos fornecerá
a opção de escolher um dos três itens diferentes
ou aumentar o nível dos recursos. E queremos que o
jogo seja pausado enquanto nosso jogador
faz essa escolha Então, vamos criar uma nova interface de usuário. Vou adicionar um novo nó de
controle aqui, aumentar o
nível da seleção,
acho que é um nome decente, e adicionaremos um novo
script a isso. Então, nível U select dotGD. Vamos salvar isso na pasta
UI, é claro. Então, faça a interface do usuário e, em seguida, abra e crie. Ok. Além disso, controle para salvar a cena ao lado de
onde o script está. Então, isso também está na pasta UI.
Vou guardá-lo lá. Ok, agora vamos
começar a trabalhar no roteiro. Vou fazer a seleção do nome
da classe para cima. Geralmente, a menos que algo
seja especificamente um script de uso único
que nada mais
precise referenciar, quase sempre
criarei um nome de classe,
se isso não estiver claro
até agora um script de uso único que nada mais
precise referenciar, quase sempre
criarei um nome de classe, . simples fato de ter um nome referenciável facilita muito o trabalho entre
scripts Ok, então a maneira
mais rápida de obter a referência
ao controlador de estatísticas do jogador é você adivinhar. O contexto
do jogador. Então, vamos adicionar export var, o contexto, que será o contexto do
jogador aqui. Controle S para salvar isso. E então, no inspetor, vamos carregar
rapidamente o contexto de um jogador do nosso jogo, e isso basicamente
nos dá a referência ao jogador e, portanto,
ao controlador de estatísticas Ok, e então, na função
underscore ready, queremos ir para o contexto dot
player dot stats dot level Chang e nos conectar a ele
com um nível de jogador alterado, que será uma nova função que
criaremos logo Portanto, sublinhe a função de sublinhado
na mudança de nível do jogador. E isso fará com que o objeto de dados
de mudança de nível. Então, dados P são o que eles
chamam de dados alterados de estatísticas. Portanto, só queremos realmente
fornecer a interface do usuário se os
níveis realmente subirem. Pode haver algumas
circunstâncias estranhas em que
decidimos que o nível pode
cair no futuro. Então, para evitar isso,
diremos que se a
alteração do ponto de dados P for maior que zero, sabemos
que ela está subindo de nível Ok, então quando o nível muda, só
queremos responder a ele subindo de nível,
não descendo de nível. Então, vamos dizer que, se a alteração do ponto pdata for
menor ou igual a zero, retornaremos aqui porque
não é uma condição
que queremos tratar Caso contrário, aumentaremos
o nível do jogador. Agora, por enquanto,
só vou escrever
o código para lidar com o aumento
de nível, um de cada vez, porque no contexto
do jogo atual, essa é a única maneira de
isso ser possível Então, vou escrever
pelo menos o protótipo do script para lidar com a subida
de nível apenas uma vez por vez Se, por algum motivo, você
pegou um objeto de 1.000 EXP e isso acionaria um aumento de
três ou quatro níveis, essa pode ser uma condição com a qual
você queira lidar mais tarde Mas acho que isso é um pouco desnecessário aqui, porque, de qualquer forma,
só vamos ganhar
um XP por vez Mas para esse script, por
enquanto, vamos
apenas subir um
nível por vez. Então, vamos criar uma função aqui. Vou
chamá-lo de seleção inicial. E então essa função,
que colocarei acima da seleção inicial da função nos
fornecerá três opções. Também mostrará a interface do usuário. Então, podemos começar
com uma teleconferência aqui. E então também queremos
pausar o jogo para que possamos dizer que colocar três pontos em
pausa Ok, então como estamos
pausando o jogo aqui, isso significa
que ele pausará
todos os scripts que estão configurados para estarem ativos
somente quando o jogo não estiver pausado, o que
é o padrão Então,
aqui à direita, em node process, precisamos mudar
o modo aqui para,
acho que sempre, para que ele sempre
possa acionar coisas
dentro do jogo, independentemente de estar
pausado ou não Porque também queremos poder
abrir o script quando o
jogo não estiver pausado Portanto, ser capaz de chamar a seleção inicial durante um jogo
sem pausa será importante Então, acho que fazer isso
sempre faz sentido. Mas definitivamente queremos que ele seja executado enquanto o jogo está pausado Mais tarde, precisaremos
entrar aqui e gerar uma lista de recompensas que
mostraremos ao jogador. Primeiro, precisaremos configurar um pouco a
interface do usuário para isso. E também queremos ter
certeza de que isso
foi testado até agora para que
esteja realmente aparecendo Vamos clicar com o botão direito do mouse
na
seleção de subida de nível e adicionar alguns componentes de
interface de usuário a ela. Então, vou começar com, digamos, um contêiner de painel, e isso nos permitirá
vê-lo quando ele aparecer na tela Além disso, clique na interface raiz. E então vamos mudar, vamos
ver, layout no canto superior esquerdo e o capset
aqui. Então, aí mesmo. Também quero ter certeza de
que o mouse não impeça os cliques
, mas na verdade vamos
ignorá-lo por enquanto Queremos clicar em coisas na
interface, como botões
para fazer a seleção,
mas não queremos que a raiz da interface bloqueie
os sinais do mouse
e da porta. Então, vamos ver se podemos fazer com que
isso apareça ao subir de nível. Vamos até a raiz e adicionarei a seleção de subida de
nível. Então suba o nível do sublinhado, e vamos colocá-lo
sob a camada de tela Vamos mostrar temporariamente a interface do usuário. Ok. E vamos
querer que isso realmente esteja no
centro da tela. Então pegue a seleção de subida de nível e vá para o layout
no canto superior direito, e vamos
centralizá-la aqui. Então, centralize e, se diminuirmos o zoom, teoricamente, isso deveria estar no centro da tela Então, vamos atingir o
nível dois e o jogo, e veremos se isso
está realmente funcionando. Então, eu vou até aqui. O jogo fez uma pausa.
Não vejo isso aparecendo, mas é um bom começo. Então, pelo menos sabemos que está sendo
acionado em Lavote. Então, estou pensando que o que pode
estar causando o problema aqui é que a
escala da camada Canvas está definida como quatro. Vamos fazer esse desse jeito. Ok, e então eu quero um
filho para a camada Canvas, que na verdade vou
usar para o dimensionamento. Vamos clicar com o botão direito
na camada Canvas e adicionar um nó de controle aqui. Então, vou pegar os outros nós e criar a raiz. Portanto, esse nó será a interface do usuário. Ok, também
precisaremos assumir o controle da interface do usuário, a raiz aqui que
acabei de criar. E vamos pegar as âncoras predefinidas e
criar esse retângulo completo Então, agora que isso vai se estender
até o tamanho do ponto de vista,
queremos garantir
que o mouse esteja configurado para
ignorar, para que isso
não bloqueie os sinais da interface Ok, e então, se tivermos a seleção de subida de nível
aqui definida no centro, podemos realmente ver que esse é o verdadeiro centro
do ponto de vista Então, aqui está o nó de controle da
interface raiz
e, em seguida, ele está no centro. Então, se eu clicar em Jogar agora e
pegarmos um XP, isso
aparecerá no centro, embora estivesse
mostrando o bit padrão. Então eu tenho que esconder isso primeiro. E agora vamos clicar em Play. Nós vamos aqui, e você vê que ele aparece, além de
pausar o jogo Ok, então esse script está funcionando. Precisamos redimensionar nossa
HPUI aqui novamente. Então, na verdade, vou
clicar na interface do usuário aqui e vou aumentar
sua escala diretamente. Talvez seja o mais
apropriado escalar os
componentes individuais em vez de aplicar uma
escala global a tudo. Então, podemos simplesmente dimensionar nossa seleção de jogos de
forma adequada. Portanto, outra vantagem de ter a interface do usuário aqui é que, se
quisermos aplicar um tema a tudo abaixo,
podemos simplesmente acessar
o tema no canto inferior direito e carregar
rapidamente o tema do jogo. Então, agora tudo estará
usando essa fonte Pixar, mesmo que não a atribuamos diretamente à seleção de subida
de nível Então, às vezes você quer controle
refinado sobre
os temas individuais Se você quiser um
tema personalizado para, digamos, a seleção de subida de nível, basta criar um
novo aqui embaixo. E acho que nos níveis
mais baixos, ele substitui tudo o que
está acima Então, você pode basicamente ter
uma hierarquia de temas como essa, porque nem tudo precisa substituir
todas as propriedades Você pode ter um tema principal
e, em seguida, para coisas muito personalizadas, como a aparência de uma barra deslizante,
você pode fazer isso como um sub
43. L42 Como aprimorar o layout da UI e o texto animado: Vamos trabalhar
na criação de
nosso modelo de interface de usuário para a seleção de subida de
nível. Então, já temos
um contêiner de painel. Acho que devemos
esticar isso, então vou puxar o canto inferior direito
e movê-lo um pouco maior. Precisaremos de
uma interface de usuário muito maior para realmente mostrar nossa seleção. Agora vamos precisar
de um cabeçalho. Talvez mostremos um gráfico.
Tipo, parabéns. Você subiu de nível
algo assim. Então, precisamos de três exibições de
colunas. Esses serão contêineres VBox, que mostrarão nossas opções Então, provavelmente será
como um texto de título, um ícone, uma descrição
e, em seguida, um botão de seleção. E quando o
botão de seleção for pressionado, a seleção de subida de nível
processará a seleção, aplicará ao jogador,
fechará a interface do usuário e
retomará o jogo. Então, vamos clicar com o botão direito do mouse em
nosso contêiner de painel e adicionarei
um contêiner de margem como próximo nível,
adicionarei um nó filho. Então, estamos procurando um contêiner
de margem. E então, nas
substituições de tema à direita, vou pegar
essas margens e definir cada uma
delas em cinco
pixels por enquanto Isso só fará com que
pareça um pouco mais bonito , para que tudo não fique tão
agrupado Vamos clicar com o botão direito do mouse no contêiner de
margem e agora adicionar um contêiner VBox Assim, podemos organizar
todo o resto verticalmente. Você já pode ver
o contêiner de margem, meio que espalhando as bordas
um pouco para os lados. Queremos adicionar a isso,
provavelmente, nosso texto do título. Portanto, podemos adicionar isso como
um rótulo de rich text. Tudo bem, clique em Adicionar uma etiqueta
secundária em Rich Text. O motivo para
torná-lo rico
em texto em vez de um
rótulo normal é que, em textos ricos, você pode fazer coisas como código BB, que é bom se
você quiser aplicar um efeito de arco-íris ou balançar
o texto para cima e Portanto, é apenas mais poderoso
do que um rótulo de texto normal. Tenho certeza de que
tecnicamente tem um custo de recursos
associado a ele, mas alguns textos animados
na tela não
vão atrasar você Então, vamos colocá-lo aqui, subindo o
nível do texto. Podemos ver que não está
realmente surgindo aqui. Portanto, precisamos revisar o conteúdo
adequado e verificar se ele é verdadeiro. Agora nosso texto vai
aparecer lá no centro. Também queremos
centralizar esse texto, então mudaremos o
alinhamento horizontal aqui para o centro Ok, agora está centralizado.
Vamos colocar um ícone abaixo para que possamos mostrar um
gráfico de quatro horas acima Então, vou clicar com o botão direito do mouse no contêiner
VBox e
adicionar um nó filho Digamos que um rack de textura. Adicione isso e podemos
selecionar uma textura. Portanto, qualquer gráfico que quisermos usar
em nosso projeto funcionará. Vamos ver se podemos carregar algo
rapidamente. Então, se eu pesquisar, digamos 64 por 64 para obter a textura de maior
resolução, vamos pegar
um desses ícones, um que queremos usar e
depois aumentá-lo ainda mais. Então, eu realmente queria usar isso como parte de
uma textura de atlas Então, se você o selecionou,
clique com o botão direito do mouse e vá para Copiar. E no menu suspenso
aqui, faça a textura do atlas. Clique na textura do atlas
e, em seguida, clique com o botão direito do mouse em
colar o final do atlas Agora podemos selecionar qual ícone
queremos usar a partir disso. Então, qualquer coisa
que você ache que parece boa, há muitas opções. E esta é a folha de sprite de textura de
64 por 64
do pacote de ícones Isso era óbvio, então um
dos três ativos artísticos
que temos para o projeto. Então, algo como
essas espadas gêmeas ou a espada brilhante
poderia funcionar muito bem Qualquer coisa que fosse como
uma figura humana brilhante, meio que implicando
: Oh, eu subo de nível Eu fiquei super forte, como, por exemplo, especificamente
assim, ou no projeto base,
usei esse, que é mais um raio,
mas também poderia funcionar Ok, então desta vez,
vou escolher aquele em que parece um feixe de
luz gigante em vez de um raio E vou bater de perto. Portanto, temos nosso ícone exibido
na textura reta. O alongamento não é
realmente como queremos,
então queremos mudar
o modo de alongamento
para manter o aspecto centrado, acredito que seja a
melhor opção aqui E isso funcionará muito bem, acho que, seguindo
nosso ícone de subida de nível, vamos adicionar um bloco de texto, que
diremos ao jogador : queremos fazer uma
das poucas seleções Então, vamos clicar com o botão direito do mouse
no contêiner do VBux, adicionar outro rótulo de rich text e,
em seguida, faremos
algo semelhante Verifique a adequação ao conteúdo. E então, para o
texto, diremos, escolha uma das opções de
subida de nível abaixo. Como pretendemos que a fonte
Pixar apareça aqui em nossa tela real vez de ir
ao mundo toda vez, para verificar como ela ficará
com o tema real do jogo, vamos até a seleção básica de aumento de nível do
nó da interface e atribuir o
tema aqui também Então, no inspetor, carregue
rapidamente o tema
e, em seguida, isso
atualizará nosso texto Agora você pode ver que,
com essa fonte diferente, o texto realmente
cabe em uma linha. Essa é uma grande diferença.
Vamos clicar no rótulo Rich text dois
e centralizá-lo. Ok, a seguir, vamos
pegar esse título e torná-lo um pouco
mais interessante adicionando um arco-íris e um efeito de
onda com o código BB Então, verifique o código BB ativado
aqui e vá para o início
do texto no canto superior esquerdo. Vamos colocar
colchetes para código BB,
arco-íris e, em seguida, espaço FREQ
para frequência igual a 0,5
espaço SAT é igual Essa é a saturação.
O valor do espaço é igual a um e, em seguida, finalize os
colchetes e você terá um
efeito arco-íris aqui Agora, para garantir
que isso termine, você vai até o final do texto
e, em seguida, coloca
colchetes Rainbow E aí temos
nosso efeito arco-íris animado na janela de exibição E também podemos alterar
as configurações aqui. Então, se você
quiser que seja menos vibrante, tente levar a
saturação para 0,5, e agora você terá um
arco-íris mais manso aparecendo lá Eu meio que gosto disso,
então vou ficar com ele. Agora, vamos também adicionar
o efeito de onda. Então, volte para casa novamente para ir para
o início da nossa caixa de texto, ou você pode simplesmente clicar
lá no canto superior esquerdo Em seguida, faça outros
colchetes e
digitaremos WA VE para o espaço de
onda AMP para a
amplitude igual a 50 Essa é a altura que ela
vai entre as ondas. E então a frequência espacial
ou FREQ é igual a dois. Essa é a frequência com
que ele faz uma onda e depois termina com o colchete
direito Ok, e então você quer ir
até o fim depois
do arco-íris aqui em cima e
fazer os colchetes Isso significa que, se você
adicionar texto extra depois disso, ele não terá o efeito de
onda porque
encerramos o efeito
em nosso bloco de texto. Então, Controle Z, podemos ver nosso texto sendo animado lá.
Isso é muito legal. Talvez queiramos
que a amplitude diminua um pouco, então vou reduzi-la para 30 Então, se
assistirmos à nossa animação, podemos ver que
o texto é animado praticamente na parte inferior ou superior
da área da etiqueta Acho que se tivermos uma
amplitude de 50, como tínhamos antes mesmo de ser
cortada. Então isso não é o ideal. Se estiver muito
subindo ou descendo, podemos adicionar um pouco de preenchimento a esse rótulo específico
acessando substituições de tema E então queremos ir
para estilos normais e
deixar uma nova caixa de estilo vazia
porque não há plano de fundo. Expanda isso, vá para as margens do
conteúdo
e, em seguida, podemos fazer
a parte superior e inferior, alguns pixels de deslocamento Então, vou tentar
fazer com que a parte superior seja menos três e a parte inferior
menos três. E então o que podemos fazer é adicionar uma margem de conteúdo aqui
na parte superior e inferior. Então, vou fazer com que seja como dois pixels na parte superior e dois
na parte inferior. Ok, e isso
basicamente fará com que nossa caixa fique um pouco
maior do que
seria por padrão. Então, essa é outra solução se
você não quiser simplesmente adicionar um monte de novas
linhas na caixa de texto. Acho que essa também seria
outra opção mais rápida. Mas também um pouco menos
preciso. Então, finalmente, para isso, se quisermos que o
texto seja maior, podemos acessar as substituições de temas e personalizar os tamanhos das
fontes Então, acho que queremos um tamanho de fonte
normal, e vamos aumentá-lo para 24. Ok, esse realmente
parece um pouco embaçado. Vamos tentar 32, certo? Ok, então eu acho que para
essa fonte específica porque é a Pixar, existem números de escala
muito específicos os quais você precisa definir
o tamanho do pixel Então, se eu dissesse que é
algo como 22, acho que não é um múltiplo de oito ou 16, então
não vai funcionar. Então, vamos fazer 32 em vez de tê-lo lá para que
seja renderizado corretamente. A
propósito, essas substituições, se você quiser, você também pode dedicar algum tempo
personalizando-as e os
temas especificamente Mas se for algo único como esse, talvez
seja mais rápido atribuir
seus valores personalizados especificamente a esse cabeçalho Somente se você tiver
muita interface de usuário em todo o jogo e quiser
personalizá-la em um local centralizado
, fazer muitos
temas faz sentido Em vez de
usá-lo apenas para fontes, você também pode personalizar os tamanhos das fontes ou
adicionar cabeçalhos personalizados
44. Ladrilho 43 Projetando a UI de seleção de recompensa e ajustes finais: Tudo bem, agora
precisamos criar nossas caixas de seleção verticais Então, isso vai ser uma subinterface de usuário. Vou criar um
novo nó aqui em cima. Digamos que seja uma interface de usuário,
mas vou clicar com o botão direito do mouse aqui e mudar seu tipo para
um contêiner de painel. Vamos apenas transformar a raiz
aqui em um contêiner de painel. E isso será em tamanho real por padrão, expandindo-se
em todos os lugares. Vamos renomeá-la para Seleção
de recompensas. E vou
salvá-lo na pasta UI. Ok, agora vamos
para a seleção de Lavop, e vou colocar três
delas na hierarquia Então, procure uma recompensa
no projeto e coloque
uma delas no VBox Vou duplicá-lo mais
algumas vezes. E você verá que o problema
imediato é que existem três, mas
são todas verticais. Portanto, precisamos de outro contêiner
HBox para torná-los horizontais Então, clique com o botão direito do mouse no contêiner VBox e adicione um contêiner
HBox do nó filho e coloque as três seleções de
recompensa sob o Agora você deve ver se você
clicar no contêiner HBox se cada um deles tem uma
posição de deslocamento um do outro Mas, no momento, eles não
se estendem pela tela. Então, precisamos ir para a seleção de
recompensas, que será o
layout, o tamanho do contêiner Queremos expandir na horizontal. E já que estamos
nisso, vamos expandir verticalmente também. Controle para salvar, volte para a seleção de subida de
nível. E agora podemos ver que eles estão meio que no sentido de uma coluna. Cada um deles ocupa um
espaçamento uniforme do espaço
da esquerda para a direita e se encaixa no contêiner
do painel principal Então, isso é mais parecido com
o que estamos procurando. Na seleção de recompensas,
vamos clicar com o botão direito do mouse na parte superior e adicionar um nó. Então, isso vai
ser um rótulo Rich Text no rótulo Rch text,
vamos colocar o texto Diremos o nome do colchete e eu verificarei o conteúdo do Fit Podemos ampliar aqui para ver. Então, para a seleção da recompensa, vou clicar em Seleção de recompensa, e vamos pegar a predefinição da âncora
e vamos pegar a predefinição da
âncora e virar no canto superior esquerdo, ok E aqui embaixo, precisamos de
um contêiner de margem. OK. Então, se olharmos aqui,
se olharmos aqui, não
há espaçamento entre nossos rótulos e a
borda desse painel Então, vamos adicionar um contêiner de margem abaixo da seleção de recompensa. Clique com o botão direito do mouse em Adicionar contêiner de
margem secundária
e, em seguida, torne o
rótulo Rich text filho dele. O contêiner de margem substituirá constantes de
tema
e, digamos, talvez três
pixels para as margens esquerda, superior, direita e inferior
aqui Agora vamos pegar a seleção de recompensa
raiz e vou mudar
sua predefinição de âncora para,
digamos, canto superior esquerdo Mas também vamos analisar
a seleção de recompensas e ampliá-la
um pouco para que possamos pelo menos ver com o que
estamos trabalhando aqui. Não precisamos esticar a tela
inteira porque
isso é enganoso, mas queremos poder
ver nosso conteúdo vertical E podemos ir para a seleção de aumento de
nível para ver como isso
vai ficar em qualquer momento após o redimensionamento
e esse contêiner de interface Até agora, parece bom. No entanto, queremos centralizar
esse título. Então, vou clicar
no rótulo Rich text e vamos fazer o centro de
alinhamento horizontal Além disso, para o
dimensionamento vertical do contêiner aqui e o controle, quero começar com o Shrink Então, isso garantirá que ele não se expanda
mais do que o necessário. Se formos para aumentar o nível de seleção, veremos nossos rótulos
centralizados aqui Ok, agora precisamos do nosso espaço reservado para
ícones. Então, clique com o botão direito
do mouse em Margin Container, adicione uma textura reta
e, em seguida, podemos selecionar um
ícone do nosso projeto Então, vamos fazer uma nova textura do Atlas. E aqui, vou carregar rapidamente um ícone de atlas
do pacote de 16 por 16 Vamos fazer essa região e
selecionar um espaço reservado. Então, algo para subir de nível, algo assim
parece muito bom. E vou bater de perto.
Agora, precisamos ter certeza de que isso está
realmente organizado corretamente, então
precisaremos de um contêiner VBox
sob o contêiner de margem Então, clique com o botão direito do mouse no contêiner de
margem, adicione um
contêiner VBox pregado como filho e transforme o título e a textura em filhos dele Ok, agora vai se
organizar adequadamente. precisamos garantir que
isso mantenha sua proporção, No entanto, precisamos garantir que
isso mantenha sua proporção, para que
não pareça estranho Portanto, no inspetor de texto,
altere o
modo de alongamento para manter o aspecto altere o
modo de alongamento para manter o Também deve manter o
aspecto centrado. OK. Lá. Isso
parece mais apropriado. Talvez também queiramos acessar o layout e definir um tamanho
mínimo de ícone. Então, aqui, vou pegar
o tamanho mínimo personalizado e dizer algo
como 48 por 48. Ok, isso meio
que expandirá isso. 32 por 32 é bom. Então, isso significa que se seu
ícone for menor que 32 por 32, ele será automaticamente
escalado para esse tamanho. Ok, vamos adicionar um texto
descritivo, para que eu possa controlar C
o rótulo de rich text e, em seguida, clicar no contêiner VBox,
controlar V e colá-lo E colocaremos a descrição
entre colchetes aqui. Obviamente, podemos ver que isso é muito grande para essa área, então talvez precisemos trabalhar
em nossos tamanhos de fonte posteriormente. E então, por fim, queremos um
botão para selecionar a opção. Então, vou clicar no
contêiner vBox e adicionar um botão. Então, aqui provavelmente vamos
querer
apenas um botão normal. O que permite que você tenha um ícone,
para que possamos
carregar rapidamente um ícone de teste, mesma forma que fizemos antes, com menos textura, expandi-lo. Carga rápida da folha de sprites de 16
por 16. Faça Editar região e
escolha um ícone. Então, talvez algo como a espada com um símbolo de
subida de nível faça sentido. OK. Agora podemos ver
nosso botão como um ícone. E então, na
caixa de texto, poderíamos dizer escolha indicando o que
estamos fazendo aqui Agora, se formos até nossa janela de seleção de subida de
nível, podemos ver nossas três partes
da interface aparecerem aqui embaixo, temos três botões que
conectaremos para escolher mais tarde. Temos nosso título animado. E é mais ou menos assim que nosso modelo
vai ficar. É só uma questão de fornecer as opções de seleção, conectá-las ao nosso jogador
e, em seguida, atualizar nosso jogador
assim que ele fizer uma Será
apenas uma questão de preencher a lista
com as opções
disponíveis e
aplicá-las
ao jogador assim que ele fizer sua seleção Ok, então você pode
notar que há um pequeno problema em que
às vezes a borda de nossos ícones meio se sobrepõe
aos ícones vizinhos Então, para corrigir isso, podemos acessar
a seleção de recompensas e verificar o clipe do filtro.
Para o botão. Então, quando você fizer isso, se você for até aqui e aumentar e diminuir o
zoom, isso deve resolver o
problema ali mesmo, para que você não veja mais pixels
sobrepostos Além disso, para o nível de
seleção no mundo, ele pode estar tecnicamente
centrado aqui Mas você pode ver
que está indo para baixo e para a direita a partir
desse ponto central. Então, na verdade, não vai
aparecer centralizado na tela. Para editar isso, acho que
seria uma boa ideia pegar
nossa camada Canvas e clicar com o botão
direito do mouse em
salvá-la como uma nova cena
em nosso projeto de interface do usuário. Então, vou dizer gameplay UI Canvas como nome, e
então vamos abri-lo. Ok, agora, se olharmos para Hue, podemos
ver com muito mais clareza onde nossos objetos estão posicionados na tela e
seu tamanho em relação
ao ponto de vista, vez de ter uma visão de mundo
desordenada Então, podemos ver, é claro, que
nossa seleção de jogadores, UI, precisamos clicar nela e
provavelmente dobrar o tamanho. Então, em escala, vou pegar a escala e
fazer dela dois. Isso pode até
precisar subir para três. Sim, vamos escolher
três por padrão. Ok, então, para lidar com
esse problema nosso contêiner de painel
basicamente vai para
a direita e para baixo, em
vez de ficar centralizado aqui Queremos entrar na cena de seleção de
Love Up e depois ir para o painel de
contêiner, eu acho. E à direita,
precisamos levar
o modo de layout para âncoras
e depois centralizá-lo aqui Sim. Ok, aí. Agora
temos o que estamos procurando. Então, isso basicamente faz com que
tudo o que é um subobjeto seja centralizado
nesse ponto de ancoragem,
onde, se
formos para a interface do usuário do Canvas agora, ela será
centralizada corretamente Ok, muito rápido, vamos
entrar no roteiro da seleção de
Llevo E quando estiver pronto, queremos
ocultar nossa seleção de subida de nível. Então, vou
digitar e me esconder aqui. E isso garantirá que,
quando iniciarmos o jogo, ele se esconda por padrão. Vamos clicar em play. Vamos
para o LeveOp obtendo EXP. E aí temos nosso seletor
LevelUp pop-up. Temos três botões para
escolher . Eles ainda não
fazem nada. Podemos decidir mais tarde que não
queremos pausar a música,
como o que acabou
de
acontecer, mas, além disso , tudo está funcionando O jogo está completamente pausado
e nossa interface está aparecendo.
45. P44 Criando um sistema de classificação de armas para atualizações de jogos: Para que nosso sistema de subida de nível funcione, na verdade, precisamos de
algumas atualizações para
preencher a lista aqui
do nosso menu de subida de nível Então, geralmente, serão
atualizações de armas. Portanto, também precisamos configurar
um sistema de nivelamento para nossas armas Então, se olharmos para
a cena do jogador, temos a arma de
lança padrão, que tem uma definição de
arma Portanto, a definição
de arma é muito simples
aqui por enquanto, mas precisaremos
adicionar uma atualização de arma. Mas adicionaremos
aqui uma série ou dicionário de
atualizações de armas para que possamos avançar para o próximo nível e realmente obter quanto dano essa arma deve causar em
qualquer nível, para que ,
quando lançarmos nossa arma, ela use as configurações
apropriadas E isso também pode
incluir coisas como o tempo de resfriamento ou quantos
alvos uma arma pode atingir. Há muitas propriedades
diferentes que você pode configurar para
seu sistema de armas. Então, se entrarmos no script de armas de
lança, podemos avançar
na definição da arma Você pode ver aqui que eu já criei um método de resfriamento, que retornará
com base no nível no resfriamento da arma Então, aqui, se
definirmos nossa matriz e passarmos o nível
real da arma, poderemos recuperar o conjunto correto de estatísticas
de nossa arma no
nível atual E então também
precisaremos gerar um método get seen. Então, atualmente, isso
é apenas carregar a cena da lança diretamente Mas quando estamos
aprimorando nossa arma, podemos adicionar a opção cenas de
projéteis
completamente diferentes gerar cenas de
projéteis
completamente diferentes, mas não queremos necessariamente fazer isso em todos os níveis,
então poderemos
fazer com
que ela volte ao projétil
da arma original e simplesmente atualizar Então, vamos fazer isso
criando algo como um nível de arma ou uma definição de
nível de arma. Então, vou
para o sistema de arquivos e vamos para as armas. Vamos clicar com o botão direito do mouse e
criar um novo script aqui. E então vou chamá-lo de
algo como nível de arma, que por si só será um recurso. Então, vamos criar isso.
Abra o script do nível da arma. Vamos até o topo e criaremos o nível de arma com o nome da
classe. Então, isso define as estatísticas da arma nesse nível
específico. Portanto, uma arma pode ter
quantos níveis você quiser e progredirá em
potência à medida que for atualizada. Assim, podemos colocar
aqui algumas estatísticas que gostaríamos de
poder acessar para um
nível diferente da arma. Então, um óbvio
seria o resfriamento. Então, podemos dizer que em export var, esfrie, e isso
será um float, e podemos usar como padrão 1.0 Ok, então vamos salvar
isso bem rápido. Vou fechar todos os
meus outros scripts aqui, então clique com o botão direito do mouse e feche tudo para que possamos
ver o que estamos fazendo. Ok, e então abra o
nível da arma e a
definição da arma aqui. Ok, então esses seriam os únicos dois com os quais estamos
trabalhando aqui. Então, nós queremos, eu diria, um dicionário, se quisermos ser consistentes com
nossos níveis de jogadores. E no Export VR, níveis, que serão um dicionário de números inteiros e o nível da arma Então, para o tempo de recarga do Git, queremos obter o
nível e, em seguida,
retornaremos o tempo de recarga
das estatísticas do Então, o nível de VR será igual aos níveis dot Git e obteremos
o nível P. E retorne null por padrão. Então, agora queremos remover
o sublinhado do nível P porque
finalmente estamos usando essa variável Agora, ele não pode inferir
o tipo aqui, então temos que dar a ela o tipo de nível
concreto da arma
e, em seguida, retornaremos o tempo de recarga de pontos de nível Ok, então clique com o botão direito no nível da
arma e faça o símbolo Loup. Ok, certifique-se de que está
realmente lá. Então, em get cooldown, ele encontrará o nível
da arma Se não conseguir encontrar
o nível da arma, na
verdade haverá
um erro aqui. Eu pude ver que estamos
usando muito essa linha. Então, na verdade, eu também vou
colocar aqui uma função de nível de arma Git O que exigirá
um número inteiro de nível P, e isso
retornará um nível de arma Então, podemos simplesmente devolver isso. E então, em vez disso, o que
podemos fazer aqui é ,
digamos, obter o nível da arma. Passe um ponto de nível p igual para baixo. Agora, uma boa razão pela qual
faríamos isso é que se quisermos
adicionar algum código posteriormente, digamos que
não haja um nível de arma e queiramos usar o nível anterior como
padrão, ou queremos dividir o erro. Podemos fazer tudo isso dentro
dessa função G (função de nível de arma). E então, em todos
os outros lugares que chamamos de Obter nível de arma, todo esse código extra será pré-manipulado Então, isso meio
que configura se
precisarmos fazer com que a função seja danificada, função g max atinja,
etc Isso reduzirá
nosso código posteriormente e o centralizará
nessa Mas, por enquanto, especialmente quando estamos fazendo protótipos, acho que definitivamente quero
saber imediatamente se
esqueci de configurar um nível de arma em que
esperaríamos que
houvesse um nível de arma definido
na definição da arma Então, na verdade, estou totalmente acordo com o fato de que isso gera
um erro
assim que tentamos
reduzir o ponto quo em um nível de arma nulo É por isso que vou
deixar as coisas assim por enquanto. Ok, agora vamos entrar no nível da
arma e configurar algumas outras propriedades
que queremos modificar por nível. Outra óbvia seria o dano que uma
arma pode causar. Então, em export var damage, podemos
realmente causar danos aos homens ao MAX, se quisermos que
seja um pouco mais interessante. Então, se dissermos em export
var men damage, e digamos que seja um float, podemos padronizá-lo para 10.0, e então temos em
export var Max damage,
que será um float que será um E vamos definir
isso como 20 por padrão, quaisquer números que você considere um bom ponto de partida,
você vai ajustar. Quase sempre para cada recurso de nível de
arma. Como
mencionei, provavelmente também queremos o máximo de acertos Então, no Export V, o máximo
de acertos será um número inteiro Vou defini-lo igual a 1,0. Ah, além disso, o
dano masculino e o dano MÁXIMO, esqueci que estamos lidando
com números inteiros no jogo, então vou mudar
isso para Então, vou mudar
isso para inteiro em ambos os casos para ser consistente Obviamente, você pode usar flutuadores em combinação com números inteiros Mas acho que,
nesse caso, quando
sempre queremos que o dano
não seja decimal, é melhor
ser
consistente em todos os nossos scripts OK. E então, da
mesma forma, o acerto máximo diz que o número inteiro não deve
ter um ponto decimal Provavelmente também
vamos querer uma variável de velocidade aqui em algum lugar. Então, exporte a velocidade da variável, e isso será uma flutuação Vou configurá-lo para 100,0, aproximadamente
pixels por segundo. Depois, um rápido comentário
lá também. Então, agora temos um
monte de propriedades. Queremos configurar
o recurso em nossa definição de arma de lança Ok, então vamos diminuir o zoom e
clicar na arma de lança. Aqui à direita,
temos nossos níveis de armas, então os configuramos. Portanto, o nível corresponde
não à posição da matriz, mas ao nível real
da arma. Então, queremos começar com um aqui. E então queremos criar
um novo nível de arma. Ok, então em nosso nível de arma, esses podem ser nossos conjuntos básicos. Por que não adicionamos
o par de valores-chave, e esse será o padrão
para nossa lança de nível um Vamos adicionar dois e
depois um novo nível de arma. E queremos aumentar
os danos aqui. Então, eu vou dizer 15 a 25, e talvez a velocidade
seja um pouco mais rápida, então 110 para a velocidade. Com o resfriamento, podemos lançar um pouco mais rápido, então vou dizer 0,9, e o máximo de acertos será
definido para um ainda porque adicionar um
golpe máximo extra é muito importante. Isso pode ser como dobrar
seu dano de forma eficaz. Então, vamos adicionar isso.
E então vamos fazer o nível três, novo nível de arma. Vamos dizer 20 a 25 de
dano, a velocidade, talvez 115, e depois
o resfriamento é 0,9, mas aumentamos o
máximo de acertos para dois Então você pode meio que
ter a ideia aqui. Quase sempre queremos que
alguns números subam. Eu acho que cada nível é um upgrade em relação
ao anterior. Não precisamos necessariamente
alterar as atualizações
em um fator linear Então, por exemplo, um nível pode ser um grande aumento de dano, mas a velocidade do
projétil permanece a mesma De qualquer forma, adicione isso e
continuaremos em quantos
níveis você quiser. Ok, então, para continuar,
vamos fazer quatro. Vamos colocar um novo nível de
arma aqui, e isso pode ajudar a expandir o nível de arma anterior para que você saiba o que precisa melhorar. Então, começamos com 20 homens danificados. Vamos fazer 25 de vez em quando e depois 30 para o dano do MX
e a velocidade,
120, o resfriamento de 0,8 O máximo atinge dois. Adicione um par de
valores-chave. Apenas continue. Ok, e acabei
de adicionar um quinto para me divertir. Então, nesse caso, você pode ver as estatísticas ali mesmo
se quiser copiar. Uma estatística importante que eu realmente
esqueci seria o número de projéteis
gerados Então, vamos exportar projéteis
var, e isso será um
número inteiro igual a Portanto, o número de
projéteis por instância por lançamento é uma propriedade muito forte Então, se quiséssemos
que um nível fosse extremamente forte
, poderíamos dizer,
talvez o nível cinco. Temos dois
projéteis por lançamento, e isso fará com que a arma
cause muito mais dano Agora, não queremos que os
projéteis apareçam exatamente
ao mesmo
tempo na maioria dos casos Uma forma seria
compensá-los para que você possa ver onde eles
vão aparecer Outra opção que você
pode adicionar
seria atrasar após a ocorrência de um lançamento, quanto tempo antes de cada
projétil se estender. Então, você poderia dizer, vamos realmente adicionar os dois
como uma opção. Então, poderíamos dizer em Export
var offset ou span offset. Vai ser um
carro alegórico. ser
igual a zero, zero. E então, na exportação de VR, atraso na geração é uma flutuação, e diremos 0,05 segundos Então, isso vai ficar
mais ou menos assim. desova é
o deslocamento máximo
para a posição de amplitude instantânea do projétil Então, a que distância
do ponto central
ele pode estar quando aparece E então, o atraso de alcance
será o tempo e segundos de espera entre os vãos
adicionais do projétil, e devo dizer que, após o primeiro, esse é o valor
chave Ok, então, no próximo vídeo, trabalharemos para pegar esses níveis de
armas e
fazer com que possamos realmente selecionar como
aumentá-los dentro de nossa interface de usuário.
46. Itens de armas P45 para aumentar o poder da sua arma: Ok, então, para a próxima
parte, precisamos introduzir
a habilidade de nossa interface de seleção de
subir de nível para obter o item para a atualização da
arma, para
que possamos aumentar o nível da arma que está realmente
ativa no jogo. Então, a primeira etapa será criar
uma lista de opções ou
recurso dentro de
nossa seleção de subida de nível, que
usaremos para preencher
as opções
aqui embaixo com base em
uma seleção
aleatória das viáveis disponíveis Vejo aqui no
canto inferior esquerdo que os projéteis estão
na pasta de níveis Na verdade, vou
transferir isso para armas que
façam mais sentido. Então, como não há nada
na pasta Levels, vou renomeá-la para configurações porque o que realmente
estamos fazendo é configurar uma lista de atualizações de armas
ou outras atualizações que podemos escolher
em nosso nível de E, na verdade, podemos
diferir isso, dependendo do personagem,
ou podemos diferir dependendo do nível que
estamos carregando em nosso jogo, mas queremos ter a opção personalizá-lo de qualquer maneira. Então, vamos
criar um novo script, e vou chamar essas opções de
nivelamento de ponto gD Este será um recurso, para que possamos editá-lo
no GIDOEditor E então eu vou
entrar aqui. E digamos que opções de nivelamento de
nomes de classes. No início do curso,
apresentamos os captadores. Agora, esses captadores só existem atualmente como uma cena
no mundo do jogo, coletados
e imediatamente a EXP é adicionada aos Então, não precisamos de um item especificamente porque essa
EXP só modifica uma estatística. Mas se quisermos
algo mais complexo, como um aumento de saúde ou a
habilidade de aumentar o nível de uma arma
, precisamos de uma classe de
item mais concreta dentro do nosso jogo, e praticamente
todos os jogos
do tipo RPG terão
isso em algum momento Então, queremos exportar uma lista de itens que podemos
usar imediatamente com nosso player. Então, vou
exportar itens, e essa será uma matriz de,
digamos, itens por enquanto. Agora, não
criamos uma classe de item. Então, vamos criar uma pasta no
canto inferior esquerdo para itens. Vou clicar com o botão direito do mouse e
criar uma nova pasta. Vou chamar esses itens. E aí dentro,
vou clicar com o botão direito do mouse e criar um novo script. E este será o item dot
gD que se estende de Resource. Ok, então dentro daqui, faremos o item do nome da classe. Especificamente para um jogo semelhante a um
sobrevivente, talvez não
tenhamos necessariamente itens que existam
em um inventário Portanto, eles ainda precisam
se inscrever imediatamente. Mas a forma como eles se aplicam
é mais complexa do que apenas o ExbPickup ser uma atribuição
imediata Então, para
que possamos aplicar nossos itens a um
jogador ou alvo, pelo
menos, vou
criar uma função. Digamos que a função try apply, que
pegará um alvo P, não dois D, e retornará um booleano Portanto, tente aplicar porque
pode haver circunstâncias
em que ele falhe, e pode ser
útil
em algum lugar do nosso código ter
esse feedback sobre se foi bem-sucedido ou
também podemos querer uma
função can apply para que
possamos verificar com
antecedência se ela é realmente
viável ou Então, direi que a função pode ser aplicada, e isso passará pelo
alvo, sem dois D e retornará de booleanos Então, por padrão, direi return false aqui porque
esse é um item básico. Não podemos aplicá-lo, e vou apenas dizer return
false aqui também. Então, vou colocar isso
em um aviso de que não
podemos aplicar o
item básico a um alvo
e, em seguida, vamos criar
nosso item de arma porque é com isso que estamos
mais preocupados primeiro. Então, vou
clicar com o botão direito nos itens, criar um novo script, e esse será o item de sublinhado da
arma, que será herdado do item como classe base,
então criaremos Então, item de arma aqui, vamos até o topo e criaremos item de arma com o nome da
classe
que é um nó dois D. Isso retornará Boolean Portanto, precisamos de uma forma de acessar o carregamento de armas do
personagem, se ele tiver um Então, uma forma simples de
dizer isso seria: far loadout é igual a p target dot find child, e vamos
procurar o carregamento de armas Está bem? E isso deve retornar
um tipo de carregamento de armas Então, vamos realmente mover isso
para sua própria função. Então, a função get loadout retornará a carga de
armas E então vamos devolver isso em vez disso,
devolver o carregamento de armas ptarget dot Fine
Child Então, precisamos passar
o Ptarget aqui. E então podemos inferir o tipo. Então, vou fazer dois pontos iguais,
obter carregamento no pTarget e depois retornaremos se
isso E então queremos
verificar se o carregamento tem
a definição de armas que estamos tentando aplicar no momento Então, poderíamos
exportar a definição de VR. E essa é uma definição de
armas , melhor dizendo. Ok, depois de obter o carregamento, queremos verificar se a arma existe ao
lado do Se isso acontecer,
veremos se
há espaço para subir de nível ou se já
atingimos o limite de nível. Então, dentro do carregamento, precisamos saber quais armas estão realmente embaixo dele
dentro desse sistema Então, quando estiver pronto, podemos obter todos os
carregamentos preexistentes
e, em seguida, adicionaremos um método
para que possamos adicionar um
novo que o
anexará à matriz,
mantendo referência a todas as Então, digamos que as armas var aqui uma matriz de armas dois D
e, na função
sublinhado pronto, que retorna vazio,
queremos pegar todas as crianças
do tipo arma Portanto, para arma, encontre crianças,
as aspas vazias da sequência padrão
não correspondiam ao nome Mas para o tipo,
vamos usar a arma dois D, e o revestimento é importante aqui porque esse é o tipo de nome da
classe Então, isso só devolverá
crianças por meio da arma
tipo dois D.
E então podemos dizer que armas pontuam a arma Penn. E agora, quando o script começa, temos todas as armas
pré-existentes. Poderíamos dizer que temos uma
função de adicionar arma, que usará uma arma
P,
que é um tipo de arma, dois D, em vez de Vitun vazia e
diremos armas, arma Penn E queremos ter certeza de
que é filho dessa arma. Então, fazemos isso em uma função. Diremos Adicionar filho da arma P. Isso vai ser bom por enquanto. Então, vamos entrar
no item de armas. Temos o carregamento para que possamos
verificar se ele já o tem. Então, depois de obter o carregamento, queremos obter a arma
associada a essa definição de
arma Então, digamos que nossa
arma será
igual à arma LoadOug,
com base em uma com base em Então, vamos
dizer a definição aqui. Agora, vamos entrar no
carregamento de armas e fazer
a função arma G,
com base na definição Então, definição P. É
uma definição de arma. Vamos devolver
uma arma para D. E digamos que para
arma em armas, se a definição da arma for
igual à definição P, vamos
devolver essa arma. Caso contrário, retornaremos null. Como só precisamos
vasculhar algumas armas, ter um pequeno loop como esse será
perfeitamente normal, não é realmente um problema. Além disso, se você quiser limitar
a quantidade de armas que um jogador pode ter
, você pode dizer
algo mais como, na exportação, as armas do VR Max são um
número inteiro de seis na parte superior E então poderemos verificar
se também há espaço. Então, podemos dizer que a
função tem espaço, e esse será um tipo de retorno
booleano, e diremos apenas que
devolver armas dot si é menor que o máximo de armas Ok, então isso é apenas uma
pequena força de função auxiliar Agora, de volta ao item de arma, se eles têm a arma, queremos ver se
podemos subir de nível. Pode até fazer sentido declarar a
arma do tipo dois D aqui, embora isso já tenha sido
inferido da chamada de função
da arma Ok, então primeiro, se não
houver arma, então se a arma for igual a nula, retornaremos que a carga tem espaço
para determinar se
podemos aplicar Porque se a arma não
existir no sistema de armas, só
precisamos ver se há
espaço para adicionar uma nova. Caso contrário, se houver uma arma, queremos ver se
podemos subir de nível. Então, diremos que devolva a arma. Pode ser algo como subir o
nível C ou ter o próximo nível. Acho que Has Next Level
soa como um bom nome para. Então, agora precisamos dessa função dentro de nossas
armas para o script D. Então, em armas para D, queremos
usar o nível em relação à definição e apenas verificar
se há um próximo nível. Então, na parte inferior, vamos criar nossa função. Portanto, a função tem o próximo nível. Isso retornará Boolean. Então, digamos que a
função funcione no próximo nível, que será um nível de
arma igual à definição Obtenha o nível
de arma do nosso nível atual mais um, que pode retornar nulo Então, retornaremos que o próximo
nível não é igual a nulo. Porque se
houver um próximo nível
, podemos atingir o próximo
nível. Podemos subir de nível. Se não houver, então
atingimos o limite de nível ou
esquecemos de definir um nível Então, podemos ter
definido o nível sete, mas definimos o nível
seis quando estamos no nível cinco? Porque cinco pode ir para seis, mas não podemos simplesmente pular para
sete, pelo menos normalmente. Então, isso deve atender às nossas necessidades para verificar
se podemos nos inscrever. E então, se
vamos aplicar, diremos função, aplicar. E deixe-me verificar a classe
base aqui só para ter certeza de que tentaremos aplicar. Na verdade, pode fazer
sentido copiar isso. OK. E então vamos
substituir isso aqui embaixo apenas declarando novamente
a mesma função Então, primeiro, precisamos pegar
a arma se
quisermos nos inscrever. Então, a arma Var é uma arma dois D, e isso vai ser igual à arma
LoadOug de Então, se a arma não estiver
lá, então já falhamos. Então, se a arma for igual a
nula, retornamos as quedas. Mas também precisamos
obter o carregamento novamente. Portanto, os carregamentos de
Var serão do tipo inferido do alvo
G loadout Então, estamos obtendo a carga no alvo
ao qual estamos
tentando nos candidatar Então, uma vez que
temos a arma, queremos usá-la. Então, vamos dizer que a
arma dot-tri sobe de nível, e isso retornará, independentemente de
termos sucesso ou não Então, retornaremos esse valor. Agora precisamos definir a
arma dot tri level up e arma two D. Então, vamos
descer aqui e ver a função, função tri level up, e vamos
retornar um Ok, então vamos dar uma olhada no topo do nosso script em D de arma 2. Podemos ver que temos o nível e o nível
da arma existe na definição da arma para ser um pouco mais
eficiente e poder acessar nossas informações
atuais. Depois de já termos subido de nível, também
poderíamos ter uma
variável local Poderíamos dizer que nosso
nível de arma é um nível de arma. Então, na leitura, digamos que o nível da
arma seja igual ao nível de definição da arma
Dot Git em nosso nível atual E então, sempre que
subirmos de nível, também vamos definir isso. Dessa forma, se precisarmos ver as estatísticas do nosso nível
atual de arma, basta acessar
esse valor aqui. Então, basicamente encontramos o
valor em nossa definição uma vez
e, até subirmos de nível novamente, temos acesso às informações
nesse nível de arma. Ok, agora com o Trevelu, queremos chegar ao próximo Portanto, nossas estatísticas
de próximo nível serão iguais
à definição de obter o
nível da arma em nosso nível mais um. Portanto, se as
estatísticas do próximo nível forem iguais a nulas, retornaremos
false Caso contrário, diremos que o nível da
arma é igual
às estatísticas do próximo nível e dizemos que o nível mais um. Nível mais é igual a um, e retornamos verdadeiro Ok, então aqui está nossa função
de subir de nível. Ok, a última coisa que
vamos fazer
neste vídeo para o
item de armas é realmente criá-lo. Então, nos itens, clique com o botão direito crie um novo recurso, pesquise o item de armas, pressione Enter, vamos
colocar isso nos itens. Então, vamos dizer item de lança. E se você
clicar duas vezes no item da lança, você pode ver que temos um lugar
aqui para a definição Queremos que a definição seja exatamente a
mesma definição de nossas armas de lança Então, se você clicar em arma de lança, você pode ver que ela tem a definição de
arma Vamos clicar com o botão direito aqui e
salvar isso dentro das armas. Então, na raiz,
vamos às armas, e temos a
definição de lança lá Queremos clicar duas vezes
e substituir isso. Está bem? Então, aqui está nossa definição real de arma de
lança, e agora esse é um recurso
compartilhado Assim, podemos clicar no item Lança e queremos carregar rapidamente a mesma
definição de lança Então, agora o item de lança será vinculado dessa forma
à arma de lança Para que possamos reutilizar
a arma de lança 2 D. Vamos salvar esse
galho como uma cena Clique com o botão direito em Salvar ramificação como SN. E vamos colocá-la na
pasta de armas como arma de
lança ponto TCN Ok, agora
podemos reutilizar isso em
inimigos ou em qualquer
outro lugar que precisemos O ponto principal é garantir
que eles estejam usando a mesma definição de
lança, que é muito importante, caso contrário, o item de
lança nunca
conseguirá encontrar a
arma de lança por meio do Ok, agora fizemos
todo o trabalho de base. Então, no próximo vídeo,
configuraremos a interface do usuário e faremos que a subida de nível funcione
para atualizar nossas armas
47. Ladrilho 46 Crie um sistema de seleção de itens ponderados para recompensas ao nível: Então, neste momento, precisamos
adicionar uma lista de itens de armas à nossa
seleção de subida de nível, que podemos escolher quando
preenchermos a janela Então é aí que entra o script da opção de
nivelamento,
onde, para um determinado
mundo de jogo ou nível do jogo, temos apenas essa
variedade de itens que
podemos atribuir na seleção de subida de
nível Então, no script de
seleção de subida de nível, precisamos exportar
uma VR para opções, e isso será
do tipo opções de nivelamento Ok, então salvamos esse script, e agora, se olharmos para o
inspetor e duas visualizações em D, clicamos na seleção Level Up
e, à direita, podemos criar nossas novas opções de nivelamento Agora, isso é algo que
provavelmente tem um nível muito específico. Portanto, você pode ter um nível um em que tenha muitas opções
e, em seguida, o nível dois, talvez
seja um pouco mais difícil, então você restringe a lista de itens, ou pode até mesmo ser por classe de
personagem, se você decidir seguir o caminho de restringir itens a De qualquer forma, esse
será um recurso no qual você deseja clicar com o botão
direito do mouse e
salvar no projeto. Então, vamos entrar, digamos,
na pasta de configurações,
já que é
por isso que eu coloco o script de
opções de nivelamento, e então colocamos as opções de nivelamento de nível um
e depois salvamos,
então será um ponto E agora podemos atribuir
uma matriz de itens. Então, vou
aumentar isso para um, e vamos carregar rapidamente
o item de arma
do item de lança E agora essa é uma
das possibilidades que
podemos usar dentro do nosso script de seleção de subida de
nível. Em nossa hierarquia, queremos que a seleção
de subida de nível passe as opções,
digamos, para
esse contêiner HBox, que poderíamos dizer que é mais
parecido com a seleção de recompensas Portanto, em termos de nossa hierarquia, temos a opção definida no nível de seleção
de nível superior Quando abrirmos o menu
para aumentar o nível de nosso personagem, nossas seleções
de recompensas serão preenchidas aqui
neste contêiner da caixa H. Então, cada uma das recompensas que
pudermos escolher aparecerá
como uma opção aqui embaixo. Por padrão, seriam três. Mas, na verdade, isso depende quantos itens
temos disponíveis. Assim, poderíamos renomear
esse contêiner HBox para
algo como um contêiner de caixa de
recompensas
e, em seguida, clicar com o botão direito do mouse
e dar um script Então, vou anexar um script e salvá-lo no UI
slash Rewards Box Container O motivo pelo qual estou fazendo isso é porque quanto mais você separa as diferentes funções de sua interface geral em scripts menores
separados, mais reutilizável
será cada um
desses componentes porque você está separando
as responsabilidades Portanto, o contêiner
da caixa de recompensas será o único responsável por
preencher as recompensas que ficarão embaixo dele Então, vamos criar um contêiner de caixa de recompensas com o
nome da classe
e, em seguida, vamos
exportar uma cena cheia
para exemplificar cada uma dessas seleções de
recompensas Então, eles não
vão realmente estar lá. E o BaseUI, eles serão eliminados e somente instanciados quando tivermos uma recompensa para Então, vamos criar uma
função populate e isso exigirá
uma lista de opções E também queremos
saber quantos itens podem ser
selecionados ao mesmo tempo. Então, acho que as opções de nivelamento
seriam um bom lugar para colocar essa propriedade em
vez da própria interface do usuário. Então, vamos clicar com o botão direito em Opções
de nivelamento, símbolo de pesquisa E eu vou dizer em export var MAX
Underscore Choices, que será um número inteiro, e vou padronizar isso para três E enquanto estamos
à frente, quero
fazer uma grande mudança
nessa variedade de itens. Na verdade, vou
transformá-lo em um dicionário de itens para que possamos aplicar
um peso a cada um. E
isso fará com que, se quisermos
priorizar um item como
uma opção possível, possamos fazer isso
aumentando sua taxa de queda forma eficaz, fornecendo a ele um valor flutuante mais alto ou
um valor flutuante menor para itens mais raros Agora, como mudei o
tipo dessa variável, significa
que preciso
redefini-la na seleção de nível. Então, se formos para a seleção de níveis e examinarmos nosso
novo dicionário aqui, precisamos fornecer o item. Então, carregue rapidamente esse item de lança
e atribua um valor a ele. Poderíamos dizer um, se quisermos. Então, agora esse item de lança tem uma
chance de cair de 1,0. E, assim como nos outros
casos em que
fizemos aleatoriedade com pesos, esse 1,0 é relativo ao peso total de
tudo o mais nesta lista Então, agora é
100% porque há apenas um peso a mais de 1,0,
então é um em um. Mas se adicionarmos mais quatro itens
, teremos 20% de chance. E, claro, como
estamos dando três opções, ele vai rolar três vezes. Quando selecionamos um item
em nossa lista suspensa, ele também é removido dos pesos
gerais Se tivéssemos cinco opções,
escolheríamos três delas, três escolhas únicas,
devo dizer. Então, vamos até o contêiner da caixa
Rewards. Agora temos quantos
vamos realmente escolher. Ah, e queremos
obter o peso total. Lista de opções,
certificando-se de que cada uma esteja disponível para ser usada
com o alvo específico. Então, vamos criar outra
função para isso. Vou chamar isso de função,
gerar escolhas. E assim
consideraremos as opções P como opções nivelamento e o alvo
P como um nó dois D. Ok, então primeiro,
queremos obter as opções restantes
da lista de opções Então, se nossas opções restantes forem iguais a, digamos, peso do item
Poptionst
ou peso dos itens,
e vamos
duplicar Ok,
então a razão pela qual estamos duplicando
aqui é porque
queremos esse dicionário de
itens com seus pesos e vamos
duplicar Ok, então a razão pela qual estamos duplicando
aqui é porque
queremos esse dicionário de
itens Para sermos específicos para essa
função, não
queremos mexer com o dicionário original
removendo itens
desse dicionário Todas as
opções de nivelamento devem permanecer
nas opções de nivelamento
basicamente pelo resto
do
jogo, porque essa é
uma definição de tempo de edição, e essas são nossas opções restantes de tempo de execução Então, duplicamos a lista e vamos removê-la depois
de fazermos
cada seleção ou depois de
invalidarmos uma Portanto, a duplicata aqui
é importante para
garantir que não estamos modificando
o dicionário original Efetivamente. Agora temos
as opções restantes. Queremos filtrar todas as
opções que são inválidas. Então, para a opção nas
opções restantes, teclas de ponto, por que teclas? Porque as chaves
neste dicionário são os itens e os
valores são os pesos Portanto, pode ser útil declarar
o tipo aqui, embora seja inferido
do peso dos itens, é melhor que possamos
vê-lo na tela Então eu vou dizer
dicionário do item, e então temos o peso. Oh, espere, o peso está flutuando. E aí podemos ver claramente que o
item são as chaves. E a flutuação é o valor. Para cada um desses itens, queremos verificar se
o alvo pode aplicá-lo? Na verdade, talvez seja melhor
chamar esse item aqui. Para o item do tipo item nas teclas de
ponto das opções restantes, podemos dizer que, se o ponto do item pode ser aplicado e
, como o
digitamos aqui, temos acesso às funções
no menu preenchido
automaticamente Então, queremos ver se podemos
aplicar isso ao alvo P. Então, se não pudermos aplicá-lo ao
pré-alvo, vamos inverter isso. Portanto, se o item Doc não puder ser
aplicado ao alvo P
, removeremos
o par de valores-chave. Então, quando fazemos as teclas de ponto, isso nos dá uma matriz. Portanto, essa matriz é separada
do dicionário original
, então acho que podemos realmente modificar esse
dicionário sem problemas, porque
já temos a
matriz separada de chaves aqui. Então, esse loop aqui, se modificarmos o dicionário, não será um problema. Normalmente, você quer ter
cuidado com isso. exemplo, você não deve modificar uma matriz enquanto está
percorrendo ela, mas nesse caso, essa matriz é separada
desse dicionário, então deve estar tudo bem No entanto, veremos com certeza quando
realmente executaremos o código. Portanto, se não pudermos aplicar o item, queremos
removê-lo da lista de opções porque não
podemos usá-lo. Portanto, as opções restantes não
removem ou facilitam, sim. Ok, aqui se chama apagar. E nós temos a chave ali mesmo. A chave é o item. Então,
apagamos o item e isso o
removerá como uma opção Então, depois de repetir
todas as opções, já
filtramos
todas as que não podemos aplicar. Então, agora só precisamos fazer uma seleção com base
no peso total
e, depois de escolher cada um, nós o removemos das opções
restantes. Portanto, nosso peso total aqui será uma
flutuação igual a 0,0, e precisamos percorrer mais uma vez as opções
restantes Então, poderíamos dizer que quatro
pesos flutuam e os valores de pontos das
opções restantes e, em seguida,
dizemos que o peso total mais
é igual a esse valores de pontos das
opções restantes e, em seguida, dizemos que o peso total mais
é igual Então eu acho que essa é uma maneira bem
clara de escrever isso. Então, agora totalizamos o peso. Queremos fazer uma seleção
aleatória entre zero e
o peso total e depois ver qual
deles escolhemos. Portanto, o peso aleatório de VR será inferido
do tipo rand F vezes
o peso total Então, fizemos isso algumas
vezes no curso até agora. O peso total é
nosso valor máximo. 0,0 é nosso valor mínimo. E considerando basicamente 0,0 a uma vez
o peso total, obteremos algum valor entre zero e
o peso total. Ok, agora temos
nosso peso aleatório e queremos escolher um item entre
as opções restantes. A propósito, haverá um loop aqui, mas
podemos escrevê-lo primeiro
para um item. Ok, agora aqui estão quatro
opções nas opções restantes. Então, vamos dizer que
se o peso atual é maior ou igual
ao peso aleatório, então escolhemos essa opção. Então, agora precisamos, na verdade, de um peso
atual aqui também. Portanto, nosso
peso atual será um flutuador igual a 0,0 Então, primeiro, queremos adicionar
o peso da opção. Então, atualmente, será mais igual às opções restantes nesta opção. Então, colocamos
a chave do dicionário. Isso nos dá valor e
, na verdade, pode ser
uma maneira mais segura de fazer isso. Então, poderíamos dizer, escolha a opção. E se não houver opção, o valor padrão será nulo Nós nos daríamos um erro aqui. E talvez isso seja
realmente o que
queremos ,
porque esperamos que esteja lá. É muito importante se bloquearmos o
par de valores-chave e ele simplesmente não existir. Então, sim, vamos deixar
que seja exatamente como teria sido fazendo
a opção de colchetes Efetivamente, é a mesma coisa exceto que essa
função get permite que você aplique um backup padrão com uma vírgula e depois a variante
padrão Portanto, é um pouco mais
flexível, mas, neste caso, queremos uma falha grave se
a opção simplesmente não existir, porque definitivamente deveria estar OK, então adicionamos
o peso atual. Queremos verificar se
o peso atual é maior que
o peso aleatório. Portanto, se o peso atual for maior ou igual ao peso aleatório, adicionaremos isso
à lista de opções selecionadas. Poderíamos simplesmente declarar as opções
selecionadas
aqui na parte superior Então var selected é uma matriz de itens porque é isso que
precisamos retornar no final. Então, vamos acrescentar a opção à matriz
selecionada Então, selecione a opção anexar
e, em seguida, precisamos
removê-la da lista de E, na verdade, acho que a
forma como vou fazer isso é definir uma variável
local aqui. Portanto, se nossa próxima seleção for
um item igual a nulo, faremos com que o próximo seja selecionado Igual a essa opção
e depois quebra. Então, saímos
do circuito quatro. Não
precisamos mais dos quatro circuitos. Depois desse loop, a próxima
seleção não é igual a null. Em seguida,
selecionaremos a opção de acrescentar pontos. Caso contrário, queremos sair
de todo o nosso ciclo de quatro ciclos. Então, precisamos de um loop de quatro
porque vamos fazer isso várias vezes. Então, vamos ver. Então, acho que
aqui, 44 vezes nas opções Range,
zero, CP, sublinhado
pontuam Max Choices com incremento de um. Basicamente, isso significa que
passamos de zero para o máximo de escolhas,
subindo uma de cada vez. Quando atingimos o máximo de
opções, paramos o ciclo. Então, se o máximo de opções for três, isso será
executado três vezes. Vai ser zero, um, dois, e quando chegar a três,
vai ser igual
ao máximo de opções. Vou
parar o circuito de quatro voltas. Ok, então basicamente
pegamos tudo isso e o tabulamos, e agora ele vai repetir
todo esse código, certo? Então, como parte
da adição da opção, também
queremos pegar
o peso total, e queremos menos igual a qualquer que seja o peso da Então, diremos que
as opções restantes não recebem opção. Estou ciente de que isso está
chamando isso de novo, mas isso não é
realmente um grande problema. Então, isso vai obter o valor
flutuante do peso. Nós
o removemos do peso total e depois queremos
voltar aqui. Então, há também a
outra possibilidade, que é que
não há nada selecionado, o que significa que
não há mais nada para selecionar. Então, poderíamos simplesmente
sair mais cedo do circuito quatro. Então, estamos falando sobre
isso para loop aqui. E isso
provavelmente parece bom para mim. Só precisamos
devolver o selecionado. Então, retorne selecionado. Então,
no final disso, obtemos até três itens. Para cada um desses itens, queremos preencher a interface do usuário Então, digamos que a VR aqui em cima, as escolhas serão iguais para gerar escolhas
nas opções P, e passamos o alvo
P para que
possamos comparar cada item em relação ao alvo para
ter certeza de que é válido. Então, temos uma escolha aqui agora. E então queremos criar
a cena de seleção de barbas e atribuir a escolha a ela aqui
embaixo Como esse bit está, na verdade,
fora desse loop de quatro, queremos acrescentar o
próximo selecionado porque
definimos o próximo selecionado aqui igual
à opção para que possamos
usá-lo fora do loop de quatro Então, queremos dizer o
próximo selecionado aqui e também o
próximo selecionado. Então, mais uma coisa que
esqueci de fazer
aqui é que, depois de
ajustar o peso total, também
esqueci de
remover o próximo selecionado
das opções restantes Então, diminuímos o peso total porque estamos
removendo a opção
e, em seguida, removemos
a opção
da lista real da qual
estamos selecionando. Então, quando voltar
aqui agora para os próximos quatro ciclos para
as opções restantes, não terá
essa opção lá, e simplesmente a
ignorará completamente porque não está mais nesse dicionário, que é o
que queremos Para as opções restantes, queremos apenas examinar
o que ainda
é uma seleção possível,
agrupando as seleções que já
foram
48. P47 - Seleção de recompensa por programação com propagação de sinal: Na nossa função Gerar
opções, temos esse conjunto de opções. Na verdade, pode nos
ajudar a
declarar visualmente o tipo aqui,
em vez de inferi-lo Então, como temos uma matriz, queremos
percorrer a matriz. Então, para cada escolha, criamos uma instância de nossa cena de seleção de
recompensas
e, em seguida, aplicaremos
a escolha a essa cena,
basicamente definindo a escolha
na cena e fazendo com que ela preencha sua subinterface com
tudo o que precisamos Então, para escolher as opções, vamos criar
uma seleção de recompensa, que atualmente é um controle, que será igual à cena de seleção de
recompensa
dot Instantiate Em seguida, precisamos adicioná-lo como
filho a esse contêiner HBox. Portanto, adicione filho da seleção de
recompensas. E então diremos o ponto de
seleção de recompensa
setHoce e passamos a
Escolha Nossa seleção de recompensas, você pode ver aqui, atualmente não
tem script. Essa função não existe, então precisamos criar uma
função no script, e vamos fazer isso
dentro da cena cheia. Então, queremos clicar em
Abrir e editar. Então, entramos na cena
original empacotada para esse elemento específico da interface do usuário. Então, na seleção de recompensas, queremos clicar em
anexar um novo script e o chamaremos de
Uilashrewardselection Crie isso. E do lado daqui. Daremos a ela o
nome de classe Seleção de recompensas que
facilitará preenchimento automático de suas funções E o que nos importa aqui
é a escolha do conjunto de funções, e vamos
passar uma escolha. E essa escolha é um item. Eu me lembro. Então, isso
retornará vazio. E a partir daí, precisamos
preencher todos esses elementos. Então, vou pegar
o rótulo Rich Text e renomeá-lo
para rótulo de nome Vamos renomear o texto
direto para ícone reto. Vamos renomear o
segundo rótulo de Rich Text para ser rótulo descritivo e vamos renomear o botão
para ser botão Ok, isso deixará muito mais claro o que eles
realmente devem fazer. Agora que temos essas
configurações, vamos entrar no script de seleção de recompensas novamente
no script de seleção de recompensas e obter uma referência
para cada uma delas. Agora, do jeito que venho fazendo
isso durante o curso, e acho que mesmo nesse caso, ainda prefiro fazer um at export var e diremos
algo como name label. É um tipo do que quer que
seja, rótulo de texto rico. Ok, e então você pode
simplesmente atribuir isso ao inspetor. Sabemos
como fazer isso, certo? Mas isso significa que sempre que você configura uma cópia do script, precisa definir
manualmente as variáveis de exportação. Então, só para mostrar outra opção, você pode fazer em uma barra pronta, digamos, no ícone Rec que será
uma textura reta E então você dá a ele um sinal
ecológico e
o configura no caminho de seu nome. Então, se eu disser escolher o botão, ele será preenchido automaticamente
aqui. Podemos selecionar isso. E eu acho que isso precisa de um sinal de
$1 no início. Então, contêiner de margem de cifrão,
barra, contêiner VBox, barra,
barra Agora, isso significa
que, quando estiver pronto, ele obterá automaticamente
esse caminho do nó e o
atribuirá diretamente ao texto. Portanto, não precisamos
configurá-lo manualmente no inspetor. No entanto, há
uma grande falha aqui, que é que isso exige o caminho para aquele
item seja o mesmo Portanto, se o seu botão de escolha
for chamado de qualquer coisa ,
exceto botão de escolha, ele
não o encontrará. Então, esse seria um dos motivos pelos quais eu poderia preferir fazer um at Export, porque se você reorganizar
seus nós aqui, contanto que ainda
tenha o conjunto de referência, isso não
quebrará seu script Ok, é por isso que eu geralmente
não uso isso, e vou voltar
para o ícone Export var Rect, que
será uma textura Rect E então queremos o rótulo de descrição
Exportar var, que é um rótulo de texto rico aqui no botão de escolha Exportar var. É um botão. Ok, e para definir uma escolha, vamos devolver o passe por enquanto para
que o script possa ser salvo e clicar
em Seleção de recompensa. Vá para o canto superior direito e
atribua cada um deles. Então, nomeie rótulo para rótulo de nome, ícone Rect para ícone Rec, descrição para rótulo de
descrição E como temos
dois rótulos em rich text, é
aqui que ter nomes
informativos, como rótulo de nome e
rótulo de descrição realmente ajuda, em vez
de serem chamados em rich text e rótulo
em rich text two. Só quero
ressaltar isso. E, finalmente, escolha o botão que atribuímos ao botão de escolha. Portanto, agora temos uma referência
a todos eles e podemos
preenchê-los facilmente com as informações
do nosso item. Ok, agora, para
lidar com a escolha do conjunto, podemos fazer o texto do ponto do
rótulo do nome, e isso será igual
ao nome do item. Então, no momento, nossa classe de item
não tem um nome. A subclasse de item de arma
tem uma definição, e essa definição tem um nome, mas podemos querer um nome específico para o
item, e acho que essa seria a abordagem
mais direta para criar um nome de item
na classe do Então, se formos até o
item, podemos fazer isso em Exportar nome de exibição do VR, que
será um nome de string, e eu o
padronizarei para item sem nome Então, isso é uma espécie de distinção
entre o item e a definição
da arma, porque um item nem sempre é
necessariamente uma arma, então podemos distinguir aqueles com duas propriedades separadas, pelo
menos por enquanto Então, agora vamos voltar
à seleção de recompensas e escolher o nome de exibição de
pontos da escolha Deixe-me dar uma olhada na definição do item de
lança, e podemos ver aqui Portanto, a definição aqui
está realmente configurada para ser mais uma definição da arma,
de como ela sobe de nível e de
seu valor de dano. Portanto, a descrição do item soa como algo
que deveria ser separado, porque você pode pegar uma cópia desse
item no
mapa-múndi e dizer algo como:
Ah, isso é um item de lança Isso adiciona a habilidade de ter
a arma ao seu jogador, mas não é a definição
da arma em si. Então, queremos
distingui-los. Portanto, podemos dizer que o texto
do ponto do
rótulo de descrição será igual à descrição do ponto de
escolha Agora precisamos que o item
tenha uma descrição. Vamos copiar esse nome, clicar com
o botão direito no item, símbolo de Lou E faremos em
Export var, bem, e faremos em export
var paste in description, que é uma string, e
que estará em branco por padrão. Ok, agora na
seleção de recompensas, isso é resolvido. Em seguida, queremos
fazer o ícone Rect. Então, poderíamos dizer que a textura
do
ponto reto do ícone será igual
ao ícone do ponto psíquico Mais uma vez, o item se distingue da definição de
arma. Ele deve ter seu próprio
ícone que possa ser definido. Então, vou
exportar a textura do ícone VR. Ok, e temos
o ícone de textura, para que possamos voltar à seleção de
recompensas. Agora, eu quero ter cuidado
aqui, porque se você tentar definir o ícone pchoict quando não
houver um ícone de ponto pchoic, você
receberá
uma referência nula assim
que tentar fazer referência Assim, você pode
verificar manualmente se o ícone
existe todas as vezes ou pode alterá-lo para ícone
Pchoic dot Get e apenas
ter essa segurança integrada Mas então temos que adicionar essa
função à classe do item. Então, vamos clicar com o botão
direito do mouse no símbolo
e, em seguida, criarei nosso
ícone da
função G aqui embaixo , ícone da função G, e isso retornará
uma textura ou nada. Então, se ícone, retornamos ícone, caso
contrário, retornamos nulo. Está bem? Acho que é bastante simples. Esse método nos dá
segurança caso seja nulo, então retornaremos null em vez de ter
um erro imediato Então, o último é um
pouco mais complicado aqui. Temos o botão de escolha. Quando o
botão de escolha é pressionado, queremos fazer a
seleção com a escolha. Então, queremos que o botão
saiba sobre a escolha. E então passamos o sinal
do botão sendo pressionado
até nossa seleção de subida de nível, para que
possamos aplicar o efeito ao jogador
e fechar o menu. Então, aqui no nível de
seleção de recompensas, queremos vincular o sinal
do botão que está sendo pressionado à opção que passamos
aqui, a escolha do item, e emitiremos isso como um sinal
na seleção de recompensa,
e então a seleção de
subida de nível se conectará a ela subindo
na cadeia e podemos basicamente saber nível superior, quando qualquer um
dos nossos botões são pressionados e depois aplicamos os efeitos ao nosso player. Então, precisaremos fazer,
digamos, o botão de escolha. Então, precisaremos
escolher entre pressionar o ponto Connect
e conectá-lo a
uma nova função no
Reward uma nova função no Mas vamos
vinculá-lo à escolha P. Então, quando estamos
vinculando, estamos basicamente passando um parâmetro extra para o retorno de chamada que essa função normalmente não
teria Então, a função sublinhado na recompensa pressionada agora
obtém a opção P, que é um item, e ela retornará nula,
e agora podemos continuar passando
essa escolha para cima na Assim, podemos ter um sinal de
AR na parte superior, que dirá sinal selecionado, que passará uma
escolha do item. Agora só precisamos emitir
esse sinal, então selecionado. Dot I MIT, e
passamos a opção P, e agora ela pode
subir na hierarquia Então, sim, normalmente, o pressionamento de um botão não
tem parâmetros
quando você o recupera. Apenas informa que
o botão foi pressionado. Mas, ao chamar bind, adicionamos esse parâmetro extra sempre que ele é pressionado Portanto, agora nosso botão pode nos
fornecer informações muito críticas sobre qual escolha estava
realmente sendo feita. Tecnicamente falando, também
poderíamos definir a variável de escolha local
aqui e, em seguida, pressionada, poderíamos simplesmente passar a escolha local para a
escolha dos itens Então, se eu definir isso ao definir a escolha, isso também
funcionaria. Duas maneiras de fazer
a mesma coisa, mas agora você conhece uma maneira muito
mais legal de usar a vinculação, então você pode realmente adicionar
parâmetros extras Além disso, isso não exige a seleção de recompensas continue
mantendo essa escolha, embora definitivamente pudesse, e não seria
problemático aqui Ok, então vamos
subir mais na hierarquia. Agora, em nossa
seleção Lavop, que vamos ver. Temos o contêiner da
caixa Rewards. Então, é aqui que estamos realmente criando as
seleções de recompensas Então, aqui, eu preciso propagar
o sinal para cima novamente. Então, digamos que sinal selecionado, que passará o item de
escolha desse jeito. Portanto, sempre que preenchemos
nosso menu de seleção de recompensas e agora que
temos um nome de classe, podemos e devemos
alterá-lo para seleção de recompensas E vamos conectar
isso a uma recompensa selecionada. Então, aqui na parte inferior, criaremos esse sublinhado da
função de retorno de chamada
nas recompensas selecionadas Recebemos a Escolha P, que é o item que
devolvemos vazio, e vamos
propagá-la para Então, selecione o ponto EMT. Vamos emitir
com a opção P. Então, isso
sobe ainda mais na hierarquia agora. Então, isso está no nível do contêiner
da nossa caixa de recompensas. Agora, na seleção de subida de nível, só
precisamos nos conectar ao
nosso contêiner de caixas de recompensas. Então, vamos exportar
nosso contêiner de recompensas, que é um contêiner de
caixa de recompensas. E quando estiver pronto, queremos nos
conectar ao sinal. Recompensas: contêiner, ponto
selecionado, conexão de pontos na recompensa selecionada. Função sublinhada
na Recompensa, selecionada. Deixe-me ampliar
um pouco aqui. E teremos nossa escolha P, que é o item, e
retornaremos sem valor. Então, vamos passar por enquanto, e precisaremos aplicar o efeito ao jogador
e fechar o menu. Voltaremos a
isso em um segundo. Então, tivemos nosso método
de seleção inicial. O que queremos fazer é basicamente redefinir o contêiner da caixa de recompensas. Queremos que ele seja preenchido,
mas também queremos que ele limpe todos os itens existentes Então, no contêiner da caixa de recompensas, vou preencher fazer esse sublinhado
e gerar escolhas Também vou fazer sublinhado
para privado, para que não o
chamemos acidentalmente de nossa interface principal Então, aqui precisamos
sublinhar porque estamos fazendo com que o sublinhado
gere escolhas Agora vamos criar a função que realmente vamos chamar. Então, opções de configuração de funções. Sim. Ok, isso
faz algum sentido. E vamos
passar nossas opções P,
que são opções de nivelamento, e vamos
passar o alvo P, que é nosso nó
dois D. Claro, vamos preencher com essas opções e nosso Mas antes disso, eu também
quero limpar esse menu. Portanto, qualquer uma das caixas secundárias, preciso
removê-las antes de preencher ou preciso garantir
que meu preenchimento reutilize a interface de usuário existente e, em
seguida,
as atualize com as novas Então, como teremos
apenas algumas opções aqui,
seria um pouco
exagerado se
preocupar demais em reutilizar todos os componentes
possíveis da subinterface Portanto, a opção mais fácil de curto prazo seria
definitivamente limpá-la, o que será
para crianças e crianças. Vamos
chamar Child Dot Q gratuitamente. Então, agora aqui no topo, podemos limpar antes de povoar. Ah, e precisamos concluir um tipo de retorno para
as opções de configuração. Então, retornaremos vazios. OK. Sim. Então, agora, configure Escolhas, podemos chamar isso em nosso script de seleção de nível. Então, comece a seleção,
faremos
recompensas Container dot Start Selection, e isso passará para
as Opções e o alvo, que é o player de contexto. E esse é o
nome errado para o método. Na verdade, eram opções de configuração. Ok, então começamos a seleção.
Nós configuramos as opções. Esperamos que o jogador
basicamente escolha uma opção
e, em seguida, receberemos
nossa ligação de volta Então, nesse ponto,
queremos fechar o menu. Então, poderíamos dizer que recompensa o
container dot CE aqui. E eu fiz disso
um método privado. Então, no contêiner da caixa de recompensas, vou apenas remover o
sublinhado aqui e aqui Ok, agora ele é
chamado internamente, mas também a partir de outros scripts Então, se você precisar tornar um método
público, você pode fazer isso. Tecnicamente, mais uma vez, o
GD Script não impede que você chame um método com um
sublinhado É apenas a melhor prática
para indicar a intenção. Então, de volta ao nível
de seleção das recompensas selecionadas, queremos aplicar o
efeito do item ao jogador. Diremos que p choice dot
Try se aplica ao jogador. Então esse será o reprodutor
de pontos de contexto. Em seguida, limpamos o recipiente
e fechamos o menu. Ok, então vamos ver.
Vamos nos esconder aqui. E isso pode ser
praticamente tudo o que precisamos. Então, um pouco de limpeza aqui. Vamos até o contêiner da caixa
Rewards
e, bem, deixe-me mostrar as
duas vistas em D, na verdade. Aqui você pode ver que
temos essas três caixas aqui. É bom tê-los à
vista aqui desde que os liberemos antes de
começarmos a usar qualquer coisa. Então, se formos para o contêiner Rewards
Box pronto, vou querer ligar para a Clear. Então, a função de sublinhado está pronta. Vamos esclarecer
esses elementos da interface do usuário. significa que eles serão
removidos e recriados sempre que o contêiner da
Caixa de Recompensas aparecer Queremos que seja o mais
otimizado possível Reutilizar cada componente da interface do usuário é melhor do que ter que
recriá-lo a partir de uma instância Mas para algo
simples como esse, você só vai mostrar
uma vez a cada, sei lá, 30 segundos de jogo, que quase não deve ter nenhum impacto, e isso não é realmente um grande problema. Ok, então ainda temos
a seleção de lanças aqui. Então, se realmente
tentarmos subir de nível, devemos ver uma seleção. Definitivamente, é hora de fazer
um teste e ver se realmente fazemos
com que ele apareça e funcione. Então, vamos clicar em Play. E
veremos como isso funciona. Ok, então
parece que eu esqueci de colocar o contêiner de recompensas aqui
na seleção de subida de nível Então, vamos aumentar o nível da
seleção. Clique nisso. E na hierarquia, precisamos atribuir o contêiner de recompensas ao contêiner de recompensas Então essa é realmente a fraqueza das propriedades de exportação, certo? Se você esquecer de configurá-lo
, não há realmente
nenhuma indicação, ser que você encontrará erros em algum
ponto do código. Portanto, não precisamos de uma declaração
porque
a conexão com o sinal
já gerará um erro
assim que falhar Vamos fechar e
correremos novamente. Ok, então vamos
pegar nosso item. Boom, temos apenas uma
opção para escolher. Então, nomeamos o item aqui. Acho que simplesmente não defini
um ícone ou descrição, mas você pode ver que
o método Get icon, porque lidamos com
o caso nulo, não
vai nos
dar um erro Por outro lado, se referenciarmos diretamente a propriedade do ícone de ponto
porque era Null, isso geraria um erro aqui Se clicarmos em escolher, isso
se aplicará ao jogador? Então, vamos descobrir mais sobre isso. Ele deve fechar o menu. Sim, mas esqueci de
continuar o jogo. Portanto, temos que voltar aqui
e garantir que, depois ocultarmos o menu ou talvez
até mesmo antes de ocultarmos o menu, diremos que Geth dot paused
é igual a false Vamos guardar isso e
correr mais uma vez. Então, entramos aqui,
fazemos nossa seleção, vamos escolher o item.
Boom, já está lá. Agora, pareceu funcionar, mas o verdadeiro teste
seria que, se tivéssemos uma tela para os níveis de nossos itens de
arma aqui
acima, trabalharemos
nisso daqui a pouco. Por enquanto, a melhor coisa a fazer seria bater de perto e vamos até nosso item de lança Vou atingir o nível dois e vamos mudar
o tempo de recarga para 0,1, porque isso será muito óbvio se passarmos para esse nível Então, vamos clicar em play novamente.
Vou pegar nosso item, clicar em escolher e vemos que o tempo de recarga
não é atualizado Então, algo está um
pouco errado no código. Então, acho que o
problema, na verdade estará na
arma em si. Vou verificar aqui
para ter certeza de que estamos realmente atribuindo o
aumento de nível, então pare aí E deixe-me ver aqui, pronto, obtemos a
definição de resfriamento para o cronômetro. Mas você pode ver aqui que estamos definindo a
hora do cronômetro aqui Mas aposto que aqui embaixo, na verdade não
redefinimos
o cronômetro para um novo valor Então, sim, esse é um problema
muito claro. Precisamos dizer o ponto do cronômetro. Na verdade, digamos que o início será o novo valor. Então, precisamos fazer o tempo de recarga do
G. Precisamos obter o ponto
de
definição Obter o de recarga de um nível atual Então, definição, ponto Obtenha o tempo de
recarga do nosso nível. Isso significa que sempre que
reiniciamos o cronômetro, obtemos o tempo de
recarga atual do Então, digamos que na
metade do disparo de um projétil, mudamos nosso tempo de recarga
porque nosso nível subiu Então, isso significa que na próxima vez que o projétil for lançado
, reiniciaremos o
cronômetro com nosso novo valor Então, agora ele usará a propriedade
de nível dois. E acho que nem preciso
ter esse ponto de interrupção. Tenho certeza
que esse é o problema. Vamos continuar e clicar em Play. Vou pegar nossa
arma, clicar em escolher e pronto. Basicamente, temos uma lança
de metralhadora porque nossa lança atingiu o nível dois, e isso vai quebrar
completamente o jogo Então, eu recomendaria que, no final, mudássemos
a temperatura do nosso projétil de lança de volta para 0,9, agora que sabemos que funciona,
e isso encerrará este vídeo
49. Ladrilho 48 Aplicando estatísticas de nível de arma ao gerador de projéteis e instâncias: Mostramos que podemos aprimorar
nossas armas por meio da seleção
de recompensas ao subir de nível, mas precisamos
garantir que, ao aumentarmos o nível de nossas armas,
estejamos usando todas as
estatísticas corretas da arma, não apenas a redução do tempo de
resfriamento. Então, vamos ver o
roteiro do projétil. E veremos aqui dentro
que ainda não estamos usando as estatísticas do nível
da arma. Estamos usando uma velocidade embutida, e o dano final
não é causado por
nenhum cálculo. Está apenas passando 100
como variável local. Então, se você está percebendo a definição do nível da arma, ela
ainda não está usando essas estatísticas, bem, é por isso Então, quando criamos
o projétil, precisamos passar pelo nível da
arma também Poderíamos ter uma função totalmente
separada para fazer isso, mas acho que seria mais prático colocar as estatísticas do nível da arma
na função de lançamento. Portanto, a função de lançamento
serve não apenas para definir
a direção, mas também para configurar as estatísticas
específicas do projétil, mas o lançamento
também serve para configurar as estatísticas específicas de lançamento desse projétil com base no nível
atual da arma Então, como perímetro extra, vamos
querer passar no nível P,
que é o nível da arma Então, essas serão todas as estatísticas
que precisamos trazer aqui. E em vez de no
topo ter uma velocidade aqui, vou remover e
, em vez disso, vamos
dizer var nível do
tipo de nível de arma, e é daí que vamos
extrair todas as estatísticas. Então, quando estivermos fazendo o processo de
física e
precisarmos multiplicar pela
velocidade, faremos o nível Velocidade do ponto. OK.
Vamos adicionar isso. E agora, no lançamento, precisamos definir o nível
igual ao nível P. Ok, então é assim que
obtemos as estatísticas, e então só precisamos
atualizar nossas chamadas para o lançamento. Mas há outras informações
aqui que são relevantes. Então, primeiro, quando a caixa de
acerto atinge uma caixa rt, precisamos retirar o dano
das estatísticas de nível. Então, aqui precisamos de um cálculo de
dano aleatório entre dano causado por
nossos homens pela
arma e nosso dano MÁXIMO. Então, removerei essa linha e diremos que var
damage será um número inteiro, e isso será igual
a um intervalo inteiro aleatório entre o dano mínimo
e o dano máximo Então, nivele o ponto de dano mínimo
e, em seguida, nivele o ponto máximo de dano que lida com a
aleatoriedade aqui. Então temos
nosso dano final. Vou apenas dizer que é igual
ao dano agora, e então passamos nosso
dano final para a caixa Hurt. Portanto, agora também temos
danos aleatórios com base no nível e
na velocidade definidos pelo nível. Então, se olharmos para o script da
arma dois D agora, obteremos um erro lançamento do ponto de
projétil porque
precisamos no lançamento do ponto de
projétil porque
precisamos passar para o
nível atual da arma dois D, que está convenientemente configurado aqui na arma dois D.
Então, digamos coma, nível da
arma aqui, e
isso apenas o envia do nível da arma
para a instância
do projétil Então, podemos testar essas mudanças
executando o jogo agora. Então, vamos encontrar nosso inimigo onde quer que
eles queiram desovar Ok, tem um. E
você verá que temos danos aleatórios
entre nossos homens e MAX. Atualmente, você pode
ver que ele ainda está passando pelo inimigo,
aí está nossa subida de nível. Então, em teoria, isso deveria
ser um pouco mais rápido, tanto no
resfriamento quanto nos danos. Você pode ver os
danos lá em cima. Então, na maioria das vezes,
isso parece estar funcionando. Mas ainda há algumas
coisas que precisamos ajustar, como quantos golpes ele pode fazer antes de realmente excluir
o projétil Então, no hipbox hit, na verdade, queremos aumentar
quantos golpes fizemos
e, se os acertos forem iguais
aos nossos golpes MAX ou maiores
, queremos liberar
nosso Então, aqui no topo,
teremos um número variável, e isso será um número inteiro Vai começar do zero. E toda vez que alcançamos o sucesso. Vou começar
aqui e dizer que var hit igual a P hurt Box
dot Tri E então diremos, eu acerto,
depois acerto mais é igual E então também podemos
dizer que se os acertos forem maiores ou iguais ao nível máximo de acertos, então vamos
liberar nosso projétil Então, agora isso pode ser liberado se o cronômetro
expirar para basicamente persistir
na cena do jogo, que precisamos
substituir pela variável aqui
também, aliás . Ou se os golpes
atingirem o máximo de acertos
, ele também será liberado
imediatamente. Então, aqui em cima, também queremos dizer que quando
criamos o cronômetro, vamos pegar a propriedade
do nível Então dizemos nível, e acho que ainda não o definimos
. Então, precisamos, tipo, de uma duração. Vamos criar uma
estatística de duração para nossa arma. Ok, então nivele a duração dos pontos. Isso significa que precisamos
pular para o nível da arma. Procure o símbolo e vamos criar a duração aqui
embaixo. Diremos que na exportação var a
duração será uma flutuação igual a,
digamos, 5 segundos por padrão Então, esse é o
número máximo de tempo que o projétil pode persistir no mundo
do jogo antes da remoção, supondo que ele não seja
removido por algo como atingir ou exceder
o número máximo de acertos Ok, então vamos
continuar e apertar play mais
uma vez. Então eu vou clicar em play. Aqui está nosso projétil de lança, vamos
esperar que alguns inimigos apareçam vamos
esperar que alguns inimigos apareçam
. Está bem? Então nós temos isso. E você pode ver,
muito importante, que
assim que um cara é atingido, a lança se remove sozinha Então, essa é uma grande mudança. E se subirmos de nível até o nível dois, ainda deve ser o mesmo,
mas nosso dano aumenta. E vamos tentar observar
esse projétil, e ele desaparecerá
após 5 segundos. Então 45. Ok, aí você pode
ver os projéteis desaparecendo do mundo
do jogo Isso é muito importante
porque, caso contrário, eles podem nunca ser removidos e estariam apenas consumindo recursos
do sistema sem motivo. Portanto, queremos que eles sejam removidos
automaticamente eventualmente. Ok, agora
também há algumas outras propriedades do
nosso nível de arma, o atraso
na geração, o
deslocamento de alcance e os projéteis Portanto, precisamos garantir
que, em nossa arma para D, estamos realmente gerando
projéteis extras, gerando-os em relação ao
deslocamento e que quaisquer projéteis
adicionais tenham um atraso após o lançamento do
primeiro E então, com o atraso de amplitude, qualquer projétil
após o primeiro tem um atraso
antes de ser gerado Ok, então vamos às armas
para D. Então, cada vez que lançamos, precisamos que os
projéteis apareçam Portanto, precisamos de um índice
de quatro voltas, digamos, quatro no intervalo
zero até o nível da arma. Ponha projéteis e, em seguida,
incrementaremos em um. Então, vamos repetir
isso algumas vezes. Depois que cada projétil for lançado, aguardaremos o cronômetro de criação do
Kit tree Create
e precisaremos desse ponto de
nível de arma, Span Delay OK. E então vamos
esperar pelo tempo limite. Então, após o primeiro loop, esperamos que o curto
intervalo de tempo atinja o tempo limite antes de criarmos
nossa segunda instância de um projétil por lançamento, e estamos criando
projéteis com base na
quantidade de projéteis que o nível da
arma Mais tarde, se quiséssemos, também
poderíamos misturar isso com, digamos, um bônus do jogador. Portanto, se o jogador tiver mais um projétil para todas as armas
, temos a função de somar esses dois números
para obter o número total de
projéteis aqui Então, finalmente,
precisamos gerar um deslocamento aleatório com
base na distância de deslocamento
do nível da nossa arma Então, para nosso deslocamento, será igual
a um vetor dois, e então faremos um intervalo
F aleatório
para X e Y.
Então, intervalo F aleatório,
menos 1,0 a 1,0,
e então intervalo F aleatório, aleatório, menos 1,0 a 1,0 E multiplicamos isso pelo nível da
arma. Deslocamento de pontos Então, isso nos
dará um valor aleatório entre a
distância máxima negativa no deslocamento do vão
e, em seguida, o
deslocamento máximo positivo aqui para o X,
e o mesmo para o Y
e o Y positivo. Então, tecnicamente, isso dará uma forma quadrada porque o X e o Y não
afetam um ao outro, então pode ser menos 1,0 em X
e Y ou 1,0 positivo .
Eu acho que está tudo bem. Estamos apenas tentando
fazer uma compensação simples. Na verdade, não
importa muito se é um quadrado ou círculo, a menos que
você queira que isso importe. Então, vou descer até o projétil e adicionar o deslocamento OK. E isso fará com que, sempre que
gerarmos o projétil, ele tenha algum deslocamento se
tivermos esse conjunto na arma Então, se eu olhar para o item da
lança, bem, podemos ver que aqui
não temos nenhum deslocamento de envergadura Então, talvez queiramos
definir um. Vamos ver. Qual seria o deslocamento máximo de
pixels que eu gostaria de fazer? Talvez umas cinco. E então faremos apenas
cinco para todos eles. Então, abra cada
nível de arma e faremos cinco. Então isso pode ser
positivo ou menos cinco ou qualquer coisa
intermediária para X e Y. E então eu vou correr, e vamos ver como isso Então observe onde as
lanças estão surgindo. E você pode ver que
eles estão um
pouco afastados um do
outro, certo? Portanto, não está sempre estritamente na
mesma posição. E também o torna um pouco mais interessante
para algumas variações. Ok, agora, o que eu quero fazer é pegar a arma de
nível um para testar, e vamos chegar a três projéteis, e eu vou
fazer essa escravidão 0,05 segundos, que Então, vamos jogar e executá-lo, e devemos obter uma
cadeia de três projéteis Um, dois, três, um, dois,
três, um, dois, três. Então você pode ver aqui
um, dois, três. Ah, agora, um pequeno problema aqui, você pode ver que se eu girar após o lançamento do primeiro
projétil,
os outros projéteis eu também giro quando
eles são instanciados Ok, então para essa rotação Rads, eu quero calcular isso
fora do circuito de quatro Eu só quero fazer isso uma vez. Assim que o primeiro
projétil for lançado, todos os outros devem ser
bloqueados nessa direção Então, vamos continuar e clicar em Play. E agora, se eu me
mover, mas girar, você verá que
todos os três estão sempre indo
na mesma direção, o geralmente é o
que
você quer, eu acho Então, vamos remover os
projéteis extras Primeiro, podemos manter esse deslocamento de desova personalizado
para todos eles Se você quiser, podemos até definir que uma arma
padrão tenha um deslocamento de alcance, mas isso depende de
você se quiser
voltar e personalizar os padrões de nível de
arma Deixe-me dar uma olhada no script do nível da
arma mais
uma vez e ver se
resolvemos tudo Portanto, dano mínimo, dano
máximo, velocidade, projéteis de
resfriamento,
máximo de acertos, deslocamento, atraso e Sim, estamos usando todas
as variáveis do
nosso nível de arma, e isso nos dá bastante personalização
para qualquer
uma das armas que
queremos criar
50. P49 Construindo uma arma giratória: Neste ponto, como temos
um sistema de subida de nível em funcionamento, queremos pegá-lo e
adicionar opções extras a ele. Então, agora seria o momento perfeito para adicionar uma segunda
arma ao nosso jogo. Então, isso será semelhante
ao primeiro. Adicionaremos uma foice, e a foice poderá
girar ao redor da tela vez de seguir em
frente, como a lança Então, se abrirmos o Spear
Dot TSC e as armas, você pode ver que ele
já tem a maioria
dos componentes que precisaremos
para nosso Então, vou
duplicar essa cena no canto inferior direito
clicando com
o botão direito do mouse na cena e
duplicando Então, vamos colocar
Syth aqui no ponto TSCN. Ok, agora eu posso pesquisar Syth no projeto
e abri-lo. Vamos ampliar o centro. Algumas das coisas óbvias que
queremos mudar primeiro, o nome do projétil, então vamos chamá-lo de Syth E então o sprite deve ser selecionado a partir da
textura do atlas para o sprite da foice Então, vou clicar
aqui, expandir a arte e usaremos os
mesmos sprites de madeira Então, se bem me lembro, há um
bom Syth aqui que podemos usar. Então, vamos selecionar
isso e clicar em Fechar. Agora você pode ver que
a caixa de acerto não
faz mais sentido porque
tem essa curva aqui. Então, queremos clicar em
nossa forma de colisão, e eu vou puxá-la aqui e depois expandi-la para a
direita, algo assim, ou poderia até torná-la mais
parecida com um quadrado retangular, se eu quiser cobrir
toda a borda da lâmina Então, vamos fazer isso. Agora, se
instanciarmos esse projétil, ele ainda funcionará
quase exatamente como a lança, onde simplesmente
avançará Então, o que realmente queríamos fazer é girar em torno
do ponto central Então isso vai significar que
precisamos de um deslocamento, e precisamos girar
esse deslocamento em um círculo e isso
nos dará nossa Então, vamos clicar com o botão direito do mouse no site. Vou adicionar um novo nó dois D, e então esse nó dois D será o pai do
Sprite e da caixa de sucesso Então, vamos colocá-los aqui embaixo. E então eu vou renomear
isso para Rotator two D, e vamos clicar com o botão direito do mouse e
anexar um script a Então, as armas Rotator
two D estão bem. Vamos criar isso, vamos dar
a ela o nome de classe rotator two D
e, em seguida, queremos colocar
algumas propriedades aqui Então, vamos dar uma velocidade
para esse nó rotador. Portanto, lembre-se de que esse
rotador é filho do objeto base. Então, o objeto base terá seu próprio movimento
e, em seguida, esse subobjeto controlará especificamente
a rotação Então, os dois se movem ao
mesmo tempo, mas são independentes um
do outro. Então, na exportação var velocity,
que é um vetor dois, terei esse
padrão de dez pixels à direita e
zero no eixo Y. Então, isso afetará
o movimento na tela. Mas também queremos que o nó gire
fisicamente, então parece que nosso
site está girando Então, ao exportar em graus de velocidade de
rotação, isso será um fluxo, eu o
padronizarei para 360, o que significaria uma rotação
por segundo neste caso. E então só
precisamos atualizá-lo no processo ou no processo físico. Vou fazer o processo de física para ser consistente com outros
movimentos do jogo. Então, digamos que nossa quantidade será igual a
graus de brilho. Então, vamos converter
esses graus
de velocidade de rotação uma quantidade de brilho. Então, precisamos dos graus de
velocidade de rotação multiplicados
pelo Delta para obter a quantidade de rotação desde a
última atualização do quadro
e, em seguida, vamos girar por essa quantidade Então, podemos até mesmo chamar essa quantidade RDs se quisermos deixar claro que é uma quantidade de brilho e eu também a
farei flutuar, apenas para dar o máximo de
clareza possível Ok, então precisamos mover
fisicamente o nodo, e isso será
baseado em nossa velocidade aqui em cima Então, vou dizer que nosso
movimento será igual
à velocidade vezes Delta E então chamamos de
translate a quantidade de movimento, e esse é essencialmente
nosso script rotador Então, se você precisar
personalizar quaisquer valores, você tem o inspetor
aqui para atribuí-los. Então, agora queremos
criar uma arma dois D que possa
instanciar nossa mira. Então, vamos procurar
a arma de lança se ao menos a
salvarmos no projeto Então, agora vamos procurar
a arma de lança. Nós vamos abrir isso. Vamos dar uma pequena olhada aqui. Portanto, esses são os dois nós D com um reprodutor AudioStream que reproduz o som de barra quando
instalamos uma arma Então, eu quero duplicar
isso e, em seguida, criar uma definição Syth
para nossa arma Então, vamos duplicar a cena da arma de lança como
arma Syth. Então, vamos procurar Syth novamente. Clique duas vezes em Open Syth, renomeie a arma de lança
para arma E então, à direita,
precisamos criar uma nova definição. Então, vou ampliar aqui, uma
nova definição de arma, e
essa será Syth. Nosso ícone, podemos simplesmente copiar do projétil Syth real Então, vou para a
cena do Syth e depois clicamos no sprite e clicamos com
o botão direito do mouse na textura,
copiamos, vamos
até a arma da foice
e colamos no
ícone com o
botão copiamos, vamos
até a arma da foice direito do mouse em Colar Ok, agora precisamos definir
alguns níveis de armas aqui. Então, vamos criar nosso conjunto. Começaremos com o
nível um da arma, novo nível de arma. Então, como queremos que
nossa foice funcione? Talvez a foice se mova mais devagar
do que um projétil normal. Talvez o resfriamento seja mais longo, então poderíamos dizer que cerca de 1,5. Antes de Max atingir,
vou colocar em cinco, para que a foice possa atingir muitos alvos antes
de morrer. Em caso de danos, vamos também
aumentá-lo para 20 a 30. E um projétil. Ok, então vamos adicionar
esse par de valores-chave
e, em seguida, vamos fazer o nível dois
com um novo nível de arma. Expanda o nível
um da arma para que eu possa comparar. E então eu vou causar,
digamos, 30 a 40 de dano, velocidade de 55, resfriamento de 1,4. Máximo de acertos de seis, e eu
adicionarei esse par de valores-chave. Vamos fazer o nível três, e
assim por diante, que você
quiser
fazer os números. Ok, então aqui estão os números que eu
usei no nível três da arma. Você pode pausar se
quiser copiar. Aqui temos arma de nível
quatro, arma de nível cinco. E arma de nível seis. E acho que isso deve ser
suficiente por enquanto. Ok, então, se bem me lembro, ainda não
defini
na definição de arma
a habilidade de escolher sua cena lotada. Então, na definição da arma, eu quero adicionar uma opção G vista. Então, por enquanto, vamos
padronizá-la para uma variável de exportação. Então, eu vou dizer que exporte uma cena de VR, e essa será uma cena lotada. Ok, e então, em vez de
Getsn carregar a lança, queremos retornar a cena Então, como estamos usando
um método get seen, podemos
posteriormente entrar e
alterar se houver algumas cenas extras que queiramos
considerar transmitir, em
vez do padrão básico. Mas isso deve ser bom por enquanto, mas realmente não precisamos de uma
segunda cena no momento. Ok, agora
só precisamos ter
certeza de que, na definição da
foice, carregamos rapidamente a foice E então na definição da
lança,
então pesquise a definição da lança.
Você clica duas vezes nele. E então precisamos
carregar rapidamente a cena da lança. Ok, e isso deve
ser bom lá. Acho que a última
coisa que precisamos para nosso Syth é o item Syth. Agora queremos encontrar o
item Spear em nosso projeto, duplicá-lo e criar
um item Syth Então, pesquise o item Syth. E esse item Syth que
vamos atribuir, é claro, a definição
de
foice Agora, para que nossos Sites sejam adicionados
como uma arma para nosso jogador, precisaremos de uma
referência à arma 2 D. Que podemos adicionar ao equipamento do
nosso jogador porque ainda não existe
no jogador, então ela
precisa ser Ok, então, para adicionar nossa referência
à cena da arma, não
podemos realmente usar a cena do pacto porque,
se fizermos
isso, ela terá uma referência
cíclica
porque a arma TD
já faz referência a esse recurso de definição de
arma Então, neste caso, para
contornar isso, precisamos fazer um arquivo de exportação, estará
entre aspas, ponto estrela TSCn, que significa que podemos
filtrá-lo por qualquer coisa que tenha a extensão dot
TSCN no final E vamos dizer var
weapon two D path, e isso será uma corda. Este é o caminho para
a cena de armas para adicionar dois
carregamentos de armas, como o jogador Ok, agora, se
olharmos nossa definição de lança, podemos atribuir à
arma dois caminhos D, que serão em armas, e então temos a
arma de lança aqui, Então é disso que precisamos. E então precisamos fazer a mesma
coisa com a foice Então, procure a foice. E parece que eu a
chamei de arma de foice, mas essa deveria ser a definição
do site aqui embaixo O TRES é a definição. A cena é a arma do local. Ok, então clique duas vezes
na definição do site e atribua o caminho a ela. Então, na verdade, você pode
simplesmente arrastar e soltar
daqui para lá, e
isso o atribuirá. Portanto, no item de arma atual, se o equipamento ainda não
tiver a arma
, precisamos realmente adicionar
a nova arma no
nível um ao carregamento , precisamos realmente adicionar a nova arma no
nível um ao Em vez de retornar
falso aqui e aplicar três vezes, na verdade
vamos
criar a nova arma Então, podemos dizer que a arma será igual a. Vamos dar uma olhada em nossa
arma de definição do caminho D, queremos instanciar Então, vamos dizer
carregar no caminho
e, em seguida, instanciar E essa vai ser
a nossa arma. Então, precisamos adicionar
isso ao carregamento. Então, carregue Adicione a arma e
nós vamos adicionar a arma. Se isso funcionar,
queremos voltar a ser verdade. Portanto, se tivermos nosso item, agora
podemos adicioná-lo
à lista de itens possíveis para
nossa interface de recompensa gerar. Então, se eu clicar na cena de seleção de
subida de nível e formos para o primeiro nó
aqui à direita, temos nossas opções de
nivelamento de nível um e já adicionamos o
item Spira Então, vamos adicionar o item do site. Então, carregue rapidamente o item do nosso site, atribua um peso de um e adicione-o. Ok. E então vamos clicar em Play e ver o que acontece
quando vamos até aqui. Então você pode ver que
diz item sem nome, e nós realmente não
vemos nenhum detalhe Se eu clicar em escolher,
na verdade não está lançando
o novo projétil Portanto, ainda temos algum
trabalho a fazer para isso, personalizando os itens e garantindo que eles sejam carregados
corretamente, e trataremos disso
na próxima parte
51. Ladrilho 50 Criando uma interface de usuário de exibição de armas para inventário de jogos: projeto realmente precisa agora é a capacidade de ver
quais armas
equipamos no canto superior
esquerdo com o indicador de interface do usuário. E quando subimos de nível para atualizar a primeira arma
ou escolher uma nova arma, eu também conheço esses nomes e
descrições aqui Isso também aparecerá
aqui para que possamos associar o que deveríamos estar vendo e o que estamos
realmente vendo. Então, isso nos
ajudará na depuração, mas também é muito útil
para o jogador Então, vamos
criar uma nova cena de interface de usuário, então vou clicar em Mais aqui. Então, eu quero nomear esse nó de
controle para, digamos, exibir
armas e também clicar com o botão
direito do mouse e mudar seu
tipo para um contêiner de painel. Ok, isso nos dará um
plano de fundo por padrão. Então, dentro daqui,
vou querer um contêiner de margem
e, em seguida, continuar com
o contêiner HBox
para organização Então, clique com o botão direito do mouse em Adicionar
um contêiner de margem
e, em seguida, clique com o botão direito em
Adicionar um contêiner HBox Ok, e aqui
vamos colocar basicamente um ícone com um indicador de nível
para cada uma de nossas
armas da esquerda para a direita. Vamos pegar a tela de
armas e reduzi-la para ficar muito
mais parecida com esta E então eu vou salvá-lo nosso projeto na pasta UI,
então na pasta UI, as
armas são exibidas. E vamos colocar uma cópia em nossa tela de interface de jogo possamos ver como isso
vai ficar mais ou menos. Então, procure a arma e,
em seguida, vamos pegar a tela
das armas e
posicioná-la sob a interface do usuário. E podemos ver que é
bem grande lá. Então você pode clicar aqui e
entrar na tela de armas, e vamos reduzi-la para talvez mais no
meio da tela Observe a caixa azul indicando o tamanho total da
nossa interface do usuário. Então, isso vai precisar
ser um pouco menor, na verdade. E eu provavelmente também quero me deslocar
do centro. Vamos também fazer o centro de layout
por padrão. Agora podemos voltar à jogabilidade UI Canvas. Podemos ver nossas armas
exibidas lá. Na verdade, não está
aparecendo como esperávamos. Então, na exibição de armas,
vou usar as
âncoras predefinidas e vamos usar o centro
por padrão ou o centro superior, e vamos usar o centro
por padrão ou o centro superior,
em vez disso. Então, no centro da parte superior. E podemos ver
o problema de por que ele se reduziu a nada Então, vou usar o tamanho mínimo personalizado
aqui e definir um padrão. Vou dizer 200 para o
X e depois 50 para o Y. Isso é só para que
possamos ver
e ajustar na
nossa interface de jogo Então, vou passar para
a jogabilidade UI Canvas, e agora podemos
posicioná-la onde precisarmos. Então, vou
posicioná-la, digamos, aqui à direita da nossa barra de saúde
principal e da barra EXB, e vou arrastá-la assim Ok. E então
podemos exibir alguns ícones de nossos níveis de armas. Então, para saber mais sobre isso,
vamos querer usar nosso contexto de jogador para que
possamos mostrar quais armas
o jogador tem. Então, na exibição de armas, vamos adicionar um script islas weapons
display dot GD E então vamos querer
exportar var o contexto, que é o
contexto do jogador aqui, e podemos atribuí-lo
no inspetor Então, carregue rapidamente o contexto
do player. E quando estiver pronto,
vamos querer usar isso para
obter referência ao nosso carregamento de armas Então, a função underscore está pronta, ela retornará void
e, em seguida, diremos
context dot player dot Temos uma referência
ao carregamento? Nós não temos. Então, se
não quisermos criar outra propriedade embutida
do player e fazer
com
que ela seja diretamente referenciada no script do player para ajustá-la, poderíamos dizer find children, e o padrão será composto por aspas vazias O tipo
será o carregamento de armas. Então, isso vai nos
dar uma matriz. Vamos obter o primeiro resultado disso fazendo
colchetes em um zero, que significa
índice de matriz de zero E vamos atribuir
isso a um carregamento. Portanto, nosso
carregamento de sublinhado será um carregamento
de armas E vamos dizer que o carregamento de
sublinhado é igual
ao resultado disso e queremos afirmar que isso não é nulo Portanto, assert underscore loadout
não é igual a nulo. É preciso ter uma carga
no jogador
para mostrar para exibição das armas, nome
percentual no final para que possamos obter o
nome desse nodo E então queremos que as armas do nome da
classe apareçam aqui no topo. Isso exibirá as armas e os níveis do personagem de
contexto. Então, vamos fazer outro
em Export var. Isso será para o UIC. Vamos dar
exemplos para cada uma
das armas em nosso equipamento Então faça um em Export var. Digamos que a exibição de armas, que será do
tipo exibição de armas, mas ainda não a criamos. E para indicar
que essa tela também faz mais do que
apenas mostrar os dados, mas também conecta tudo Na verdade, vou
renomear isso para ver. Isso também ajudará a diferenciar
da exibição de armas, o contêiner de subinterface do E então eu vou renomear
ambas as telas de armas. E então eu vou renomear
as duas armas, ponto GD,
e TSCN e Então, agora será
Weapons View e aqui em cima, armamentos view dot TSCN Ok. Além disso, entre na cena de visualização e renomeie
o nó raiz Isso é muito importante.
Então, as armas são vistas lá. Agora, precisamos criar nossa exibição
individual de armas para que ela possa entrar na visualização
das armas. Então, vamos adicionar uma nova
interface de usuário ao nosso jogo. Essa será uma
interface de usuário no início. E estou pensando
que a raiz aqui também pode
ser que seja um contêiner de painel. Você sempre pode deixar
um painel vazio, mas ter a capacidade de ter o plano de fundo é
meio útil. Então, vamos mudar isso
para um contêiner de painel. Vou renomear a raiz
para ser exibição de armas. Vamos clicar com o botão direito do mouse nele, adicionar um contêiner de margem do nó filho, caso seja necessário,
e clicar com o botão direito do mouse em Adicionar um wect de textura
para exibir nosso ícone Clique com o botão direito do mouse em adicionar uma etiqueta. E, na verdade, estou
pensando que não preciso um contêiner VBox ou HBox para isso, porque talvez
eu queira que o rótulo escreva sobre
a textura Para muitos jogos
que tinham uma textura e depois
texto ao mesmo tempo, ele realmente escreveria o
texto sobre o ícone da textura. Você veria muito isso nos sistemas de inventário
em relação ao número de itens
no inventário. Exceto neste caso,
estamos falando sobre o nível da arma que
está equipada para o jogador. Então, como texto de teste, poderíamos dizer o nível X aqui. Obviamente, podemos ver que a tela está
ocupando a tela inteira agora. Então, vamos realmente reduzir isso. Vou até a exibição da arma
básica
e levaremos o layout para as
âncoras predefinidas no canto superior esquerdo Ok, isso deve
reduzi-lo drasticamente. Agora podemos ver que está
apenas mostrando o texto. Vamos definir uma textura
nesse reto de textura. Então, farei uma nova textura de
atlas
e, em seguida, carregaremos
rapidamente um atlas Vamos procurar
talvez o 16 por 16. Folha Sprite em nosso
jogo para todos os ícones
e, em seguida, queremos editar a
região e selecionar uma Então, algo que
parece uma arma. Aqui temos uma espada que
funciona bem e podemos fechar. Ok, podemos ver que
o ícone da espada está lá, mas não respeita
a proporção, então queremos ir para o
modo de alongamento e mudar isso para manter o aspecto
centralizado, eu acho Ok,
aí está. E agora queremos pegar nosso contêiner principal de
exibição de armas, e queremos que ele também tenha um tamanho
específico. Então, vou dizer tamanho
mínimo personalizado de 48 por 48. Isso nos dará um quadrado aqui. E eu vou
querer pegar o texto do rótulo, e nós queremos que ele seja
centralizado na parte inferior Então, o alinhamento
vertical na parte inferior,
aqui no, você
verá que
isso não muda nada,
porque precisamos expandir o tamanho da
etiqueta para que o texto seja centralizado na parte Então vá para o layout agora, e nós vamos
querer o tamanho do contêiner
para preencher, eu acredito Sim. Ok, aí.
Então, agora ele vai mostrar o nível X
no canto inferior direito. E agora
parece que queremos um pouco de amortecimento entre nosso
reto de textura e nosso rótulo Por enquanto,
vamos salvar isso em
nossa pasta de interface de usuário, nossa tela de
armas. E acho que o que queremos é
um segundo contêiner de margem. Então, vou clicar
no primeiro contêiner de margem, adicionar outro contêiner de margem, e esse será
o pai da texturização Então, vamos posicionar isso no topo novamente para que
o texto apareça. Agora, com esse contêiner de margem, acesse as substituições de tema e queremos que a margem
inferior tenha algo em torno de dez pixels Dessa forma, o texto não
mostrará que você sabe, sobre as
partes importantes do nosso ícone. Talvez até
precisemos mais do que isso. Então, vamos tentar 12. Talvez até precisemos
mais do que isso, na verdade. Para que possamos ver como ficará mais adequadamente, vamos aplicar o tema do nosso jogo
à tela da arma. Então, clique na exibição da arma, encontre o tema e
carregue rapidamente nosso tema atual. Ok, agora isso é muito menor e está no canto
inferior esquerdo. Acho que quero isso no
canto inferior direito. Então clique na etiqueta e vamos fazer o
alinhamento horizontal para a direita Está bem? Parece
muito bom, mas está um pouco
perto da borda. Então, eu quero pegar o contêiner de margem
principal. Essa é a que está logo
abaixo da tela da arma, e eu quero definir algumas margens Então, vamos às substituições de temas e talvez dois pixels
em cada uma delas Ok, isso parece certo. Exceto talvez a parte inferior da margem.
Talvez não precisemos disso. Sim. Ok. Eu gosto mais disso. Tudo bem, agora, nossa
tela de armas precisará uma referência ao nodo D da
arma 2 E então, sempre que os
dois nós D da arma sobem de nível, mudamos o texto aqui
para mostrar o novo nível. Então, vamos adicionar um script
à exibição da arma. Isso só vai aparecer no ponto de exibição
GD do Uilashwapon. Ok. E esta será a exibição da arma com o nome da
classe. E precisamos de uma referência
à arma 2 D. Eu poderia
simplesmente exportá-la agora. Então, essa será uma arma var do tipo arma dois D.
Eu direi que valor definido, e essa será
arma igual Sempre que configurarmos a arma, acho que vou simplesmente chamar
uma função de atualização, e vamos configurá-la aqui Então, atualize a função. Portanto, para definir o texto no
rótulo e no ícone, precisamos obter uma
referência de exportação para cada um deles. Então, em Export var texture, texto direto do tipo textura Rc E então precisamos em
Export var label, que é do tipo label. E quando atualizamos,
queremos dizer que a textura de pontos
texrec será igual ao
ícone de ponto definição
de pontos da arma. Sim, isso funciona E então diremos que
o texto do ponto do rótulo é igual ao ponto da arma, se tivermos um nome
aqui, nome da arma. Não, queremos o
nome da definição porque o nome na arma é,
na verdade,
o nome do nó que não terá
espaços ou algo parecido, então é melhor obter
o nome do recurso porque essa é uma
propriedade personalizada que definimos. E então queremos
dizer que mais é igual a espaço mais uma sequência do nível de pontos da
arma. Está bem? Então, isso basicamente mostrará o nome da arma e, em seguida, em que
nível ela está atualmente. E caso a definição da arma
não tenha um ícone, vamos criar um método de obtenção de ícones. O que funcionará como fizemos com um dos outros scripts anteriores, que retornará null se essa propriedade não for definida Então, vamos clicar com o
botão direito na definição. Vamos abordar isso, clique com o botão direito do mouse na definição da
arma.
Vamos abordar isso. E então vamos criar
nosso ícone de função G, que retornará uma textura dois D. Então, se o ícone
não for igual a nulo, retornaremos o ícone Caso contrário, retornaremos null, e isso deve evitar
que você receba erros se o ícone for
nulo Ok, e provavelmente
também queremos tentar atualizar o R para que o sublinhado da
função esteja pronto, vou tentar fazer uma Isso também nos ajudará a confirmar que, se não houver
uma arma com dois conjuntos D, ela funcionará bem
e aparecerá em branco. A ideia aqui é
que sempre que
configurarmos a visualização de armas, ela seja preenchida
com exibições de armas Configuramos a arma e ela será atualizada imediatamente Então, vamos para a visualização de armas. E aqui dentro, bem, você vê que eu estava
exportando uma tela de armas, mas na verdade, o que eu quero
fazer é exportar a cena Então, essa será uma
cena lotada que podemos exemplificar. E então
carregamos rapidamente à direita nossa tela para a
arma, então exibição da arma. Então, pronto, quando
tivermos o carregamento, quero preenchê-lo com
todas as exibições
de armas de cada uma das armas que estão realmente em nosso Então, fiz algo
semelhante com o nível de seleção, em que eu apenas o limpo
e o reinicio a
cada vez, gerando novas cenas para gerando novas cenas para cada subinterface que
precisa ser criada Mas aqui, na verdade, vou
tentar reutilizá-lo que vocês possam
ver as duas abordagens Tecnicamente, esse
seria o melhor uso de seus nós, pois não precisaria
excluí-los e
recriá-los a cada vez. Então, acho que será útil
saber depois do curso. Então, uma das maneiras pelas quais
podemos acessar facilmente todas as
nossas telas
de armas ativas será ter
uma variedade delas. Então, eu vou dizer que var
underscore é exibido, e isso é uma matriz Vou ampliar a exibição das armas. Vamos também criar nossa função de
atualização. Portanto, nossa atualização
de função retornará nula. E para cada uma das armas
em nosso conjunto de armas, criaremos
uma tela, caso seja
necessário criar uma Caso contrário, se ela já existir nessa variedade de exibição de armas
, vou
reutilizá-la apenas atualizando as propriedades dela
com a nova arma configurando a arma
na arma Ok, então, para nossa função de
atualização, queremos percorrer
todas as armas, e faremos isso
usando as
posições do índice para que possamos combinar os índices de carregamento de armas com
nossos índices de exibição de Portanto, para IN, alcance zero para sublinhar o
tamanho dos pontos das armas de carregamento, aumentando Então vamos
primeiro pegar a arma. Então nossa arma será uma arma do tipo dois. Igual ao sublinhado das armas de
carregamento nessa posição de índice, e precisamos obter ou
criar a Então, eu vou dizer que var
display é uma exibição de arma, e vamos definir
isso como igual a obter ou criar uma exibição em uma posição de
índice de I. E então, em nossa tela,
uma vez que tenhamos adquirido isso, direi que
a arma exibida será igual à
arma em si. E como a
atualização faz parte
do setter e desse script, ela será imediatamente
atualizada automaticamente Agora, eu falei um
pouco sobre efeitos
colaterais e, se você
fizer o setter dessa forma, não está necessariamente 100% claro que configurar a
arma atualizará
automaticamente a interface do usuário Mas como isso é tão essencial
para a exibição da arma, acho que não há problema em dizer
aqui:
Oh, nós configuramos a arma. Claro, a arma mostrará a arma
atual. Mas como a exibição da arma
é literalmente o que ela faz, configurar a arma e
sugerir isso atualizaria a arma que
ela será exibida na interface do Eu não acho que seja
muito problemático com
isso como efeito colateral Mas é definitivamente
discutível. Então, agora só
precisamos obter ou
criar a tela. Então, funcione, obtenha ou crie uma
exibição com o parâmetro de índice, e isso será um número inteiro, e
retornaremos uma exibição de arma Então, digamos que a
exibição var do tipo de
exibição de arma seja igual
à exibição de pontos Get no índice. Ok, então isso pode ser nulo. Então, se display
não for igual a null, nós apenas retornaremos o display Caso contrário, precisamos criar
um aqui e adicioná-lo à tela para que
a tela seja
igual
à instância da
cena de exibição da arma E eu digitei esse nome errado. Então, aqui, Controle C, Controle V. E então
queremos adicioná-lo como filho
a essa interface de usuário, ou melhor , ele vai para o
contêiner HBox. Então, espere. Preciso de uma referência
ao contêiner. Portanto, exporte o contêiner de exibição V, e isso será qualquer
tipo de contêiner. Só precisamos exportar
isso na interface do usuário. Em seguida, pegaremos o contêiner de
exibição e adicionaremos o display
como resultado disso. Dizemos que as telas não se
abrem por meio de uma nova tela. E então, por fim, queremos
retornar a tela,
girar a tela Portanto, ele deveria ser criado aqui ,
se ainda
não existisse aqui. Então, isso resolverá
a criação dos novos monitores. Agora, e se removermos uma arma? Depois de percorrermos as armas e configurarmos
todas as telas, queremos verificar se a matriz de armas é realmente
menor que a nossa
matriz de telas e, em seguida, remover as telas extras. Então, digamos que removemos uma
arma do jogo e queremos que nossa tela
aqui seja atualizada. Bem, isso vai ser uma referência nula
na tela agora Então, podemos dizer que, para
exibição e exibição arma
I display dot é nula, então podemos simplesmente
liberar a tela Então, exiba o ponto Q gratuitamente
e espere aqui. Eu preciso ter esse sublinhado lá porque
é uma variável privada Portanto, temos nosso ponto de
exibição Q livre. Portanto, temos nosso ponto de
exibição Q livre e queremos redimensioná-lo
para nosso SI de carregamento Então, vamos realmente entender isso como uma variável local do tamanho de
nossas armas. Agora podemos reutilizar o tamanho das armas
aqui e aqui embaixo também. Ok, então, para percorrer
essa função novamente, ela atualiza e cria telas conforme necessário
para mostrar todas as armas, remove todas as telas
que tenham armas nulas e redimensiona a matriz de telas Então, obtemos o número de armas. Para cada uma dessas armas, atribuímos a arma à posição de
exibição correspondente. Então, depois de fazermos isso,
examinamos todas as telas
mais uma vez e, tecnicamente, poderíamos ir do
alcance da arma até o final dela,
mas otimizá-la um
pouco para não ganhar muito, porque estamos mostrando
apenas
seis itens aqui Mas se a
arma exibida for nula, mas aqui se a
arma exibida for nula, que poderia ser se
removêssemos uma arma, então vamos deixar
a fila na tela e redimensionar o conjunto de telas para que esse tamanho
corresponda às Em nossa tela G ou create, se a exibição existir
no mesmo índice, ela apenas retornará
isso e nós o usaremos. Caso contrário, ele criará
uma nova cópia da cena
e, em seguida, a aplicaremos no contêiner HBox Ok, agora no inspetor, temos
que atribuir aquele contêiner HBox Poderíamos renomeá-lo para Displays Container
se isso ajudar Então exibe o contêiner, mantendo
a nomenclatura consistente. E já temos a tela de
armas aqui. Então, isso funcionará em Ok, então vamos executá-lo e ver se
está funcionando em execução agora. Então, corremos e não conseguimos encontrar o carregamento de
armas porque acho que pode
ser chamado de carregamento de armas Então você pode ver que Fine Children é meio frágil assim Então, temos armas
carregadas lá fora. Então, vamos tentar encontrar o carregamento de
armas com o S e depois executá-lo Ok, então chegamos onde temos
textura de ponto igual ao ícone de ponto de definição de ponto da
arma Ok, então
encontramos outro problema. Eu não configurei o texto etiqueta
na tela da Então, vamos entrar na
exibição de armas e corrigir isso. No canto superior direito, quando você estiver
deslocando a arma, atribua a textura
com um clique duplo
e, em seguida, atribua Ok, e vamos
executá-lo mais uma vez. Veja se isso resolve os problemas. Ok, então aqui, quando não
há arma, isso vai causar um problema. Então, talvez nós
realmente queiramos que ele coloque uma arma antes de atualizá-la Portanto, como a atualização ocorre
aqui quando configuramos a arma, removerei a atualização pronta Não é realmente necessário
e, na verdade,
causa mais dor de cabeça aqui do que precisamos.
Então eu vou clicar em play. E tudo bem, lá vamos nós. Spear one lá
em cima, no canto superior esquerdo Vou até aqui e
selecionaremos o novo item. Agora, isso não
vai funcionar porque não
configuramos sinais. Ok, então um erro que eu cometi, quando você chama o Git em um índice que não
existe em uma matriz, ele vai te dar erros
fora do limite Então, o que realmente
devemos fazer é garantir que o índice
esteja na matriz. Então,
vamos dizer que se exibe , digamos que o tamanho é
maior que o índice, então vamos
retornar esse bit aqui, exibe pontos do Índice Git Claro. Em seguida, podemos remover a declaração
variável var display weapon display aqui embaixo até quando instanciarmos a cena de
exibição, e removeremos essa
linha na parte superior
52. Ladrilho 51 Conectando sinais e configurando a interface do usuário de armas para exibição dinâmica: Ok, então temos
mais alguns sinais para conectar em nossa visualização de armas e na
tela de armas para que,
quando estivermos no jogo, ela mostre corretamente a configuração correta
das armas
depois de atualizarmos a interface Então, uma questão muito importante
aqui será quando nosso equipamento
adicionar uma arma,
chamando o
método de adição de arma que
vamos conectar ao sinal de mudança de
arma, que acho que ainda nem
criei Então, vamos entrar no carregamento de
armas. Vou clicar com o botão direito
aqui, abrir o símbolo. Agora estamos no script GD do ponto de
carregamento de armas. Portanto, temos o método de adicionar
armas e queremos admitir
um sinal aqui para que nossa visão possa
responder a isso. Então, no topo, vamos criar
nossa mudança de armas de sinal. Se quisermos, podemos passar o conjunto de armas
para o sinal. Então, armas, que é
um conjunto de armas 2 D. E agora só
precisamos admitir isso aqui
embaixo
quando chamamos adicionar arma. As armas são trocadas, os pontos de emissão são emitidos e nós entregamos as armas Está bem? Agora, de volta ao
nosso script de visualização, assinamos so on ready Depois de obtermos o loadout, queremos fazer com que as armas de sublinhado mudem conexão E vamos dizer
que nenhuma arma foi trocada. Vamos fazer esse método aqui
embaixo. Então, a função das armas mudou. O parâmetro é a arma P, que é uma matriz de duas
armas D, que
retornaremos vazias Agora, vamos
chamar a atualização aqui. Isso é tudo o que precisamos
fazer porque a atualização já controla
a carga das armas e
quais armas temos,
qual é o tamanho delas Então, na verdade, não
vamos
usar diretamente essas armas P aqui, então vou sublinhá-las
para que não recebamos um aviso E agora, antes de clicarmos em play, quero ter certeza de
que nossos itens estão realmente definidos corretamente. Então, no sistema de arquivos inferior
direito, vou pesquisar o
item. Temos o item Syth Então, vamos ver se vamos
para o topo agora, este é um item sem nome,
sem descrição, e também precisa de um ícone Além disso, parece que eu também
entendi o item errado, parece que tenho a definição
errada do item. Isso faz muito
sentido agora, por que a arma da foice não apareceu Então, vamos carregar rapidamente aqui
a definição de foice. Ok, então isso está configurado corretamente, mas temos que definir
nosso nome de exibição. Foice. Então, para a descrição, vou colocar um
projétil que gira ao redor da tela e
pode atingir muitos inimigos Essa é basicamente sua principal
diferença em relação à lança. E para o ícone, bem, vamos entrar na definição de
foice Vou clicar com o botão direito do mouse no
ícone aqui e copiá-lo ,
fechá-lo e colar no ícone aqui. Ok, agora precisamos
fazer algo semelhante no item da lança. Então, clique
duas vezes na lança. Em seguida, iremos para o canto superior direito. O nome de exibição será lança. Portanto, a descrição pode ser
um projétil básico que avança da
direção em que o personagem, eu acho, direi, está olhando E então o ícone, nós
apenas copiamos isso
da definição para o ícone do
item. Assim mesmo. E isso basicamente deve lidar com muito
disso. Então, vamos jogar. Acho que a única
coisa agora é que
não estamos conectados a
um sinal de subida de nível, mas tudo bem, podemos ver a lança
um no canto superior esquerdo Vamos pegar nossa foice. Então, a foice 1 está agora lá em cima, e nosso projétil de foice também
está sendo lançado Podemos ver que está girando. Talvez sua velocidade de movimento não seja realmente suficiente porque
queremos que ela realmente gire em um
círculo ao redor do jogador. Mas vamos garantir que ele possa atingir. Sim. Ok, então parece
estar atingindo inimigos Bem rápido, nas opções
geradas, há um aviso sobre o sombreamento
selecionado e o sinal já declarado Então isso não é ótimo.
Vou pegar a matriz selecionada
e gerar opções. Isso está no script de visualização de
armas. Isso está no contêiner da
caixa de recompensas aqui. Vou pegar isso e controlar R. Vou
renomeá-lo para itens selecionados Vou clicar em substituir,
não substituir tudo,
porque lembre-se que não queremos mexer com
os nomes dos sinais aqui Então, substitua somente dentro
dessa função, e queremos ir até aqui. Também devo combinar maiúsculas
e minúsculas e palavras
inteiras para ajudar a reduzir o número de coisas
extras selecionadas. Portanto, o datapen selecionado agora
é o datapen de
itens selecionados e, em seguida,
retornamos OK. Então, isso deve
lidar com esse aviso. Ok, então a cena do nosso site não estava girando exatamente da maneira
que esperávamos Então, um problema com os scripts do
projétil é que, se eu tentar dizer, execute essa cena sem lançá-la primeiro de uma
arma de dois D, vamos
preparar esse problema em
que ele atingirá a afirmação Então, o que poderíamos fazer em vez disso para fins
de teste, principalmente, é ter uma direção
padrão. Então, vou dizer
que a direção será igual ao
vetor dois pontos à direita. Então, basta ter esse padrão lá. Removeremos a declaração. Por isso, também vou
exportar o nível de variação para que tenhamos a opção de definir um nível de arma no inspetor Não deveria ser
necessário para nós, porque na maioria das vezes,
lançaremos por meio do método de
lançamento, certo? Foi assim que
montamos o projétil. Mas caso queiramos
testá-lo no editor, eu poderia configurar um nível de teste
aqui e o direito
para que pudéssemos definir a velocidade padrão da arma. Então, vamos clicar em Play. Ok,
agora com essa configuração, devo ser capaz de
executar esse script e ver como ele se
moverá por padrão, o que é muito útil para
nós lá no topo. Eu poderia até criar uma cena de
teste em que tivéssemos uma câmera
olhando para o centro da uma câmera
olhando para o centro da
nossa, para nos ajudar ainda mais em nosso propósito de
depuração visual, que não precisemos rodar
o jogo completo e subíssemos de nível toda vez que quisermos
testar o Então, vamos criar nossa cena de teste. Então, essa
será uma nova cena em dois D, e eu a salvarei na raiz. Então, vamos chamá-lo de teste de
armas dot TSCn. Guarde isso, e eu vou colocar
a arma da foice. Então, foice, arma, ponto TSN. Acabamos de colocar isso
na raiz. Vou renomear o nó raiz. Então teste as armas e, em seguida
, clique com o botão direito do mouse e adicione uma câmera ao D. Então isso terá um zoom de três.
Eu acho que é bom. E vamos tentar
executar a cena
clicando no botão reproduzir cena
atual. Ok, então a razão pela qual
não vemos nada
aqui é porque não devemos colocar a arma de
foice aqui Devemos colocar o
projétil Syth. Então, meu erro. Então, vamos procurar por sythe dot
Tscn e soltar isso na raiz. Agora, se aumentarmos o zoom,
devemos ser
capazes de ver isso. Ok, isso é bom. E vamos apertar o botão Executar a cena
atual. Agora podemos ver como ficará quando nossa foice disparar para a direita, e
isso tornará muito mais fácil e rápido
depurar Agora, com nossa configuração de cena de
teste, podemos ver como nossas armas giram e se movem
na tela, mas não é
exatamente isso que estamos procurando Então, o que realmente
precisamos mudar aqui
é voltar à cena da foice, esse nó rotador Se quisermos que a
arma ou o sprite gire em torno de um ponto central, precisamos mover
esse deslocamento do rotador para a direita,
mantendo nosso sprite
e a caixa de acerto na esse deslocamento do rotador para a direita,
mantendo nosso sprite
e a mantendo nosso sprite e Então, vou
mover temporariamente esses dois para fora
do rotador dois D para que eles não
se movam com ele, e então vou
mover o rotador dois D para a
direita assim Ok, então isso nos
dará um deslocamento para que tudo ao redor possa
realmente girar em torno desse ponto em vez de apenas girar
aqui em Então, vamos trazer isso direto
da caixa de impacto de volta para
o rotador dois D. Ok, bom. E talvez queiramos aumentar a velocidade X para 25 Vamos examinar a cena e ver se isso nos dá
o que estamos procurando. Então, sim, mas isso é um
pouco rápido demais, na verdade. Então, talvez nós apenas baixemos isso volta para o padrão
de dez e o executemos novamente. Então, é a rotação que está
realmente fazendo isso. Então, ou precisamos de uma
rotação mais lenta ou talvez precisemos que ela esteja
mais à direita Não tenho certeza de qual.
Isso é uma espécie de adivinhação para mim aqui. Então, se acontecer de você mover o rotador com esse sprite
e a caixa do quadril embaixo dele, certifique-se de
movê-los de volta
ao ponto central 00 E então vamos executar a cena de
teste e ver. Acho que apenas 360 graus
é muito rápido. Ok, então eu vou
voltar para a terceira cena e vamos diminuir os graus de
rotação. Vamos cortar isso
pela metade, talvez 180. E então vamos executar
nossa cena de teste. Ok, provavelmente é muito
mais parecido com o que queremos, mas eu também aumentei muito a distância do rotador agora Ok, então vou mover o sprite
dois D
para fora e a caixa do quadril para fora, e vamos mover o rotador de
volta bastante para dentro Mova o sprite e a
caixa do quadril de volta para baixo do rotador. E vamos testá-lo na cena
de armas de teste. Ok, então vamos executar isso. Uh, quase. Mas talvez a velocidade do
projétil ainda seja muito rápida. Eu não sei Precisamos
testá-lo no jogo. Então, vamos clicar em play, e isso realmente
executará o jogo principal porque essa é a cena principal. Então, vamos pegar a lança, o projétil
da foice. E essa é a aparência da nossa
arma de foice no momento Não tenho certeza se estou muito
feliz com o padrão, mas pelo menos está cumprindo
o conceito geral. É principalmente uma questão de termos que ajustar
as variáveis agora Deixe-me tentar fazer com que o jogador
seja atingido e destruído. Ok, então ele ainda
se retira da cena, mas teremos que
criar a tela de game over. Como parte do
aprimoramento do curso. Então, vou
executar isso mais uma
vez para pegar nosso projétil de
foice É como
ir para a direita. Eu prefiro que seja mais, tipo, centralizado para a direita Deixe-me ver se consigo ajustar isso. Talvez seja o resultado
da velocidade X. Vou tentar desligar isso
e vamos rodar a cena novamente. Ok, então agora é
um pouco assim. Voltará
ao início aqui. Porque o rotador não
tem velocidade extra. E a direção em que ele é lançado depende se você está
virado para a esquerda ou para a direita. Então, pelo menos, é uma aplicação
igual para os dois lados.
Talvez você goste disso. Talvez você não. É
principalmente uma questão de ajustar as variáveis para obter o padrão desejado
para o movimento Então, pelo menos por enquanto, eu diria que é bastante aceitável. Vamos aumentar o nível da arma de
lança aqui. E isso vai aumentar o
nível da arma, mas não temos um sinal de
aumento de nível conectado aqui. Ok, então onde fazemos isso
é na tela de armas. Vamos entrar na exibição de armas. Quando colocamos a arma aqui, precisamos conectar os sinais. Mas, nesse ponto, eu diria que isso é,
na verdade, colocar muita coisa em um
setter para a arma Isso meio que esconde o que deveria fazer. A
atualização foi boa. Mas acho que se estamos
conectando sinais e atualizando a interface do usuário,
isso é demais. Então, vamos criar uma arma com conjunto de
funções. que passará em uma
arma, a arma 2 D. Ok, então se a arma não for igual a null e diremos que o
nível de pontos da arma alterado está conectado, então faremos
um retorno de chamada aqui, sublinhando o nível da arma Claro, isso vai nos
dar um erro porque o nível alterado ainda não
existe na arma. Então, vamos pular na
arma, procurar o símbolo. Vamos criar um sinal aqui, nível do
sinal alterado, que você passará no
nível, que é um número inteiro Se isso é tudo que vou
fazer com esse nível, e acho que é, então
vamos dizer valor definido. Diremos que se o nível for igual
ao valor, retornaremos com sabedoria, nível é igual ao valor e
podemos alterar o nível Nos níveis. Então, estamos meio que tornando essa
propriedade observável, e isso é tudo que
vou mudar lá O motivo dessa proteção é que, se definirmos o nível como o nível, não
queremos emitir sinais de interface de usuário
desnecessários
porque o nível, na
verdade, não mudou Portanto, só precisamos
fazer essa atualização se estivermos
configurando-a com um novo valor. Agora, eu esqueci dois pontos
aqui no topo, então isso
eliminará esse erro Agora, em nossa exibição de armas,
o nível foi alterado. Precisamos criar uma função de retorno de chamada
alterada
no nível da arma função de retorno de chamada
alterada Então, a função copiar e colar
no nível da arma mudou, e então temos o
nível P, que é um número inteiro Vamos retornar void e queremos
atualizar a interface do usuário Uh, mas o que estamos realmente
fazendo aqui é nos desconectar do sinal da
arma antiga, se ele existir Então, verificamos se a arma antiga existe aqui, verificando
se ela não é nula Então, se o sinal estiver conectado,
precisamos desconectá-lo. Nível de pontos da arma alterado ponto de desconexão no nível da
arma alterado Sem parênteses. E essa
parte é apenas verificar se o sinal está realmente
conectado antes desconectarmos um sinal
que não está Então, apenas guardas de segurança. Ok, então preparamos a arma antiga para ser
totalmente desconectada, então podemos trocar a arma agora Então, vamos dizer que arma
é igual à arma P, e então queremos nos conectar a
esses sinais de
mudança de nível de armas Mas também podemos colocar um guarda verificar se ele já está
conectado por qualquer motivo. Isso é um pouco
excessivamente seguro, mas poderíamos dizer que, se o ponto de mudança de nível da arma já estiver conectado a essa função aqui
embaixo, e quisermos
fazer o inverso Então, estamos dizendo que se não estiver conectado,
precisamos conectá-lo. Então, o nível de pontos da arma
mudou, dot Connect, sublinhado no
nível da arma mudou E também queremos atualizar, com certeza. Então, vamos atualizar isso Então, quando configuramos a
arma, nós atualizamos
e, toda vez que o nível
muda, nós atualizamos Então, agora queremos pegar
essa propriedade e sublinhar e
torná-la privada Então, isso será mais
como uma variável privada. E não queremos modificar isso
diretamente. Queremos
encorajar fortemente qualquer pessoa que esse script a usar o método set
weapon em vez disso. Então, vou selecionar aqui, e vamos controlar e basicamente encontrar e substituir. Portanto, certifique-se de combinar
maiúsculas e minúsculas e palavras inteiras, e então vamos mudar isso
para arma de sublinhado Acho que podemos nos safar
com a substituição em massa aqui. Portanto, todas as 11 instâncias
substituem todas. Esse é o Control R para
abrir esse menu. Agora, é claro, se
rodarmos o jogo
, obteríamos
um erro porque estamos tentando configurar a arma, não sublinhar a arma
do ponto de vista das armas Então, se formos para a visualização de armas, agora em nossa atualização, queremos chamar a arma display
dot set
na arma dois D com a arma
dois D e remover isso Então, todo o motivo para mover o código de
configuração de arma reativa para esse
método explícito de conjunto de armas é para que saibamos que há
mais coisas acontecendo aqui do que simplesmente definir
o valor da arma A propósito, livre-se
dessa atualização. E podemos até remover isso, mas aqui, neste momento, é basicamente apenas
uma variável regular. Mas não queremos
esconder o fato de que ele está conectando e
desconectando sinais
e atualizando a interface do usuário Pode ser um pouco mais explícito. Então, todo esse código poderia
facilmente estar sob o configurador de
variáveis de arma,
mas ter essa
grande função de bloco escrita meio que deixa
mais claro qual é a nossa intenção E eu sei
que isso meio me
contradiz quando
antes eu pensava:
Ok, você pode simplesmente montar armas
e usar a atualização Mas como
também estamos emitindo sinais, acho que há
muita coisa acontecendo, e não queremos
esconder isso de ninguém que esteja
tentando configurar a tela. Queremos que eles
saibam: Ok, existe grande função de arma. E isso é lidar com
todas essas coisas extras. Ah, certo. Então, vamos seguir
em frente e rodar o jogo, e eu vou subir
o nível da lança até o nível dois Ah, ok, então você
pode ver que havia outra referência à
variável de armas , mas nós a
tornamos privada. Então, queremos que alguém consiga pegar
a arma em vez acessar a
variável privada lá Deixe-me dar uma
olhada nessa função e ver se ainda
precisamos dela. Ok, então, como a visualização das
armas
está funcionando para liberar
as telas antigas, precisamos que a arma de
exibição de pontos seja substituída pela arma de
exibição de pontos Git Então, vamos criar essa
função na tela da arma. Então, funcione aqui,
arma Git que
retornará uma arma para D.
Vamos apenas dizer que,
se for arma sublinhada, retornaremos arma sublinhada,
senão retornaremos nula Então, por que se preocupar em ter
essa função de arma Git quando você pode simplesmente acessar diretamente
a variável de arma Bem, tornamos essa arma privada porque
queremos ter certeza de que encorajamos qualquer desenvolvedor a usar a
função de configuração de arma explícita E como essa é
uma variável privada, não
devemos acessá-la
de fora do script. Então, precisamos de uma função pública Get weapon
para acessar isso. Então, é basicamente
encapsular e impedir outras pessoas
façam coisas com o script onde não
deveriam fazer isso
com o Agora, mais uma vez, o sublinhado
é apenas uma prática de indicar que ele deve
ser privado de forma eficaz, mas o GD Script realmente
não tem privado ou público como palavras-chave Portanto, você não pode realmente impedir
que alguém o acesse. Você só pode indicar sua
intenção com o sublinhado. Ok, então vamos fechar isso e rodar a cena mais uma vez. Vou subir o nível da nossa lança. E vamos fazer o upgrade da lança. Então você pode ver que
Spear foi para o nível dois ali mesmo
e no canto superior esquerdo Claro, essa interface do usuário é muito pequena, preciso aumentá-la. Então, vamos para a
jogabilidade UI Canvas, e eu vou clicar aqui. Na verdade, vou mudar o
layout e centralizá-lo. Então, Anchors ficará no centro, e então eu quero
compensá-lo a partir daí, mais ou
menos Também entre na cena de exibição de
armas. Então, se eu for transformar aqui, ficarei mais parecida
com 400 pixels por 75. Quero ter certeza de que a
âncora ainda está centralizada, para que eu possa personalizá-la aqui e depois voltar para a parte
superior central para recentrá-la Vamos dar uma olhada na
jogabilidade UI Canvas. Ok, isso ainda é bom. Vou entrar na
exibição de armas a partir daqui novamente. E acho que o principal
é que precisamos apenas
garantir que cada uma
dessas exibições individuais, o ícone esteja configurado para
um tamanho mínimo. Então, se eu olhar a exibição de
armas aqui, vamos pegar o
tamanho mínimo e criá-lo. Poderíamos até dizer 96, 96. Vamos torná-lo grande e depois reduzi-lo, se necessário Então, o rótulo de texto aqui, eu também preciso que seja maior ?
Talvez eu tenha. Vamos simplesmente substituir
o tamanho da fonte aqui. E eu vou fazer com
que seja, digamos, 16. Ok,
isso é o que está acontecendo agora 32. Ok, então vamos tentar 32. Diminua o zoom. Vamos apertar o play. Como está na interface
do usuário no momento? Ok, isso é muito melhor. Então eu vou pegar a outra arma. Nós temos nossa foice.
Então lança, foice Acho que a única
outra coisa é que talvez um pouco de
contêiner de margem ajude. Então, feche o jogo e,
na visualização de armas, nosso contêiner de margem, vamos
substituir o tema Estou pensando em constantes
de dois em todos os lados. Vamos clicar em play. Execute-o. E isso não ajudou muito. Vamos fazer quatro pixels
em todos os lados, eu acho, e apertar play. Ok, isso é pelo menos mais
visível. Vou fazer com que sejam seis. Então, seis de todos os lados,
isso deve ser suficiente. Ok, então entramos no modo de jogo. Ok, agora temos uma pequena
barreira entre nosso contêiner individual
e a visão geral das armas. E isso parece
muito mais sólido. Então, está mostrando
o tipo de arma que
temos e o
nível da arma, e essa é provavelmente a maior parte do que realmente
precisamos que ela mostre. Então, acho que estamos
prontos para ir aqui. Deixe-me subir de nível para curtir. Vamos pegar o Syth Level 2. Sim, Syth também está
subindo de nível corretamente. Então, isso basicamente ajuda
a configurar a visualização das armas e a tela cheia, com todos os
sinais conectados, corrigindo os
itens, garantindo eles tenham uma
descrição e um ícone, e apenas com aquela interface de usuário clara, qual podemos ver o que
realmente está acontecendo
com nosso jogador
53. Ladrilho 52 - Criando itens de aumento de estatísticas para atualizações de jogadores: Portanto, com nosso
sistema de nivelamento trabalhando a capacidade de escolher
um item de arma e
atualizar nosso carregamento de armas com uma nova arma ou um
nível aprimorado de uma arma, agora seria o
momento perfeito para adicionar a habilidade de escolher uma atualização não
relacionada
a Por exemplo, um item de aumento de
etapa, que
aumentará permanentemente nosso HP ao subir de nível E podemos até mesmo transformá-lo em um item que tem uma chance rara de derrubar
inimigos, se quisermos Em nossa pasta de itens,
no canto inferior esquerdo, vou expandir isso e criar outro
tipo de item. Vou clicar com o botão direito aqui
e criar um novo script. E poderíamos chamar isso de item
Stat Boost dotGD. Isso se estenderá a partir do recurso. Então, é uma espécie de tipo de
definição. E então, em nosso
item Stat Boost, vou abri-lo e
dar a ele o
nome de classe Stat Boost Ah, e isso na verdade
vai se estender da
classe básica do item, não do recurso. Então, se olharmos para o item, temos o Trapply
e o Can apply Então, vamos
pegá-los porque
precisamos implementá-los
em nosso Stat Boote Então, eu vou apenas
colá-los aqui. Então, para se inscrever, queremos
verificar se o alvo tem, ,
um bloco de estatísticas e B. Esse bloco de estatísticas tem a estatística que estamos tentando aumentar Poderíamos criar várias classes
diferentes para, digamos, aumento de
HP e item de redução de
resfriamento. Mas, em vez disso, vamos
simplificar isso com um nome estatístico de export var, que é um nome de string E vamos definir isso igual
a nada por padrão. E então vamos fazer uma alteração no valor de
export var, que é um float E vamos definir isso igual a 0,0. Então,
primeiro de tudo, quero tirar o Spblock do
player, se ele existir Então, eu vou dizer que var
Stats é um controlador de estatísticas, e vamos
tirar isso de ptarget dot get, e vamos obter esse nome de
estatística como Então, isso pode acabar sendo nulo. Então, se as estatísticas forem nulas, retornaremos false aqui Outra coisa que queremos verificar é a mudança de valor
realmente definida. Então, se a mudança de valor
for igual a 0,0, vou enviar um aviso. Não é possível aumentar a estatística
se a mudança de valor for definida como 0,0 ou na verdade, digamos que a porcentagem é um pouco mais flexível
e, em seguida, a alteração percentual do valor E retornaremos falso aqui. Então, a razão para isso é que, se não
configuramos o item, ele realmente não fará nada, então
vamos pular a aplicação
e colocar um
aviso
para vamos pular a aplicação e colocar um
aviso saibamos que esse é um problema
que precisamos corrigir apenas
alterando
a propriedade de alteração de valor
para outra coisa Não há uma função pronta para verificar essas coisas,
como
seria com um nó, porque
os recursos nunca estão prontos. Então, este parece ser um
bom lugar para colocá-lo. Vamos verificar isso
antes de nos inscrevermos. Caso contrário, acho que
podemos voltar à verdade. Acho que esses são os dois principais constituintes que
estamos observando Então, a outra coisa que eu
queria ter certeza, na verdade, era essa parte. Então, estamos vendo se as
estatísticas têm o nome da estatística, então eu realmente configurei
isso incorretamente Queríamos dizer se o ptarget
dot obtém estatísticas aqui. Então, primeiro, estamos obtendo
o controlador de estatísticas
e, em seguida, queremos verificar
se stats dot G stat Name Não é igual a nulo. Se
isso for igual a null , retornaremos false Então, primeiro, garantimos que
ele tenha um bloco de estatísticas, depois garantimos que
ele tenha a estatística
e, em seguida,
garantimos que realmente configuramos esse item corretamente
para alterar o valor Ok, então, uma vez que
passarmos tudo isso, poderemos aplicá-lo. Então, aqui embaixo, eu quero pegar o
controlador de estatísticas mais uma vez, então eu estou apenas copiando e colando isso
daqui para baixo Obtemos o controlador SATs
e, em seguida, queremos obter o valor atual e
adicionar a alteração a esse valor Portanto, nosso valor atual
será igual a stats
dot GET stat name
e, em seguida, vamos
pegar isso e incrementá-lo Então, digamos que nosso novo valor será igual ao valor
atual mais
a alteração do valor. E então definimos esse
valor nos Sts. Então, stats dot define o
nome da estatística para o novo valor, e eu adiciono um pequeno erro de digitação lá, então certifique-se de que esses
nomes estejam E então queremos voltar à realidade. Portanto, também podemos verificar
aqui, mais uma vez, apenas para ter certeza de que as estatísticas
ainda foram realmente encontradas. Portanto, se as estatísticas forem nulas,
retornaremos false. E talvez queiramos realmente
um erro aqui porque
devemos verificar se
podemos aplicar logo
antes de aplicá-lo. Portanto, as estatísticas do
controlador de estatísticas de push e erro não
foram encontradas na meta de
porcentagem S, porcentagem P. Então, isso vai pegar o nó e substituí-lo
lá. Tudo bem Sim, então, para estatísticas
que recebem um nome, estamos basicamente mudando
isso para flutuante por enquanto O novo valor é flutuante, e nós o colocamos de volta
no valor estatístico Agora, algumas de nossas estatísticas,
como HP, são números inteiros. Então, quando colocamos isso de volta
no controlador de estatísticas, ele o reduzirá
novamente para um número inteiro e
perderá nosso valor flutuante Portanto, a ideia aqui
é que, se você quiser aumentar um número inteiro, certifique-se de usar valores
não decimais no item
real de aumento de estatísticas Portanto, perde um
pouco de clareza, pois estamos apenas agrupando números inteiros e flutuantes na mudança de valor,
mas isso nos dá
a flexibilidade de
poder lidar com
a grande maioria de nossas estatísticas por meio de uma classe,
em vez de criar uma para mudança de HP,
outra para aumento percentual de dano, Apenas muito menos scripts nos quais
as coisas poderiam dar errado. Então, vamos criar
nosso item HP Boost. E na
pasta de itens, no canto inferior esquerdo, vou criar
um novo recurso, que será
um item de reforço do SAT. Então, isso vai para
a mesma pasta. Vou chamá-lo de HP Boost, sublinhar os pontos do item e salvá-lo Agora, à direita,
temos nosso item SAT Boost. Então, o SAT que queremos mudar
será Max HP, e gostaríamos que aumentasse 50. Agora, eu vejo uma falha aqui, que é que, se
aumentarmos o MX HP, ele também não aumentará
o HP básico Então, temos que tomar uma decisão sobre como queremos
lidar com isso. Uma maneira seria que, sempre que
aumentássemos o HP MÁXIMO, ajustássemos o HP
automaticamente em nosso
script de controlador de pilha nessa quantidade Então essa é uma opção.
Deixe-me verificar o controlador SC se
isso faz algum sentido. Então, pesquise o
ponto gD do controlador de pilha e o projeto, abra-o e veremos que
temos o MAX HP. Assim, podemos ver a mudança
fazendo o MAXHP menos o e podemos dizer aqui que,
se a mudança for positiva, afetaremos o No entanto, acho que isso está realmente começando a
aumentar esse setter,
e pode ser que, na verdade queiramos
alterar o HP máximo em
alguns itens,
mas não o HP básico Então, acho que uma maneira um pouco melhor de fazer isso seria em
nosso item de aumento de estatísticas. Na verdade, temos um dicionário de estatísticas que queremos alterar e depois as examinamos Dessa forma, podemos fazer MaxHP
e HP ao mesmo tempo. Poderíamos até ter
um item que aumente, digamos, HP máximo, HP e ataque de uma só vez, e isso exigirá apenas um pouco de quatro ciclos Então, vamos mudar
isso, vamos torná-lo um export var Stat changes E este será um dicionário de nomes de strings com
os valores flutuantes Está bem? Então, vamos nos
livrar disso agora, e isso nos dará
alguns erros imediatos. Portanto, queremos garantir que
cada um desses nomes de string exista no controlador de estatísticas Então, poderíamos dizer que quatro teclas
nas estatísticas mudam as teclas de pontos. Vamos apenas verificar se a chave está realmente nesse controlador. Então, se a chave de estatísticas do
Git for nula, ela não tem as estatísticas, não
podemos modificá-la,
isso é um problema E então podemos
simplesmente fazer aqui embaixo. Para o valor nas estatísticas, os valores dos pontos são
alterados. Em seguida, verificaremos se o
valor é igual a zero e, seguida,
teremos esse problema, então
substitua-os por valor. Ok, então, tecnicamente, aqui, estamos fazendo dois loops, e isso está abaixo do Então, a melhor maneira de fazer isso seria simplesmente obter o valor da chave. Então, direi que o valor var é igual
à tecla de ponto G de alterações de estatísticas
e, em seguida, podemos verificar o valor sem
os quatro loops extras Então, vou cortar isso
e colar aqui, remover os quatro segundos loops. Isso deve torná-lo muito mais eficiente e fácil de ler porque agora estamos
lidando apenas com isso 14. Ok, agora aqui na parte inferior, precisamos fazer algo
semelhante para
teclas de ponto que mudam as estatísticas Precisamos obter o valor
de cada um deles. Então, vamos rever
isso, para que faça parte do ciclo quatro. E diremos que stats dot Get key. Isso nos dará
o valor atual. Tomamos o valor atual
mais a mudança de valor. Isso nos dá um novo valor. Então, de onde obtemos
a mudança de valor? Bem, precisamos dizer que a mudança do
valor de var é igual
à tecla Stat Changes dot
Get. Ah, hein. E então temos o
novo valor quando
os somamos , conjunto de pontos de estatísticas. Sobre o novo valor, espere. O nome do conjunto não foi declarado
no escopo porque o nome do
conjunto é a chave. Então, queremos definir a chave com o novo valor
no controlador de estatísticas. Ok. Agora, vamos pesquisar o
item no projeto. Vou abrir o item HP Boost. Agora temos a
capacidade de lidar com várias mudanças de estatísticas de uma só vez Então, vou fazer o MaxHP
e serão 50. Quero fazer o MXHP
antes do HP porque
quero aumentar o MX HP
antes de tentar aumentar o Portanto, o HP também será 50 aqui. Então, aumentamos o MX HP
e, em seguida, o HP subirá 50 Se você estiver no FHP, deve
estar no FHP pela segunda vez. E então vamos chamar o nome de
exibição aqui, HP boost. A descrição
aumentará o HP máximo em 50. E então, para o ícone, vamos
criar uma nova textura de atlas. Vou expandir isso. Vamos fazer o upload
rápido do nosso projeto e eu obterei a folha de sprites de 16
por 16 Então, vamos editar a região
e escolher uma. Então, amplie, temos
algo parecido com uma poção de saúde, algo que
faça sentido para nós Há uma gota de sangue
que pode ser viável. Ou aqui está um coração. Essa é
outra boa opção. Ok, eu meio que gosto dessa farinha. Então, vamos pegar essa farinha vermelho-sangue
carmesim, e vamos escolhê-la para
que possa ser o ícone do nosso item E vamos testar isso
adicionando-o como uma opção em nossa cena de aumento de
nível de jogadores. Então, na cena de seleção de aumento de nível, vou clicar em
nossa seleção LevelUp E temos nossas opções de
itens aqui. Vou
carregar rapidamente um novo item. Então, esse
será nosso item de aumento de HP. Vamos dar
uma chance de queda de
um e clicar em Adicionar par de valores-chave. Ok, agora podemos clicar em
play e entraremos aqui. Vou
subir de nível e vamos selecionar nosso aumento de HP. Escolha isso e
você verá que, de
repente, temos 160
HP, e é assim que subimos de nível. Então, você pode ver daqui
que seria muito fácil aumentar outras estatísticas,
como dano de ataque, redução de
resfriamento, o que mais? Velocidade de movimento, etc., para seu personagem, pois você
precisa dar atualizações
54. P53 Como implementar captadores HP Boost e aprimorar a interface do usuário: Conclua nosso sistema de atualização criando uma coleta
que
nos permitirá pegar e aplicar
imediatamente um
desses itens, como
nosso item HP Boost Então, vamos querer pesquisar as picapes em
nosso projeto Então, temos nossos captadores de objetos. Vamos criar um captador HP Boost. Comece duplicando a cena D de coleta de
XP. Então, vou clicar com o botão direito do mouse
e duplicar isso e , em seguida, este será o captador
HP Boost, sublinhado dois D, claro, e clique duas vezes nele Ok, então a primeira coisa que
quero fazer aqui é mudar o sprite para que seja o mesmo do meu item Então, vou clicar em
Animated Sprite TwoD. Vamos ver a animação aqui
e criar um novo recurso de
quadros Sprite para que
possamos definir um ícone diferente Vou adicionar molduras de
uma planilha de sprites. Vamos entrar na arte. Não é uma fanta vermelha,
veja ícones de Raven, folha de sprite
completa, 16 por 16, amplie Verifique se, à direita,
você definiu o tamanho para 16
por 16 aqui para que ele
possa dividir a
folha de sprite adequadamente E sim, vamos encontrar
aquela flor que eu estava usando. Então clique nele, adicione a moldura. E bum, aí está o nosso item. Eu posso ver o captador XP, mas na verdade é
apenas um captador que imediatamente
adiciona Então, esse script realmente ignora toda
a necessidade
de ter o item Então, o que estamos
procurando é mais um item que coleta dois D. Então vamos renomear nosso
nó base, item coleta D, e vamos clicar com o botão
direito do mouse,
desanexar o script, clicar com o
botão direito do mouse em anexar um novo script, e isso será uma coleta de sublinhado de
item, dois D, isso vai se
estender da coleta até D. Nós criamos isso, damos
o nome de classe item coleta dois D. Então isso vai aplicar um item que coleta dois D. Então,
vamos renomear nosso
nó base, item coleta D,
e vamos clicar com o botão
direito do mouse,
desanexar o script, clicar com o
botão direito do mouse em anexar um novo script,
e isso será uma coleta de sublinhado de
item,
dois D, isso vai se
estender da coleta até D.
Nós criamos isso, damos
o nome de classe item coleta dois D. Então isso vai aplicar o item coletado até o
objeto que o pegou. Então, na
interface do nível,
aplicamos imediatamente o item ao nosso jogador. Aqui está um pouco diferente. Temos que pegar o item
no mapa do jogo primeiro, como pegamos o EXB
e depois ele
aplicará o efeito do item
diretamente ao jogador Se adicionarmos itens em um inventário, esse método de aplicação
seria mais como adicionar um item
à
matriz de inventário e partir daí, mas nosso jogo não
precisa de inventários, então estamos basicamente pulando Mas nosso jogo realmente não precisa inventários além do carregamento de
armas,
que funciona de forma um Então, nós realmente não precisamos
entrar nisso para este projeto. Portanto, nosso item Pickup
two D, é claro, queremos exportar um
item do tipo item. Está bem? Então salve isso e, em seguida, podemos clicar aqui e vamos
atribuir, se
quisermos, podemos atribuir o item padrão. Mas talvez eu deixe
isso em branco. Deixe-me dar uma
olhada no script D básico de pickup two,
clique com o botão direito nele Portanto, precisamos implementar
a função take. Então, vamos copiar isso no item pick up two D.
Vou colar isso Vamos implementá-lo em um segundo. Eu também vou fazer a função underscore ready, retorna void E vamos afirmar
que o item não é nulo. Cada item retirado deve ter
um item atribuído para retirada. Na verdade, acho que assert é
um pouco forte demais aqui. Eu provavelmente escolheria
mais, como push error. Assim, podemos ver o que está
errado no console, mas isso não interromperá o fluxo do jogo porque, quando
instanciamos a coleta do item, provavelmente
ela será uma queda, e não
queremos necessariamente que isso
interrompa completamente o fluxo de
nossos testes de jogo Então, acho que o erro push é um
pouco mais apropriado aqui. Então, vamos
remover o sublinhado
do alvo P. Então, primeiro, vou dizer que ponto
do item pode ser aplicado ao alvo P, depois vou
aplicá-lo ao alvo P. Portanto, o item não tente
se aplicar ao pTarget. E se isso acontecer, eu o removerei
do local da cena. Agora, talvez fosse melhor
se a função T também tivesse um booleano para retornar false Então, aqui, a natureza
de mudar isso para um booleano significa que
teria que
voltar para a classe base
e mudar isso E então, qualquer classe que também substitua a função T, teria que
alterá-la Então, essa é uma das
falhas de depender muito da herança
para suas classes, em vez de usar uma abordagem de
composição, como você vê no
inspetor agora, a composição seria mais
como se você tivesse vários pequenos scripts
diferentes,
cada um pequenos scripts
diferentes com seu próprio
propósito, em vez de ter
um script básico estendendo vários Então, por exemplo, o jogador pode
ter um personagem estendido
e, em seguida, pode
haver outra classe acima do jogador, como
Spearman ou dragoon, que adiciona mais Mas se
você tiver muitos scripts
dependendo
diretamente uns dos outros,
uma pequena mudança, como apenas
mudar isso para um booleano, pode significar que você precise atualizá-lo em vários lugares. Então, apenas
algo em que pensar. Na verdade, não é tão
problemático aqui. Ok, então o que
vamos fazer com essa coleta de itens é
colocá-la no mapa do jogo agora Então, HP Boost Pickup. Nós temos isso. Salvamos
isso no projeto. Oh, realmente, o que
eu acho que eu quero fazer disso é
fazer disso uma
cena base, então eu vou renomeá-la como item de coleta dois D. Agora vamos
procurar captadores Então, vou
clicar com o botão direito aqui e
vou fazer uma nova cena
herdada E então, nessa
cena herdada, eu posso atribuir o item. Então, vou carregar rapidamente
nosso item HP Boost e depois salvá-lo novamente na coleta de itens como
coleta HP Boost Dois D. E então essa é a cena que
colocamos no mundo do jogo. De certa forma, criar
uma cena herdada como essa é muito semelhante a estender um script
e colocar toda a base em seu novo objeto Mas em certas
circunstâncias como essa, em que estamos apenas mudando o tipo de item
que a configuração da cena tem:
o captador de aumento de HP, com o item de aumento de HP,
mas, por outro lado,
sendo apenas um
item normal , coleta dois D.
Acho que em casos como
esse, isso realmente faz muito sentido Então, queremos colocar nosso item
no mundo do jogo agora. Vou pesquisar
o World Dot TCN. Ok, vou ampliar aqui. Temos um jogador lá, então
vou procurar o captador HP Boost e tentar arrastá-lo para o mundo
do jogo Eu poderia simplesmente colocá-lo lá, mas vamos colocá-lo
primeiro nos captadores para que ele tenha o pai W
certo para movê-lo Vamos colocá-lo
ali e talvez um segundo aqui só para ter certeza de que podemos fazer isso duas vezes. Vamos apertar o play e depois
vamos pegar nossa picape. Então eu vou andar até
aqui, e bum, nós temos 150 HP. Aqui podemos escolher se
queremos lança ou foice. Interessante, não está oferecendo a opção para a terceira picape. Talvez eu precise ser adicionado. E então eu vou aqui
e obtenho nosso próximo aumento de HP. Portanto, existe nosso item permanente de aumento de
Sp, que funciona de forma um pouco
diferente da nossa EXP, que apenas
modifica diretamente Então, vamos verificar a seleção de subida de
nível e vou me certificar de que
o item ainda está lá. De alguma forma, tudo começou, então vou
carregar rapidamente o valor de um do
item HP Boost , adicionado. Então, agora vamos tocar em
play mais uma vez. Só vou me certificar de
que está funcionando novamente. Obtenha o aumento de HP ao subir
de nível, selecione-o. O HP sobe, selecionamos
aqui e aqui, então obtemos três aumentos de HP Isso está funcionando bem. A última coisa que
quero ajustar, e essa é rápida, é que para nossas seleções de caixas de recompensa, elas não diminuem
para o mesmo tamanho Quando um deles tem
uma descrição mais longa. Então, eu quero entrar na cena de seleção de
recompensas. Clique na raiz
e deixe-me ver aqui. Uma delas precisa
se expandir até o fim. Então, na verdade, a maneira mais rápida de depurar isso seria clicar em play E enquanto o jogo estiver rodando, vou até aqui
e vamos testar, alterar o tamanho aqui. E então vou voltar
e ver se está atualizado. Ok, então nossa área de aumento de HP,
deixe-me verificar a raiz. Isso está configurado para preencher e expandir. Talvez seja a descrição
que precisa ser feita e expandida. Então, podemos ver que a raiz aqui já
expandiu e preencheu o conjunto. Então, vou verificar
o contêiner de margem e ter certeza de que
também é assim. Então, faremos o dimensionamento do
contêiner do layout. Preencher. Ok, então outra
coisa que eu poderia ver na visão
remota para ver as notas que estão realmente em
execução no jogo. E vamos expandir a camada mundial do
Canvas até a interface do usuário. Temos o nível de seleção. Temos nosso
contêiner de painel embaixo dele, o contêiner de margem,
o contêiner de caixa V e o contêiner de caixa de recompensas
e nossas três seleções Então, por que esses
tamanhos são diferentes? Então, podemos ver, se
olharmos aqui à direita ,
que os tamanhos do
Y são todos iguais. Isso é o que
esperaríamos ao analisar isso. Eles estão todos esticados
até o fim. Então, vamos encontrar o nível
em que eles não estão. O menor
é o terceiro. Então, deixe-me expandir isso. Clique em Margin Container. Podemos ver o contêiner de margem. É o
tamanho máximo de 20 pixels, então não é isso. Vamos até o contêiner VBox. O contêiner VBox é 214. Isso também é o que
esperaríamos porque o contêiner de margem
tem uma margem. Então eu acho que na verdade é
essa caixa de descrição. Você pode clicar nos
nós e realmente ver uma caixa quando ela estiver selecionada
aqui. Isso é meio legal. Acho que isso pode
realmente ser novo. Então, nós só queremos que
a descrição empurre
tudo para baixo. Ok, então sabemos o que
estamos tentando expandir. Então, na visualização local agora
aqui no canto superior esquerdo, vamos clicar na descrição.
Ah, e lá vamos nós. Lá vamos nós. Então, aqui embaixo,
no tamanho do contêiner, está programado para começar a encolher Eu quero que isso realmente
seja preenchido e expandido. Agora, se eu
voltar para o jogo, ele vai
até o final. Ok, então você pode
ver isso, certo? Esses três estão caindo. Também gostaria que os
tamanhos dos ícones fossem iguais. Então, talvez precisemos definir um
tamanho absoluto específico para os ícones. Acho que talvez o ícone da lança tenha
sido configurado usando um maior, mas quero ter certeza de que todos
tenham o tamanho certo Então, se clicarmos no ícone Rec aqui, vamos tentar alterar o tamanho do keep para ignorar o
tamanho E acho que isso os
torna iguais agora. Sim, tudo bem. Parece
estar alinhado. Se você tiver outros problemas, esse seria um tipo
de
processo de depuração que você pode usar para corrigir sua interface
de usuário enquanto
realmente executa o jogo Portanto, é muito útil
porque você pode realmente ver como ele
será
atualizado imediatamente . Você pode alterar seu controle dentro do
Gado e da cena local, e ele será atualizado imediatamente
na visão remota. Então, essa é, na verdade, uma
das coisas mais legais sobre Gudo Ok, então com isso, acho que
nossos captadores de sistema de atualização, tudo o que precisamos,
nesse sentido está funcionando muito bem agora Então, essa é realmente a maior
parte do curso até agora. Vamos fazer algumas coisas
refinadas,
como salvar e carregar
um sistema de pontuação, como quantos inimigos
matamos entre as sessões de jogo, tela de
fim de jogo
para ver quando realmente perdemos Então, podemos ir ao
nosso menu principal e reiniciar o jogo,
esse tipo de coisa. Mas a jogabilidade principal está
praticamente lá agora. Então, esse será
o fim deste vídeo
e, em seguida,
entraremos na
fase de
encerramento e polimento do curso
55. P54 Criando um captador de poção de saúde para soltas inimigas: Quero adicionar mais um vídeo
sobre como fazer a coleta de itens do
seu jogo no Então eu criei a picape
para o item de aumento de HP, mas quero criar um item que seja
derrubado pelos inimigos Isso será apenas uma poção de saúde
simples. Então, vou pesquisar nosso item
HP boost no projeto
e duplicar
o captador HP Boost Então, clique com o botão direito e desça para duplicar e vamos
chamá-la de Poção da Saúde TCN de dois pontos D. Agora queremos
abrir essa cena, Health Potion tod dot Então, nosso item aqui se
chamará Health Potion two D, apenas para indicar que está no mundo
do jogo Two D. Para o
item HP Broca à direita, vamos clicar no menu suspenso
e torná-lo exclusivo Então, estamos basicamente pegando a base e criando
uma cópia exclusiva dela, e agora vou clicar com o botão direito do mouse aqui e salvá-la como
uma poção de saúde Então, clique com o botão direito em Salvar como
e, em seguida, coloque-o no
projeto e nos itens, e eu farei a poção de saúde Sublinhe o item TRS. Vamos alterar as mudanças nas estatísticas para aumentar apenas o HP em 25 e remover o HP
máximo desse Agora, para nosso nome de exibição, direi Poção de saúde E para a descrição, direi que restaura 25 HP, ponto final E então, para o
ícone, vamos selecionar outro ícone da nossa região
e encontrar uma poção de saúde Tenho certeza de que há
alguns deles aqui. Então, sim, mais perto do topo, temos mais do que alguns. Realmente, faça sua escolha aqui. Eu vou escolher o de aparência
típica. E vamos selecionar isso. E então também precisamos
pegar o mesmo ícone para o Sprite
two animado D. Então clique lá, vá para a animação, faça novos quadros
de Sprite e selecione selecionar dos quadros Ícones de arte,
folha de sprite completa de 16 por 16, ampliam o
tamanho do conjunto superior para 16 por 16 Em seguida, controle o zoom do
meio do mouse até a parte superior e pegue
a mesma poção de saúde, que está aqui Só deve ser selecionado um. Clique em adicionar. Ok, e aí está
nossa poção de saúde Então, isso já deve
ser capaz de funcionar. Deixe-me jogá-lo no mundo do
jogo como uma cópia. Então, temos nossa
poção de saúde dois D.
Vou colocá-la aqui
por enquanto, e então podemos
usar a poção de saúde Então, na verdade, a
saúde básica começa em 50. Então, se eu for até aqui,
você pode ver que 50 vai para 75 de 100.
Então isso está funcionando. Ok, então precisamos
entrar na cena do esqueleto e modificar
nosso componente de gotas, mas na verdade nunca configuramos uma gota para o esqueleto.
Então, vamos para Oc. Vou apenas
selecioná-lo aqui e, no Controle C, copiá-lo para o esqueleto Em seguida, no canto superior direito, temos nossas definições de queda, que já farão com que
a EXP caia com um peso de 1,0 Então, queremos adicionar a
habilidade de, às vezes, soltar uma poção de HP em vez da EXP Vou adicionar um elemento e clicar em
uma nova definição de descarte. Então, apenas para fins de teste, darei a ele cinco gotas de peso, que significa que 86%
das vezes ele perderá uma poção de saúde,
não uma EXP, só para que você
possa vê-la E então vamos carregar rapidamente nossa poção de
saúde 2 D. Ok,
então, para
que nossos colírios realmente funcionem, também
precisamos adicioná-los como uma
chamada em nossa animação de morte Então, vamos clicar no reprodutor de
animação, ir até Death e
fazer uma chamada sobre drops aqui. Então, no início, vamos adicionar
um método de chamada nas quedas. E vamos clicar com o botão
direito do mouse em inserir uma tecla para soltar uma vez. Isso é bom. outro erro que eu cometi
na retirada do item Quando enviamos o erro
para o item não é nulo. Na verdade, isso deve ser pressionado se
for nulo, porque estamos
tentando verificar se realmente nos
lembramos de definir um item de exportação na retirada
do item Essa foi uma simples reversão
lógica. Ok, agora vamos clicar em
Play e vamos tentar
derrotar um esqueleto Vou apenas coletar alguns itens
em XP aqui, pegue o site. E vamos esperar que
um esqueleto apareça. Enquanto isso, podemos ver que os orbes ainda estão
perdendo XP Sempre, essa é a
única queda possível, e aí temos um esqueleto Então, se derrotarmos esse cara, cerca de 86% das vezes, ele deve soltar uma poção de saúde Então, esse tempo não aconteceu.
Teremos que derrotar mais alguns. E vamos ver. Recebemos
a poção de saúde para desovar Sim, lá vamos nós. Poção de saúde Então, na verdade, vimos que
os dois podem desovar. Outra poção de saúde veio desse esqueleto, outra poção de
saúde Então você pode ver que
a ponderação
definitivamente está funcionando
na grande maioria
das vezes em que estamos recebendo a poção de
saúde
em vez da Então, agora que
sabemos que está funcionando, podemos simplesmente ir até o esqueleto Vamos até o Drops. Vamos pegar a definição de queda da
poção e torná-la 0,1 Então isso significa que dez em cada 11 vezes a EXP vai cair, e uma em cada 11 vezes
a poção de saúde vai cair,
e
é assim que
a ponderação funciona Você soma todas as possibilidades
mais seus pesos, e suas chances são
o peso daquela específica dividido pelo peso total de
todas elas juntas Ok, e é
basicamente assim que você adiciona uma poção de saúde
ao jogo Então você pode ver que, uma vez que
temos nosso item de estatística, nossos captadores que nos
fornecem um item de estatística, e podemos simplesmente aplicá-los
ao jogador e definir como um nome de string a estatística
que estamos afetando,
fica muito fácil modificar
muitas
coisas diferentes em fica muito fácil modificar muitas
coisas diferentes
56. Parte 55 Implementando o tremor da câmera para efeitos de ataque e morte do jogador: Agora estamos passando para a parte
polida do curso, que encerrará as
coisas adicionando algumas
boas metades Vamos começar
com um tremor de câmera ao
apertar para que nosso jogador torne o jogo um
pouco mais intenso. E também faremos
coisas como adicionar uma tela de fim de jogo e a
capacidade de monitorar a pontuação mais alta. Então, vamos começar
com a vibração da câmera. Vamos para o mundo. E no mundo, temos
uma câmera duas D aqui. Então, poderíamos simplesmente
anexar um script
diretamente na câmera dois D. Então
eu vou clicar aqui, anexar um script
e, digamos, sacudir câmera dois D. Sublinhado
dois D, eu diria E vamos criar e
colocar isso,
eu suponho, na pasta UI. Então abra isso e crie. Vou dar a ela o nome de
classe shake Camera two D. E vamos
trabalhar na configuração disso. Então, primeiro, precisamos de uma
referência ao nosso jogador, como muitos outros scripts, para que,
quando o jogador sofrer dano, possamos acionar o
efeito de tremor. Então, vamos exportar o
contexto var do contexto do jogador. Então, assim como antes
com outros elementos da interface do usuário, temos acesso às estatísticas
por meio do contexto. E então vamos adicionar
algumas variáveis para controlar nossa força de vibração. Então, primeiro, exporte var Max shake strength,
que é um float, e eu vou defini-lo como 10.0 por padrão Também podemos ter
uma duração de shake. Então, exporte var shake duration, que é uma flutuação,
e definiremos isso
como 0,3 segundos por padrão E então eu quero um conjunto
separado de variáveis para quando
o personagem morrer. Portanto, essa deve ser uma sacudida
extra forte para causar o impacto de
: Oh, você perdeu seu jogador,
você perdeu o jogo. Então, vamos fazer Export Var
death shake strength, e isso será um
float up padrão para 20,0 E então temos em export
Var a duração do death shake, que vou definir como uma flutuação
de 0,6 segundos por padrão Então, quando nosso script começar, quero obter as
estatísticas do jogador. Então, eu vou dizer que
var underscore stats será um
controlador de estatísticas aqui, e então precisamos da função
underscore Então, vamos contextualizar as estatísticas de pontos do
jogador, e vamos definir estatísticas de
sublinhado iguais a essas Vamos afirmar que
isso não é nulo. As estatísticas G não são iguais a nulas. É preciso ter uma referência às estatísticas
do jogador
para sacudir a câmera. Ok, então quando nossa câmera estiver
tremendo por todo o
lado, queremos lembrar sua posição
original para
que, quando terminarmos, possamos retornar a essa posição Vamos ter outra
variável aqui. Este
será um vetor dois D, sublinhado o deslocamento original, que
será um vetor 20 Ok, lembre-se do sinal de
igual aí. Então, estamos inferindo que é um vetor do vetor dois ponto zero, e isso também o torna um
vetor 20 Ok, então nosso
deslocamento original em pronto será igual ao
nosso deslocamento atual Então esse é o deslocamento
da câmera porque nosso script estende
essa câmera diretamente E então precisamos nos conectar ao controlador
de estatísticas
HP alterou o sinal. Então, sublinhe as estatísticas
Hp hanged dot Connect. E vamos conectar
à qual vamos
conectar isso em HP alterado. Então, vamos criar essa
função aqui embaixo, sublinhado na HP foi alterado, e ela
terá os dados estatísticos Então, dados P e esses são dados
alterados por estatísticas. Desta vez, quando tivermos
nossa função de retorno de chamada, vou
usar os dados P diretamente, porque eles são
muito úteis aqui para determinar se estamos
fazendo um shake normal ou um death shake Então, se a mudança de HP
no evento for maior
ou igual a zero, só
queremos voltar
porque não estamos tremendo com a cura ou porque o
HP não muda Então, agora queremos verificar se o valor do ponto u do evento
é maior que Zarel Então, o personagem ainda
está vivo, essencialmente? Então, se for esse o
caso, usaremos os valores normais de vibração. Caso contrário,
usaremos o valor do death shake. Portanto, a
força do tremor do sublinhado será igual à nossa força
máxima de vibração
e, em seguida, o tempo
do tremor do sublinhado será igual
à nossa retenção Nossa duração de Shake. Ok, então precisamos dessas variáveis
locais aqui em cima. Então var ressalta que a força de
vibração é uma flutuação e Var ressalta que o tempo de
vibração também é É claro que
o padrão será zero. Ah, e quando eu coloquei o evento aqui, eu realmente quis dizer Pdta Então, pata dot change
e pdata dot neu. Ok, então, caso contrário, há
um outro caso aqui, que é que a
saúde está abaixo zero ou igual ou abaixo de
zero, devo dizer. Nesse caso, vamos definir a força
do tremor
para os valores de morte. Então, a
força do tremor do sublinhado será igual à força do
tremor da morte, e o tempo
do tremor será igual
à duração do tremor da morte Ok, agora, há
outra coisa aqui, que é que,
dependendo da saúde do nosso personagem, podemos querer aumentar
ou diminuir a força. É por isso que eu tinha a força de
vibração MX aqui. No momento, sempre
será o máximo
de 10,0 que eu configurei lá Então, acho que uma boa maneira de
fazer isso seria verificar quanto dano você causou versus qual é o HP máximo
do personagem Então, se um ataque afeta
metade da saúde deles, você quer que seja um tremor de câmera
bem forte. Mas se for apenas um dano
ao longo do tempo, tipo: Ah, ele causa um dano segundo, isso é muito
irrelevante Você pode simplesmente fazer
uma pequena sacudida ou eliminar completamente
a sacudida Então, var, a taxa de dano será igual ao valor absoluto F, do ponto do evento hg. Essa é a quantidade de
saúde que acabamos de mudar, e ela será dividida
pelo máximo de um ponto, oh. Então, durante a edição, notei que a matemática aqui está incorreta. Chamar o máximo
entre um ponto oh e o ponto estatístico MX HP não faz muito
sentido aqui porque na verdade, queremos que a proporção esteja entre
a
mudança e a saúde,
o valor absoluto disso, de
qualquer forma. E o MX HP Então, na verdade, o que queremos fazer
é dizer uma variação percentual. E o que realmente
queremos dizer é o valor absoluto flutuante da mudança de ponto de dados p
dividido pelo ponto estatístico de sublinhado MX Então isso nos dá nossa proporção, que deve ser de 0 a 100 Mas queremos acabar com isso. Então, digamos que a proporção fixa agora. Vou cortar
isso e, digamos fixar F na variação percentual, e vamos
forçá-la entre 0,0 e 1,0 Então, se por algum motivo nosso valor de alteração fosse realmente maior do que nosso MX HP
total, digamos que sofremos 9.000 de dano
e nosso HP máximo fosse 100
, isso
seria na verdade uma mudança percentual de Então, na verdade,
queremos limitar isso a 100%
ou, se estivermos
indo na outra direção, não
pode estar abaixo de 0% de alteração. Portanto, nosso valor total será de 0 a 100, não importa quão grande ou
pequena tenha sido a mudança Multiplique a força máxima de agitação
pela proporção fixada. A última coisa que precisamos
fazer aqui para
garantir que isso não retorne
como zero é pegar o MX HP
e lançá-lo em um flutuador Então, isso é importante
porque, caso contrário, inteiro dividido por um
inteiro simplesmente diminuiria o ponto decimal antes mesmo de convertê-lo em
uma Agora podemos correr
e
garantir que ainda esteja
funcionando conforme o esperado, então vou encontrar um cara para nos atacar. Ok, e ainda temos
aquele tremor de tela, certo? Claro, o da morte
será muito maior. Então, como mudamos a matemática, talvez
você também queira ajustar
a força máxima de vibração e torná-la mais forte,
como 20 ou 30. E lembre-se, isso
sempre será uma porcentagem da força
máxima de agitação. Então, você precisa levar isso
em consideração quando estiver realmente descobrindo o quão forte será
o tremor Então, vamos ver, aos 30, força
máxima é mais ou menos
assim. Talvez um pouco forte. Então, eu poderia até reduzir
isso para 20. Como mais um número final. Ok, agora, finalmente,
nós realmente precisamos do processo para o shake. Então, vamos até o topo aqui. Depois que o sublinhado estiver pronto, direi processo de sublinhado
da função Então, estou apenas preenchendo isso automaticamente. E então vamos dizer que, se o tempo de agitação for
maior que 0,0, então vamos
realmente sacudir a tela. Então, como fazemos isso
é com um pouco de matemática. Então, vamos dizer que o tempo de underscore
shake underscore é menos igual ao Delta Então, removemos o tempo do tempo que estamos passando aqui, e então eu vou
pegar o valor da vibração X e
da vibração Y e aplicar
esse deslocamento Portanto, var shake X
será igual à faixa F aleatória de menos 1,0 a 1,0
vezes a força de agitação. Então, essencialmente, estamos
obtendo uma direção aleatória multiplicada pela nossa força de vibração
atual E então var shake Y, é
claro, você pode
imaginar que é o mesmo. Será igual ao intervalo
aleatório de sublinhado F, 1,0 a 1,0 vezes
sublinha a força de agitação Pegamos os dois e os
aplicamos ao deslocamento da câmera Então, o deslocamento será igual ao deslocamento normal
mais
o vetor dois, e isso será
agitação X e agitação Y. Então, basicamente, em
cada atualização de quadro, a câmera vai tremer para uma nova posição aleatória ligeiramente diferente
do deslocamento original, e fará isso até que
o tempo de vibração Portanto, se o tempo de vibração
for zero ou menor, digamos outra coisa,
queremos retornar o
deslocamento da câmera ao original Portanto, o deslocamento será
igual ao deslocamento original. Ok, e se eu entendi direito, esse é basicamente o
nosso roteiro. A última coisa que
precisaremos fazer é atribuir o contexto do jogador
e o inspetor Então, rapidamente aqui, menu suspenso, carregamento
rápido, contexto do player. E vamos rodar o jogo
e deixar nosso jogador ser atingido e ver se
funciona conforme o esperado. Ok, então aqui está um orc, e nossa câmera treme
toda vez que somos atingidos E aí está nossa câmera
tremer on death, que é muito mais forte,
como você pode ver. Então, essencialmente, esse é
todo o nosso efeito de vibração da câmera. Obviamente,
seria um bom momento para inserir a tela
do GameOver para que possamos retornar ao menu Iniciar do jogo, que também precisamos criar
57. Ladrilho 56 Criando uma tela de jogo com a navegação do menu principal: Uma das últimas coisas que
precisamos adicionar é uma tela de GameOver e
uma tela de menu mínimo Então, o GameOver, é claro, vai aparecer quando nosso
personagem for derrotado Portanto, precisaremos acessar
o contexto do jogador novamente para que possamos verificar
se I live é falso. Então, primeiro, vou abrir o sistema de arquivos
e acessar a interface do usuário, e encontraremos nossa interface de usuário
principal, o Canvas que facilitará um
pouco o trabalho
, para que possamos ver onde vamos
colocar o jogo na tela. Então, por enquanto,
acho que vou pegar
a seleção de subir de nível
e esconder isso. Isso facilitará o trabalho. E vamos usar a interface do usuário. Vou clicar com o
botão direito do mouse em Adicionar um nó secundário. Então, queremos um novo controle esse controle será centralizado Então, no layout, vamos fazer âncoras de posição do
layout e centralizar Agora, clique também para ir para o mouse
e gire o filtro para Ignorar. E vamos clicar com o botão direito do mouse e adicionar um contêiner de painel a
esse nó de controle. Então, recipiente de painel.
Esse será o pano de fundo. Vamos pegar o
recipiente do painel e esticá-lo. Então, aumente o zoom, certifique-se
de que o contêiner do painel esteja
selecionado aqui e vamos expandi-lo. Portanto, queremos que nosso contêiner de painéis esteja centrado em nosso controle principal Então, vamos ao layout agora e
fazer o centro das âncoras do layout. Isso deve colocar as
âncoras dos pais aqui no
centro, então isso é bom Isso o tornará centralizado
na tela. Vamos renomear o
nó principal para a tela do GameOver. Além disso, clique com o botão
direito do mouse e salve-o como uma ramificação na
pasta UI, na tela GameOver Então, agora podemos simplesmente entrar
nisso e editar isso puramente. Então, em nossa tela do GameOver, é claro que
precisaremos de algo como um rótulo de rich text como título Vamos clicar com o botão direito do mouse em Adicionar
um rótulo de rich text. E eu posso simplesmente dizer
GameOver dentro de você. Provavelmente também queremos
tornar o
tema baseado em raízes como nosso tema principal do
jogo. Então, carregue rapidamente o tema aqui, tema do
jogo que
nos dará a fonte de arte Pix Agora também podemos usar
o rótulo Rich text
e, digamos, conteúdo adequado. Também queremos
dizer texto centralizado, também parece ser
muito grande Acho que isso não será um problema, depois de adicionarmos o
contêiner VBox, clique com o botão
direito do mouse no contêiner do
painel e
adicione um contêiner VBox Mova o
rótulo de rich text abaixo dele. Ok, isso corrige o tamanho já
que agora é
controlado pelo contêiner Vamos clicar com o botão direito do mouse
no VBox e adicionar talvez um rato de textura e, em seguida, obteremos um ícone
triste E então teremos
um ícone do GameOver. Se usarmos textura e fizermos textura de
atlas, nós a expandimos. E então, para o atlas, vamos carregar rapidamente nossos ícones Poderíamos usar o 64 64 aqui se quisermos
manter isso no projeto. Editar região. Ok,
e então precisamos diminuir o
zoom e
selecionar algo que
seria bom para,
tipo, um fim de jogo. Portanto, há muitas
opções para escolher. Acho
que esse crânio parece estar dormindo Não é muito escuro, não
é muito fofo, então acho que pode funcionar. Deixe-me tirar isso do caminho para que eu possa ver o editor da região. Talvez eu precise realmente
alterar o tamanho aqui. Vou tentar um passo de quatro
no X e quatro no Y. Dessa forma, posso esticar
isso para a direita, e então a esquerda e a direita
se combinarão Também vou puxar um pouco a
parte inferior para cima. Ok, então com a etapa 44, funcionou um pouco bem,
então eu posso chegar mais perto aqui. Ampliamos nossa tela do
GameOver. Acho que vou
querer um clipe de filtro. Acho que também para
o modo de alongamento, precisamos manter o aspecto centrado, e isso parece bom para mim Então, também
adicionaremos uma caixa de descrição. Então, clique com o botão direito do mouse no VBox, adicione outro rótulo de rich text e podemos dizer que
você foi derrotado Tentamos tentar novamente. Claro, vamos continuar com
isso, conteúdo adequado. Sim. E então só
precisamos de um botão aqui na parte inferior para
ir ao menu principal. Então, clique em VBox, adicione um botão de nó filho Este botão exibirá menu principal. Vou anexar um script a ele. Então, esse será um novo botão. Ok, a seguir, vamos
pegar esse botão aqui e eu vou renomeá-lo botão de mudança de
cena porque vamos voltar
ao menu principal Vamos anexar um script a ele. Então, este será o ponto GD do
botão de mudança de cena. Crie isso. E queremos adicionar
Export var ao mesmo caminho. Então, podemos realmente transformar
isso em um arquivo de exportação, e isso seria aspas
star dot TSCN Ok,
então nosso caminho de cena é
uma string e, quando
estiver pronto, nos conectaremos ao
sinal pressionado, então pressionar o ponto de conexão
no botão pressionado
e, em seguida, o
sublinhado da função no botão pressionado simplesmente
mudará Então, vamos fazer a
mudança de ponto do Gtree de cena para arquivo, e colocamos o caminho da cena, e então isso
mudará nossa
cena atual para a cena do menu principal Como uma verificação
importante, provavelmente ajudaria se disséssemos que o caminho da cena está vazio É igual a false e
diz que deve haver um caminho de visão para o qual mudar
quando esse botão é pressionado OK. Então, mais uma coisa que eu provavelmente quero é um contêiner
de margem. Vamos clicar com o botão direito
na tela do GameOver e adicionar um contêiner de margem Vou
colocá-lo diretamente sob contêiner
do painel e, em
seguida, o VBox embaixo Está bem? Agora
podemos definir valores no contêiner de margem
e
nas substituições do tema, algo como quatro
para todos os lados, e isso fará com que
pareça um pouco melhor, fornecendo um pouco de
espaço para o texto. E em nossa tela de fim de jogo, precisamos ter certeza de
que isso abrirá a interface do usuário quando o jogo for perdido. Então, vou anexar
um novo script aqui. Interface de jogo na tela. Crie isso. Talvez queira um nome de classe aqui,
game over screen. E vamos obter uma referência ao jogador
por meio do contexto. Portanto, em Exportar vara,
o contexto é do tipo player context. Diremos que a função underscore
está pronta e, quando estiver pronta, contextualizaremos as estatísticas de pontos
do player e obteremos a alteração Alive. Vamos nos conectar a isso e
dizer que o jogador Alive mudou. Portanto, alteramos nossa
função de sublinhado no player Alive. Não me lembro se isso
tinha algum parâmetro, então clicarei no símbolo Alive changed e verificaremos se
ele tem o Boole ativo, então
volte ao script do game over, e precisamos disso como
parâmetro aqui Então P Alive é um booleano. Isso retornará vazio. E se P Live for igual a false, mostraremos todo o menu do jogo aqui. Ok, agora, nosso estilo de
botão de mudança de cena não vai funcionar porque
não temos uma cena no menu principal. Então, vamos criar um espaço reservado. Adicione uma nova interface de usuário de cena e esse será o menu principal. Vou salvá-lo no projeto. Então, vamos fazer
isso na raiz do menu principal
do projeto e salvá-lo. E então, na tela de fim de
jogo, vamos atribuir esse menu principal como um caminho para o caminho da cena e o
botão de mudança de cena como este. Você pode simplesmente arrastar e soltar. Essa é a maneira mais fácil de fazer isso. Ok, também, antes que eu esqueça, vá para a tela Game Over e
atribua o contexto do jogador. Então, basta carregar rapidamente esse recurso de contexto
do player. Agora queremos ir para o mundo. Podemos ver que a interface do game
over está aí. Então, vamos ver se podemos
testá-lo bem rápido. E certifique-se de que podemos acessar
o menu principal por meio dele. Então eu cliquei em Play. E
está aí mesmo. Vou acessar o
menu principal, e isso nos dá uma tela em branco
porque,
na verdade, não adicionamos nada
a essa cena. É apenas um
elemento de interface de usuário em branco, essencialmente. Então, isso está realmente funcionando. Acho que a outra
coisa que queremos fazer é estar pronto para o
game over na tela. Vamos apenas garantir que ele se esconda. Então, diremos que se esconda está pronto. Em nosso UI Canvas de jogabilidade, talvez também
queiramos escondê-lo lá, mas não precisamos necessariamente
dizer se isso ajuda. Mas vou deixá-lo visível por padrão para que possamos
testar a altura. Então está escondido, e agora
só precisamos ser derrotados, e ele deve aparecer
se estiver funcionando corretamente. Então, dois acertos, três acertos,
quatro acertos, cinco acertos. Aí está nosso pop-up do game over, no menu
principal, e o
fluxo está funcionando. A última coisa que eu acho que preciso
aqui é apenas redimensionar isso. Então, vou colocar a tela de
game over dentro do nosso
jogo UI Canvas, e vamos pegar a forma do layout e elevar a escala para três. Isso deve ser grande o suficiente. Para que eu possa testá-lo mais uma
vez rapidamente no jogo. Ok, então um golpe, dois acertos, três, quatro, cinco
acertos, fim de jogo. E temos o botão do menu principal. E esse é o fluxo básico.
58. Ladrilho 57 Rastreamento de alta pontuação e exibição de UI para derrotas de inimigos e tempo de sobrevivência: Uma coisa boa que falta em nosso jogo é uma pontuação alta, poder rastrear quantos inimigos
derrotamos em um jogo e depois lembrar essa
pontuação em um arquivo seguro
para obter uma folha de pontuação máxima que
podemos ver na tela do menu
principal Então, para implementar isso,
precisamos primeiro começar
contando quantos inimigos
derrotamos sempre que um
inimigo é derrotado. Então,
precisaremos de uma combinação de reportar o estado de morte
a um gerenciador de estatísticas ou de
alta pontuação
e, em seguida, pegar esse
valor após o
término do jogo e salvá-lo para
atualizar o arquivo Safe. Então, no início do curso, adicionamos um gerenciador de jogo Singleton e nunca fizemos
muita coisa com Na verdade, a forma como implementei o game over screen
acabou sendo apenas usando o
contexto do jogador, em vez de
ter que reportar diretamente ao gerente do
jogo. Então, vamos realmente
dar ao gerente
de jogo um propósito para que
possamos usá-lo no curso. Então, teremos um
objeto dentro de um gerenciador de jogo para as estatísticas e depois o
rastrearemos durante o jogo. E então definimos isso
sempre que começamos um novo. Então, nos sistemas,
vou
clicar com o botão direito do mouse e fazer um novo script. Digamos que sejam estatísticas do jogo, que serão
contadas por árbitros porque na verdade, vamos
torná-las filhas do
gerente de jogo Singleton Então, abra as estatísticas do jogo
e, em seguida, digamos
que, se
nossos inimigos forem derrotados, o
que será um número inteiro padronizado como zero, precisaremos de um
nome de classe aqui no topo Então, estatísticas do jogo. E
então, no gerenciador de jogos, terei uma função start, que retornará nula, que
pegará nossas estatísticas de jogo e as redefinirá ou
configurará para um novo objeto Então, para estatísticas de estatísticas do jogo. Serão estatísticas
iguais às do GameStats dot nu. Vamos continuar com isso por enquanto. E quando o mundo estiver cheio, vou querer pegar as estatísticas do
jogo e redefini-las. Então, vamos anexar um
script ao mundo. Tudo bem, clique aqui,
anexe um script. Vamos colocá-lo na cena base. Então crie isso e eu
direi que a função está pronta, e diremos
gerenciador de jogos dot SAT. Ok, então tudo o que
precisarmos
que nosso jogo carregue no início, teremos
isso lá. Então, enquanto estivermos usando
o script mundial aqui
, seremos
capazes de gerenciar isso. Talvez também queiramos
dar a isso um nome de classe. Poderia acabar sendo
um roteiro bem importante se continuássemos
com a série. Então eu acho que merece
o nome de classe mundial. Então, agora, sempre que
começarmos um novo jogo, ele basicamente redefinirá
as estatísticas. E então talvez denuncie o fim do jogo. Poderíamos considerar
entrar aqui um pouco mais tarde e salvar as
estatísticas de pontuação mais alta. Ok, agora eu quero
modificar nossas estatísticas e quero relatar sempre que
nossas estatísticas forem modificadas. Então, nas estatísticas do jogo, criaremos um sinal para nossos
inimigos derrotados. Então, sinalize que os inimigos
foram derrotados, alterados. Usaremos um valor e um
número inteiro como parâmetro
e seguiremos
um padrão semelhante, e seguiremos
um padrão semelhante sempre
que
atualizarmos o valor, evitaremos
se forem os mesmos valores Se os inimigos derrotados tiverem
o mesmo valor, nós simplesmente retornaremos. Caso contrário, estamos
definindo um novo valor. Então, inimigos derrotados
são iguais a valor, e então dizemos que inimigos derrotados trocaram o ponto m por um novo Ok, então sempre que
atualizamos a propriedade, nós a reportamos com um sinal para que possamos
observar a propriedade. E acho que isso é
tudo o que precisamos para configurar uma interface de usuário. Ok, agora que isso está aí, sempre que tivermos o estado da
Morte ligado, digamos, nosso orc ou ao nosso esqueleto,
vamos entrar no script do estado da
morte Então, em nosso estado de morte, acho
que Enter faz mais sentido
dizer estatísticas de pontos do gerente de jogo, EMS derrotado mais é igual a um, e é assim que
atualizaremos esse contador acompanhando todos os
inimigos que derrotamos Agora, a última coisa que precisamos é uma pequena interface de usuário para mostrar quantos inimigos
derrotamos Portanto, dentro de nossa tela de interface de usuário de
jogabilidade, vamos adicionar outra, vamos
transformá-la em um contêiner de painel. Adicione o contêiner do painel secundário aqui e colocaremos o layout como âncoras no canto superior direito Vou esticar
um pouco assim. Compense isso. Deixe-me chamar isso
de visualização de estatísticas do jogo. Em seguida, clique com o botão direito do mouse em salvar uma ramificação como cena
e a interface do usuário
, é claro , entre na cena, e vamos clicar com o botão direito do mouse nela
e criar um script. Então, essa será a visão de Gamestts. Posso dar a ela o
nome da classe, a visão dos jogadores. E na visualização em dois D
em que a editamos, vamos adicionar um rótulo para nossos inimigos
reais derrotados. Então, clique com o botão direito do mouse em Adicionar nó filho. Começaremos com um
contêiner HBox, eu acho, e depois clicaremos com o botão direito do mouse em Achil
Node, rótulo Rich Text Vou apenas duplicar isso. Então, o primeiro será
para mostrar o texto
e, em seguida, o segundo
será o número. Então esse será o rótulo estatístico. E então a parte inferior
será a etiqueta do valor. OK. Portanto, o
rótulo do SAT mostrará
consistentemente
inimigos derrotados, dois pontos, vamos nos adequar ao conteúdo E então, na segunda,
colocarei colchetes, zero. Então, isso é apenas um espaço reservado. E acho que precisamos que eles se estendam para que
possamos realmente vê-los. Então, vamos tentar fazer o layout, dimensionamento do
contêiner e
expandir na horizontal Sim. E então etiqueta de quantidade, mesma coisa. Vá para o layout. Dimensionamento do contêiner, expanda na, expanda na horizontal Ok, então agora isso é
mais ou menos o que temos agora. Ok, agora pegue as estatísticas do jogo pressione Q para entrar no modo de seleção, e vamos reduzi-las
ao que precisamos Um contêiner de margem
também seria bom aqui, então vou clicar com o botão direito do mouse e adicionar
um contêiner de margem secundária, e vamos colocar o contêiner HBox embaixo dele no contêiner de
margem O tema substitui
constantes e talvez quatro pixels em cada lado.
Isso parece muito melhor. Acho que isso pode ser funcional
o suficiente por enquanto. Vou voltar ao jogo UI Canvas
e me certificar de que ele esteja novamente no
canto superior direito como uma âncora, no canto superior direito, e depois o desloco pressionando W para
movê-lo Em seguida, basta movê-lo um pouco para fora
da esquina. OK. E então eu preciso, no script
da visualização do GamestTS, eu preciso realmente me conectar ao sinal
nos Então, a função já está sublinhada. Vamos fazer o
gerenciador de jogos: estatísticas de pontos, inimigos derrotados alterados, conecte-se a
inimigos derrotados alterados. Vou pegar esse nome e criar
uma nova função aqui embaixo, função no inimigo
derrotado foi alterada, que
considerará a quantidade P e o valor inteiro retornado nulo, e vamos
atualizar o valor Ok, então, basicamente,
pegamos o novo valor e o colocamos no rótulo. Então, na Export VR. De qualquer forma, pegamos o rótulo de nossos
inimigos derrotados e definimos o texto
igual
a uma sequência da quantidade e pronto. Só precisamos de dois pontos
aqui no final. Talvez, quando estiver pronto, queiramos
afirmar que existe o rótulo de
derrotado do inimigo É necessário definir o rótulo de inimigos derrotados para mostrar a
contagem ou a montaria de inimigos derrotados. Seremos um
pouco mais precisos. Agora, clique na
Visualização de estatísticas do jogo e entre na cena. E dentro daqui, queremos
atribuir esse rótulo de valor. Então clique em atribuir e
escolha a etiqueta do valor. E se eu estiver certo, isso
deve ser tudo aqui. Então, vamos jogar e
tentar. Tudo o que precisamos fazer é derrotar alguns inimigos e vê-los
aparecer no canto superior direito. Então, o problema aqui é que as estatísticas não
são iniciadas em nada, então eu quero
clicar com o botão direito do mouse no símbolo Lou Acho que o problema aqui é que as estatísticas podem não ser definidas
antes de serem executadas na interface do usuário, já que esse é o
topo do mundo, acho que as crianças
estão prontas primeiro Então, a melhor maneira de
fazer isso, eu acho, seria dizer que as estatísticas
são iguais a gamestts dot u. Então, isso sempre será
criado quando o jogo começar E então queremos
chamar stats dot reset. Então, vamos criar uma
nova função para isso. Isso também significa
que não precisamos
reconectar os sinais porque
ainda estamos usando o mesmo objeto Então, na verdade, é uma maneira
melhor de fazer. Vamos entrar nas estatísticas do jogo e
criar nossa função de reinicialização. Então, reinicie a função. Nós apenas
devolvemos tudo aos valores padrão. Então, inimigos derrotados são iguais a zero, e isso deve ser tudo o que
precisamos agora Portanto, agora as estatísticas devem
ser definidas
assim que o jogo começar, antes mesmo de o
mundo ser carregado. E então, a partir daí,
devemos ser capazes de nos
conectar ao sinal. Ok, vamos tentar mais uma vez. Tudo bem, jogue. Ok, temos
uma contagem no canto superior direito. Claro, é
muito pequeno, mas podemos pelo
menos ver isso. Então, vamos derrotar um orc e
garantir que esteja funcionando. E temos um lá para
aparecer se matarmos outro cara. Está bem? Aí temos
três. Então, sim, a contagem está funcionando com certeza. Eu só preciso ampliar a interface do usuário. Então, na jogabilidade Canvas,
vamos fazer isso aqui. Uma
escala de transformação simples de três. Mova isso para
a direita aqui. E agora precisamos realmente cortar muito
desse espaço extra. Isso está ocupando
demais sem motivo. Então, vou precisar de uma
pequena edição lá. Vamos entrar na visão
dos jogadores. Na verdade, vou alterá-la de volta para zero sem os colchetes que, antes de
derrotarmos o primeiro inimigo, ela não tenha
nenhuma exibição instável Ok, agora que o
tamanho é muito grande, acho
que muito disso é só definir
manualmente o tamanho de visualização
dos jogadores Então, vamos reduzir isso aqui
para o que realmente precisamos. Então, podemos torná-los
muito menores. E essa segunda visão
não precisa ser tão
grande quanto a primeira. Portanto, não há
razão para que eles ocupem a mesma
quantidade de espaço. Acho que o que realmente queremos é mais um contêiner de
fluxo. Deixe-me mudar o tipo
de contêiner de caixa H para
um contêiner de fluxo H. Ok, agora vou
até o rótulo do valor e vamos desmarcar expandir aqui E então vamos tentar pegar o tamanho mínimo personalizado
e configurá-lo para,
tipo, 40 pixels,
provavelmente grande o suficiente, para que eu
possa segurar pelo menos
mil dígitos E então o resto
do espaço será ocupado
pelo inimigo derrotado. Também vamos mudar a
visualização na base para o nosso tema padrão do jogo
Quick Load. Sim, ok, isso também vai
ter um grande impacto. Então, agora, se olharmos para isso, eu posso realmente reduzir isso. Eu deveria ter feito isso
no começo, na verdade. Então, algo assim,
esse é o nosso espaço para a etiqueta e o
número ali. Podemos acessar o jogo UI Canvas e reduzir
isso drasticamente Você pode ver que
tudo o que não é aquele pixel do lado direito é consumido pelo rótulo de
texto à esquerda. Portanto, é melhor que esses dois
elementos não estejam tentando
ocupar uma parte igual do tamanho
da visualização, mas um seja
como um tamanho estático e o resto apenas se expanda E então eu vou colocar isso um pouco mais no
canto ali. Vamos clicar em Play. E veja
como isso acontece. Ok, isso é muito melhor, tamanho
mais apropriado. Então, é claro, só
para testar novamente. Vamos derrotar um cara, e isso é atualizado, então
temos nossos inimigos derrotados contando. Então, vamos adicionar mais uma
estatística, que é quanto tempo nosso jogador
sobreviveu no jogo, outra estatística útil
e boa para nossa pontuação mais alta Então, em nossa visão de Gamests, vou duplicar
esse contêiner HBox Agora vamos
precisar de um contêiner VBox para que eles possam se
sobrepor uns aos outros Clique com o botão direito do mouse em Margin
Container e adicione um VBox. Mova essas duas caixas
H para baixo dela, assim, e agora altere o rótulo
estatístico à esquerda
para cólon sobrevivente no tempo E se entrarmos no GameStatsView, será uma
configuração muito semelhante Vamos apenas nos conectar
às estatísticas de quanto tempo vivemos e mostrar que,
na época, a área sobreviveu. Então, vamos clicar com o botão direito do mouse em Estatísticas, procurar o símbolo
e abri-lo. Então, vamos fazer com que o tempo de
variação tenha sobrevivido, que é uma flutuação igual a 0,0 Vamos definir o valor disso. Nós realmente não deveríamos precisar desse
guarda. É só um extra. Então, vou apenas dizer que o tempo
sobrevivido é igual ao valor. E então, é claro, o
tempo sobreviveu, mudou de emissão, o tempo sobreviveu E então teremos esse
sinal aqui no topo. O tempo sobreviveu, mudou. O que
será uma flutuação temporal. Ok, então todo o
motivo de ter esse guarda é que,
se por algum motivo, algo no jogo definiu o valor
como o valor em
que ele já está, tipo, inimigos derrotados era
50, e agora é 50 novamente. Eu acionaria uma atualização
extra da interface do usuário. Mas, honestamente, em primeiro lugar, é improvável
que isso aconteça E em segundo lugar, isso realmente não
deveria dar grande importância a nada. Portanto, é mais do que apenas com base
em detalhes técnicos. Isso só muda se
o valor realmente
mudar, em vez de realmente ser
um problema para o jogo. Então, eu só
queria esclarecer isso. Ok, agora, nosso reset
também precisa levar o tempo sobrevivido e defini-lo 0,0 porque estamos
redefinindo o tempo Ok, então vamos ver o que mais? Em nosso mundo de jogo, acho que queremos
aumentar o tempo Então, quando o mundo estiver funcionando, teremos um processo de
sublinhado de função Vou pegar o
gerenciador de jogos dot stats
dot TV plus é igual ao Mas isso só pode realmente ocorrer
enquanto o jogador estiver vivo. Então, vamos fazer Exportar para o contexto em Exportar
contexto VR, contexto do jogador. Você pode ver onde estamos usando esse recurso de contexto em
todo o jogo em
diferentes lugares. Portanto, ter isso como
um recurso salvo é extremamente útil
para poder espalhar
a referência
para toda a nossa interface de usuário e outros nós que precisam
referenciar o jogador sem ter uma
referência direta à cena do jogador. Então, espero que eu tenha deixado
claro o quanto isso pode ser útil. Portanto, temos o contexto do jogador e só queremos
aumentar o tempo sobrevivência se o jogador estiver vivo. Então, se entrar em contato com
dot player dot stats dot Live
, aumentaremos o tempo Caso contrário,
vamos simplesmente pular isso. E isso deve ser
bom o suficiente. Por enquanto preciso de uma referência
ao novo rótulo de quantidade. Então, diremos que em Export var, Time label é um rótulo de rich text, e essa é a visualização
GameSts, é claro Então, digamos que o gerente de jogo
dot stats dot Time survive
change dot Connect, on
Time survive, changed. E nós só temos outra
ligação aqui embaixo. A função no tempo
sobreviveu alterada, obtém o PT float Vamos retornar vazio
e, em seguida, colocamos o
texto na etiqueta Portanto, o
texto do ponto do rótulo temporal será igual a uma sequência de caracteres do PT, e isso provavelmente é bom o suficiente. Também vou fazer uma declaração
sobre o
cronograma . Verifique se está configurado. É necessário definir o marcador de tempo para
atualizar o tempo sobrevivido. OK. E em nossa visão de jogos, vamos atribuir esse
outro rótulo de valor Talvez queiramos renomear
esses contêineres HBox. Então, o primeiro contêiner foi o contêiner derrotado pelo inimigo. E então o segundo é
o contêiner que sobreviveu ao tempo. Então, apenas esclarecendo
qual é qual. Vamos garantir que esteja
na interface de jogo. Vamos sair para o mundo,
ver se ele ainda está lá. Clique em play para testar e executar e ver como
isso vai ficar. Ah, ok, então eu não defini o contexto do
mundo, é claro. Então, no nodo mundial, temos que carregar rapidamente
o contexto do jogador. Está bem? E agora, se corrermos, o tempo deve ser
capaz de aumentar. E então temos o tempo lá em
cima, no canto superior direito. Agora, isso está funcionando principalmente. Acho que há
alguns problemas aqui. Primeiro, parece que precisamos
expandir isso um
pouco mais verticalmente Oh, bom. Quando o
jogo é positivo, ele também para. Isso é importante. E então, em segundo lugar, não
acho que
precisamos mostrar todos
os milissegundos. Acho que reduzir isso
para uma casa decimal
seria um pouco menos
estressante Você pode ver que a segunda
e a terceira casas decimais estão Você nem consegue
lê-lo. Portanto, não adianta mostrar
essas informações. Ok, então, para alterar nossa função de configuração de
texto, vamos
fazer a cotação por cento um F. Então, isso nos dará o valor flutuante com
uma posição decimal
e, em seguida, forneceremos um símbolo de
porcentagem para
adicionarmos a variável PT para
realmente configurar essa adicionarmos a variável PT para
realmente configurar Ok, e agora podemos
clicar em play e
veremos que a hora
mostra apenas a primeira casa decimal Isso é dez vezes mais
legível e menos perturbador. Grande atualização. Então, acho que está
ótimo para nossas estatísticas de jogo. Acho que a única
coisa que eu poderia mudar é colocar o tempo sobrevivido no topo e o inimigo ser derrotado na parte inferior e clicar em jogar mais
uma vez. Acho que vai
ficar um pouco melhor. O tempo sobreviveu. Acho que quero a mais chamativa
no canto superior direito
e, em seguida, as outras
estatísticas menores mostradas abaixo dela, aquelas que
serão menos atualizadas Aqui está apenas uma pequena
preferência visual. OK. E só para mostrar que ainda
podemos derrotar o orc, e isso impede o funcionamento. Portanto, as estatísticas do jogo são boas
, pelo menos na jogabilidade.
59. L58 Como salvar e carregar partituras altas com JSON: Ok, agora que nossas
estatísticas de jogo estão funcionando, queremos pegar
isso e, em caso de derrota, queremos atualizar
as pontuações mais altas e salvá-las em um arquivo JSON Então, isso seria basicamente o início de um sistema de salvamento de carga. E nesse tipo de
jogo, especificamente, não
existe tanto um
estado de salvamento quanto apenas pontuações altas, mas o processo seria muito semelhante se você
precisasse salvar um arquivo de jogo. Basicamente, você precisa
serializar os dados em um arquivo, e uma das maneiras mais
convenientes fazer isso é o formato JSON Portanto, para salvar e
carregar os dados, quero ter um objeto de
salvamento e carregamento. Agora, normalmente, eu faria
disso um sistema separado, mas a única vez
que precisamos salvar os dados é quando nosso
personagem é derrotado, e vamos lidar com isso
por meio do gerente do jogo. Então, na verdade,
vou
criar um novo script nos sistemas criar um novo script e
chamá-lo de save load. Não vou chamá-lo de
sistema porque é mais
um componente do próprio gerenciador de
jogos. E isso será contado por referência. Então, vou criar esse script. Vamos expandir
os sistemas. Abra-o. Poderíamos dar a ela o nome da
classe save load. E vamos
precisar de duas funções aqui: função de salvar estatísticas, e isso vai usar as estatísticas
atuais do jogo
como parâmetro. Então, estatísticas das estatísticas do jogo, e retornaremos nulos aqui Então, isso pegará as estatísticas
atuais e transformará em um
dicionário de dados
e, em seguida,
serializaremos esses dados Então, os dados de VR são iguais
a e eu
coloco e coloco entre
colchetes aqui no Colon, estatísticas com dois pontos Agora, esse método,
é claro, não existe. Escreveremos isso em um minuto. E uma vez que temos os
dados em um dicionário, este é um dicionário
de dados, a propósito, eu poderia deixar isso mais claro
declarando o tipo lá Mas sempre que você vê esses
colchetes e o script GD, você está falando
sobre Então, em seguida, transformamos
esses dados em uma string JSON. Então, isso também é muito simples
de fazer. Diremos que var JSON string será igual a JSunnu. Portanto, temos um novo
objeto JSON que
nos permite chamar essa string do método
Pi em nossos dados, e isso a torna em um formato de string JSON
legível em JSON Então, agora precisamos
abrir o caminho do arquivo. Então, diremos que var
file será
igual a fileaccess dot OP Portanto, essa é outra
classe estática na biblioteca Godo, e precisamos fornecer a ela um caminho e, em seguida, o acesso correto ao arquivo Então, vamos dizer Save File path, que ainda não definimos, e então queremos acessar aqui. Então, onde vamos obter o caminho
seguro do arquivo
aqui no topo? Diremos var, salvar o caminho
do arquivo é uma string. Isso será igual ao usuário
slash LASH gametatt JSON. Ok, então o que esse
Fopath basicamente significa é que ele
salvará os dados do aplicativo, supondo que você esteja no Windows, para esse projeto de jogo específico, na raiz dessa pasta, haverá um novo arquivo
chamado gamesatt Então, cada jogo feito no GADO tem
uma pasta de usuário no Windows, essa é a barra de dados do aplicativo Gdolah, o nome do
seu projeto, E então ele salvará o JSON do
GameStatst na raiz. Portanto, esse arquivo JSON é
efetivamente seu arquivo salvo. Para um jogo de sobrevivência, o arquivo say é, na verdade,
apenas suas estatísticas mais altas porque toda vez
que você inicia um novo jogo, você tem um novo personagem,
não salva e carrega o jogo como faria
com um RPG típico Mas o processo é
mais ou menos o mesmo. Então, se o arquivo existe e tivemos que abri-lo
para gravação, correto? Então, se não o encontrarmos, então deve
ter ocorrido um erro. Mas se a encontrarmos, diremos file dot store string
porque temos uma string JSON lá em cima,
certo, então apenas armazenamos a string
JSON no arquivo
e, em seguida, fazemos file dot E é assim que você
grava no arquivo. Caso contrário, se a
operação correta estiver falhando, claro que queremos pressionar
e errar Portanto, o erro push
falhará ao abrir um
arquivo para gravação, e eu poderia dizer no caminho, por cento s, e
faremos as cotações Então aqui, porcentagem do caminho do arquivo
salvo. Então, fornecendo o máximo de
informações possível, e então podemos depurar a partir
daí se houver algum problema Obviamente, você precisa soletrar
porti error corretamente. Isso ajudaria, e essa
é a função segura. Ok, agora queremos fazer
nossa função de carregamento de estatísticas. Então, a função carrega as estatísticas e teremos
o
objeto de estatísticas no qual estamos carregando
os dados. Portanto, as estatísticas são do tipo estatísticas do jogo. Claro, receberemos isso do gerente
do jogo mais tarde. E primeiro, queremos
abrir o arquivo para o R acessar. Então, o arquivo VR é igual a Deus, não
consigo digitar agora. O arquivo VR é igual a fileaccess dot OP no caminho
do arquivo salvo Então, estamos carregando e salvando
no mesmo caminho de arquivo. E então temos o Fleaccess
dot RED. Então vamos. Então, digamos que, se não for arquivo, então falhamos em abrir,
podemos dizer, erro push, falha ao abrir o arquivo para
leitura em Path percentents,
percent, save file Talvez até queiramos
fazer disso um booleano. Portanto, se o tornarmos um booleano
, podemos retornar false aqui, pois falhamos na operação Isso pode ser um
pouco mais útil. Posteriormente, você pode alterar Safsts para fazer a mesma
coisa, se quiser E estamos retornando false, não literalmente a palavra-chave,
então, neste momento, nossos arquivos estão abertos para acesso de leitura. Então, agora precisamos obter a
string do arquivo JSON. Portanto, nosso JSOText é igual
ao arquivo dot Get as text. OK. E a razão pela qual
isso não está aparecendo é provavelmente porque eu
não digitei isso aqui. Então, eu poderia dizer acesso a arquivos. Vamos ver, o texto JSON também deve ser sublinhado lá,
e podemos continuar Então, temos o texto do arquivo, então
terminamos com o arquivo. Vamos fechar o
arquivo, fechar o filé. Se o arquivo estiver vazio
, podemos voltar aqui. Portanto, o texto com pontos JS está vazio. Então você pode retornar
verdadeiro ou falso aqui. Depende
do que você quer. Vou retornar true, na verdade, para que possamos indicar que
a operação foi bem-sucedida, mas não havia dados para carregar Então, vamos dizer que carrega os
dados de estatísticas no objeto de estatísticas do
jogo. Portanto, se o arquivo não estiver vazio, precisamos convertê-lo. Até agora, JSON
será igual a Jsunt Nu. Portanto, temos um novo objeto JSON
e, em seguida, queremos
analisar o texto Então, digamos que var error seja igual análise de pontos
json no Então, se houver um
problema com isso, retornará um erro. Então, em caso de erro,
queremos enviar um erro, falhamos em analisar o JSON
com porcentagens de erro, e eu direi Acho que isso pode acrescentar algumas informações
extras úteis. E então retornamos false
aqui porque, é claro, se ele errou ao analisar o arquivo, então há um grande
problema com nosso arquivo SAI Provavelmente não foi
formatado corretamente. Ok, então se não houve erro, sabemos que a análise funcionou corretamente, então podemos dizer var Um dado do dicionário é
igual aos dados json dot g. Então, estamos basicamente
transformando-o no formato GIDorCognized E então diremos que os dados de
Varsats são um dicionário igual ao ponto de
dados. Entre na cotação
Stats, E o padrão aqui
é um dicionário vazio. Então, essas estatísticas devem corresponder às
que temos aqui. Salvamos as estatísticas
no par de valores-chave e precisamos recuperá-las
do par de valores-chave de estatísticas Então, quando tivermos nossos dados estatísticos
reais, que são um dicionário, podemos fazer stats dot
From dict for dictionary, e
passaremos os dados estatísticos. E isso é tudo o que precisamos
fazer para nosso carregamento, então retornamos verdadeiro. Ok, eu acho que isso parece
muito certo. Então, o que precisamos agora é de
um método de dois dicionários e do dicionário from
para nossas estatísticas de jogo. Então, se abrirmos as estatísticas do jogo, digamos que function to dict
retorne um dicionário
e, em seguida, a função
de dict pegue um dicionário de dados
e retorne void Então, para
transformar isso em um dicionário, precisamos que um dicionário de realidade virtual como esse seja
igual a um novo dicionário. E então, na verdade, você
sabe, dentro daqui, podemos simplesmente colocar
tudo isso em uma coisa e colocar cada novo par de
valores-chave em uma nova linha. Então, diremos que inimigos derrotados são iguais a
inimigos derrotados. CD de dois pontos para o par de
valores-chave. À esquerda, você
tem o nome da string e, à direita, o valor real. Então, à esquerda,
temos sobrevivido ao tempo. E então dois pontos, e tempo sobreviveu até a
variável à direita, e então retornamos
o dicionário E é realmente muito simples. Então, a seguir, do dicionário, queremos carregar os valores antigos
nos valores atuais. Então, vamos fazer com que
inimigos sejam derrotados, igual a p data dot git, o par
de valores-chave E então, o valor padrão, vamos torná-lo nulo para que,
se não houver esse valor, obtenhamos um erro porque caso contrário, o carregaríamos em algo como zero, e isso
substituiria permanentemente todos os nossos dados salvos É meio discutível qual
caminho você quer seguir aqui. Por exemplo, você quer que ele falhe
imediatamente
no carregamento do salvamento
ou que seja bem-sucedido, mas depois substitua os dados reais
antigos, que realmente não parece
muito desejável, certo? Você não quer anular
o progresso do jogador. Então, talvez seja mais como se
você precisasse lançar um hot
fix ou algo parecido. Se você se deparar com
essa circunstância
em que o JSON simplesmente
não carregou corretamente, você não tem esse campo, está faltando o nome,
algo assim Então é por isso que eu
estou indo mais ou menos assim: Oh,
deveria ser nulo Então, quando ele tenta definir o float como nulo ou
o inteiro como nulo,
você encontrará um erro e ele precisará ser
corrigido ou, caso contrário, interromperá todos os jogos de Acho que esse é provavelmente
o caminho a percorrer aqui. Então, time
survived será igual a pdta dot get on time
survived como uma string, e então o
valor padrão é Ok, então temos as estatísticas do jogo Atualmente, as únicas
estatísticas do jogo são as estatísticas principais do jogo, estatísticas atuais do jogo, mas também queremos ter estatísticas
de jogo persistentes,
nossas estatísticas de jogo com maior pontuação. Então, eu quero colocar uma
função aqui para obter
o valor mais alto em comparação com
as estatísticas atuais do jogo. Então, vou dizer que a função
está configurada para a maior, digamos, definir pontuações mais altas. Para as estatísticas atuais do jogo P, e isso será
anulado Então, vamos
chamar isso apenas nossas estatísticas de jogo com pontuações mais altas, mas basicamente
consideraremos o maior
dos dois valores. Portanto, os inimigos derrotados serão iguais ao máximo de inimigos derrotados ou ao ponto P atual de
inimigos derrotados. Ok, então estamos apenas
pegando o valor mais alto e configurando-o para os inimigos
inteiros derrotados E fazemos a mesma coisa
com o tempo sobrevivido. O tempo sobrevivido é igual ao máximo. O tempo sobreviveu e o ponto P
atual, o tempo, sobreviveu. Ok, então é assim que
obtemos as pontuações mais altas. Apenas comparamos as
estatísticas atuais no final
do jogo e vemos se maiores do
que nossas pontuações mais altas
atuais. Portanto, precisamos do objeto de salvamento e também das estatísticas de jogo com maior
pontuação em nosso gerenciador de jogos. Então, vamos abrir o gerenciador de
jogos agora. Gerente de jogo dot GD. Então, também teremos aqui
as estatísticas de pontuação mais alta, que
serão um GamestStnu e também teremos aqui o var saveoad, que será igual
ao nosso objeto save será igual
ao nosso Portanto, esse é apenas um
componente local do nosso gerenciador de jogos. Talvez até o tornemos privado. Sim, por que não? Torne-o privado. Porque, na verdade, na lógica do
saveoad, queremos pertencer apenas
ao gerente do jogo Na verdade, não é
algo que outros scripts deveriam abordar,
então nós o tornamos privado Então essa função aqui,
digamos que a função End Game, acho que é um pouco
melhor renomear Isso será anulado. Então, no final do jogo, queremos obter nossas estatísticas de pontuação mais
alta e definir pontuações altas
com nossas estatísticas atuais. E então talvez queiramos
redefinir as estatísticas atuais, mas na verdade não vou fazer
isso porque talvez
queiramos mostrar no menu principal
do jogo quais foram as pontuações da
última sessão, para que não reiniciemos o jogo corretamente
até
reiniciarmos o jogo corretamente. Acho que é um pouco melhor. Ah, e é claro, depois de
estabelecermos as pontuações mais altas, queremos chamar save
load dot save stats. Então, vamos salvar as estatísticas
de pontuação mais alta. E acho que está pronto. Sim, na função Ready. E lembre-se, isso é
Auto Load Singleton,
então, assim que o jogo começar, ele já estará E eu quero fazer o sublinhado salvar as estatísticas de carregamento de pontos
nas estatísticas de pontuação mais alta E sim, isso realmente
lida com o resto. Portanto, a fila lógica para salvar
e carregar está basicamente escondida dentro desse objeto de
salvamento ou, na verdade, está
encapsulada Portanto, toda a carga de salvamento
está aqui, mas o gerente do jogo
realmente determina quando deve salvar
e carregar esses dados. E você pode ver que isso torna
o gerenciador de jogos muito mais fácil de ler porque dividimos suas funções em componentes
diferentes, em vez de amontoar
tudo em um script gigante de gerenciamento de jogos Portanto, este vídeo está
um pouco longo, então farei o próximo vídeo sobre como criar
a tela do menu principal. Já temos o modelo para ele porque nosso
botão de fim de jogo vai até aqui, mas não configuramos
nada aqui Então, vamos conectar
isso às estatísticas de
pontuação mais alta , ter uma tela, um botão Iniciar o jogo e algum tipo de
fundo de tela inicial
60. Parte 59 Como projetar um menu principal com exibição de alta pontuação e funcionalidade de início de jogo: Vou pegar o layout
no contêiner High Scores e colocá-lo nas âncoras da parte superior ou
direita. Então eu posso ampliar. Vou pressionar Q para mover essa
posição para lá. Vamos ampliar nosso contêiner de pontuações mais
altas
e, em seguida, criaremos alguns
outros nós de controle aqui. Então, vou clicar aqui e
adicionar um nó filho. Digamos que Margin Container. Mesma história com o contêiner
Margin. Queremos uma substituição de tema, quatro pixels em todos eles E então, para economizar
tempo, acho que
poderíamos acessar a visualização de Gamesets. E vou copiar e colar
que o tempo sobreviveu
e os inimigos foram derrotados. Vou apenas
controlar a visualização de tudo e colar no menu principal. Então, dentro de lá. E eu esqueci
um contêiner VBox,
então adicione um contêiner VBox
e mova
esses dois contêineres de texto para
baixo dele. Assim. E então é mais ou menos
assim que vai parecer agora. Vamos salvar o
contêiner de pontuações mais altas em sua própria cena, clicar com
o botão direito do mouse, digamos cena
branchien, assim E então eu quero transformar
o layout e triplicar a escala, desse jeito. Ok, então quando fizermos
isso, vai mexer um pouco com
nossa predefinição de âncoras, então vou
posicionar isso ali Não há necessidade de deixá-lo
realmente perfeito. Também vamos abrir o contêiner de pontuações mais
altas e adicionar um texto de título. Então, ampliando aqui o contêiner
do VBox, clicarei com o botão direito do mouse e
adicionarei um rótulo de rich text E vamos posicionar isso em
cima do contêiner VBox. Confira o conteúdo do Fit e
, digamos, as pontuações mais altas, mas vou começar
com, digamos, arco-íris Termine os colchetes, vá até o final Rainbow Obviamente, para
que isso funcione, precisamos verificar
se o código BB está ativado e obtemos um arco-íris
padrão Então, acho que quero
diminuir a frequência e tornar isso menos dramático. Então, digamos que a
frequência seja igual a 0,5. Bem, vamos até 0,25. Sim. Isso é muito melhor. E então precisamos do
SAT para saturação. Então, digamos que saturação
de 0,2, talvez 0,5. Ok, isso é um pouco
mais manso. Então isso é bom. E faremos o centro de
alinhamento horizontal. Ok, isso não é tão ruim. Então, no menu
principal, podemos ver como
isso vai ficar. De volta ao contêiner de pontuações mais altas, vamos atribuir o rótulo correto. Portanto, o rótulo máximo derrotado é o rótulo da quantidade sob o contêiner derrotado do
inimigo. E então o rótulo que sobreviveu por mais tempo está no recipiente que
sobreviveu Ok, salve isso e, de
volta ao nosso menu principal, precisamos de um fundo de textura. Então, vou clicar com o
botão direito do mouse no menu principal. Vamos adicionar um ato de textura. Vou renomear isso para ter o plano de
fundo destruído. Voltaremos a isso.
Além disso, na tela do menu principal, queremos ter certeza de que
desativamos a filtragem do mouse Então, passe o mouse à direita, giramos o filtro para ignorar.
Isso é importante. Caso contrário, o menu principal
realmente bloquearia os
botões abaixo dele. Então, vamos adicionar um botão
agora para o nosso jogo Iniciar. Então, adicione um botão. Vamos renomear isso para o botão
Iniciar jogo. E se bem me lembro, eu só tenho um roteiro que pode mudar de
cena imediatamente. Então, botão de mudança de cena, vou arrastá-lo e soltá-lo
diretamente no botão
Iniciar jogo. E então precisamos dar a ela
a trajetória cênica do mundo. Então, no canto superior direito, caminho da cena, selecione o ponto mundial TCN, e agora esse botão deve ser
capaz de abrir o mundo, que é a nossa cena de jogo Esse botão é muito
pequeno, é claro, então precisamos ir para o layout. E eu vou triplicar a
balança aqui embaixo. Vamos também posicioná-lo em
âncoras e, em seguida, dizer no centro da
parte inferior. Podemos ampliar aqui. Eu vou bater em W. Vamos
mudar isso até aqui. Vamos dar a ele o
texto Iniciar jogo, e talvez queiramos
selecionar um ícone também. Então, vamos criar ícones
como textura de atlas, carregamento
rápido e atlas
do nosso projeto de jogo Eu vou fazer 64 ou 64. Escolha a região e
escolha o ícone que quiser para começar o
jogo. Então eu não sei. Como este é um jogo baseado em
combate, talvez uma dessas
espadas seja boa Então, vou pegar isso, certificar de obter todos os pixels. Então eu preciso
esticar isso para a esquerda, apertar. Por precaução, eu também vou
verificar o clipe do filtro. Não queremos que
pixels de borda entrem lá. Então esse é basicamente o
nosso jogo inicial. Pressione o botão W e
verifique se está dentro dos limites do nosso menu principal Vamos também ao Projeto, e vamos pegar o menu principal e fazer dele nossa cena de lançamento
do jogo. Então, em geral, corra, em vez de lançar
o mundo agora, vamos carregar. O menu principal tem pontos TSCN. Ok, agora
vamos ver onde estamos. Vou clicar em play. a pontuação mais alta lá em cima,
temos Start Game. Vamos clicar em Iniciar jogo, que inicia nossa cena principal de
jogo. Isso é o que esperaríamos.
E rapidamente, na verdade, vamos ser derrotados
para que possamos ver a pontuação mais alta
em nosso menu principal. Claro, eu renomeei o Game Manager dot report game over, então precisamos mudar isso para
game manager dot end game Isso está no estado do jogador
derrotado. Ok, agora vamos
lançar mais uma vez. Então, vou me certificar de ser derrotado por uma dessas obras, três acertos, quatro
acertos, cinco acertos. E vamos ver. Os jogadores
já foram libertados. Está na nota mundial porque, na verdade,
libertamos o jogador Também precisamos dizer
aqui para todos os mundos. Se o processo funcionar, onde estamos adicionando
o tempo sobreviveu, teremos que dizer se o
contexto está fora do jogador. E teremos que dizer que
não é igual a nulo. Acho que para referências
liberadas anteriormente, se você apenas usar o Context Out player,
ainda haverá um erro, mas se você disser que
não é igual a nulo
, isso contornará isso Ok, então, basicamente, se o
jogador não existir mais ou
não estiver mais vivo, adicionaremos o tempo de
sobrevivência às estatísticas do jogo. Como o player foi removido, isso resolverá essa parte , e devemos estar prontos para começar. Ok, então mais uma jogada de rebatida, certificando-se de
que realmente funcione Oh, podemos ver que
a pontuação máxima foi atualizada aqui,
então isso é bom. Talvez precisemos redimensionar um pouco
a interface do usuário. Como você pode ver,
o problema aqui
está mostrando cerca de
12 pontos decimais, então vamos mudar
isso em um minuto Vamos ver se podemos ser
derrotados em menos de 7
segundos. Ok, vamos. Um, dois, espere. Atualize este equipamento
e ele falhou. OK. Então, temos que encontrar outro inimigo ou
dois. Lá vamos nós. 12 segundos. Menu principal. Você pode ver que nossa
sobrevivência mais longa agora é de 12,6 segundos. Os inimigos derrotaram dois. E vamos fechar o jogo e clicar em play. Isso verificará
se o carregamento do arquivo está realmente funcionando. Então, vamos fechar e clicar em play. Talvez eu ainda não o tenha configurado. É interessante
ver se tem ou não. Ok, então sim, quando
o jogo carrega, o gerente do jogo é, tipo, uma das primeiras coisas a carregar, e ele já carrega
na pontuação máxima qual é a pontuação máxima salva
do arquivo. Ok, então, como um bom momento
para mostrar onde isso está, vamos apresentar os dados do aplicativo
no Windows File Explore
e, em seguida, queremos encontrar Godot E então eu acredito
que são os dados do usuário do aplicativo, o script GD do Script
Survivor mais recente do projeto E aqui
temos o Arjsofle. Ok, então vamos editar no Bloco de notas. E aí você pode
ver ali mesmo. Nossas estatísticas reais do jogo
foram salvas em um arquivo. Temos inimigos derrotados
duas vezes e sobreviveram a 12,6, e esses são nossos dados de jogo salvos, que são atualizados sempre que somos derrotados, caso tenhamos algum desses números Ok, então para o contêiner de
pontuações mais altas, o texto sobrevivente mais longo, nós meio que queremos
copiar o que estávamos fazendo na visualização de estatísticas do jogo Então, vou
entrar nesse roteiro. E então eu quero copiar
essa parte aqui, que pega o
fluxo e nos dá uma string que tem apenas
uma casa decimal Vá para o contêiner de pontuações mais altas, e eu vou substituí-lo
aqui por este. O PT,
é claro,
será na verdade o gerente de jogo dot high
scorstts dot Time Agora, se estivermos jogando,
chegarmos ao menu do jogo, devemos ver 12,6
segundos aqui Isso é muito mais legível do
que nossa pontuação mais alta. Então, agora, para nosso histórico, vou literalmente fazer uma
captura de tela do jogo E você pode
desativar a interface do usuário para isso se quiser
fazer uma captura de tela Isso provavelmente seria
um pouco mais útil. Ok, então vamos também desativar as formas de colisão antes de
fazer a captura Então, depure as formas de colisão. Ok, então vamos
pegar nosso site como uma atualização
para que possamos mostrar isso. Vou deixar alguns desses
captadores no mapa do jogo. Vamos esperar que o
esqueleto apareça e depois veremos se podemos obter uma boa captura Uma coisa que eu
consideraria
seria aumentar a taxa de desova se quisermos enfatizar quantos inimigos
existem no jogo Ok, então vamos capturar a tela aqui. Eu não gosto muito desse. Vamos talvez fazer uma captura de tela lá. Então, imprima a tela para fazer uma captura de tela, se isso
não for óbvio E eu vou abrir a Gap. Então, o Gap é um editor de imagens gratuito. É como o Photoshop. Mas grátis. Então
vamos fazer File New, e eu vou fazer 1920 por
1080 pixels. Abra isso. Controle V para colar
nossa captura e vamos pegar
algo parecido Não é realmente um tutorial
de edição de imagens aqui, mas bem rápido, vou colar uma barra
superior lá. Então, usando um preenchimento preto, podemos fornecer o
texto, se assim o desejarmos. Vou escolher uma fonte. Então,
vamos usar o pixel regular. Você teria que instalar essa
fonte se quiser usá-la. Ok, então eu passei
um pouco de tempo criando uma
espécie de miniatura personalizada, exceto que vamos
usá-la
no projeto final do jogo Então, basta colocar em um
fundo preto na parte superior, um texto da Pixar,
mencionando que é um curso GD, mencionando
que é um curso Do e, em seguida,
o ícone Gudo Essa provavelmente não será a miniatura
final do curso, mas podemos usá-la na tela do menu do jogo, pelo menos
por enquanto E eu vou abrir isso. Eu o exportei para o
projeto, é claro. Então, onde você salvou isso, você pode ver que eu tenho a tela do menu
principal aqui. Então, o que eu quero fazer e a interface do usuário, essa é, na verdade,
a tela errada. Queremos o menu principal.
Vamos para o fundo Rec Vou carregar rapidamente e procurarei a
tela do menu principal. Coloque isso aí. Talvez eu precise aumentar
o tamanho aqui, então vamos para o modo de layout, âncoras e destruímos completamente Ok, então com isso e
totalmente destruído, agora queremos ter certeza de que nada
seja bloqueado por Então, acho que precisamos mover
isso para o topo à esquerda. Ok, aí as
pontuações mais altas mostram que podemos jogar. Ok, e podemos jogar, e devemos vê-lo lá. pontuação mais alta de Script Survivors aqui
. É um curso de Gado. Temos o
botão Iniciar Jogo e o ícone Gado,
que, quero dizer, são bastante
sólidos para cerca de cinco, 10 minutos de trabalho, acho que, é
claro, podem ser melhorados. Ok, agora, neste momento, praticamente o jogo
está quase pronto. Temos nossa tela inicial lá. Podemos começar o jogo,
as pontuações mais altas,
exibidas durante o jogo
as pontuações atuais e na tela do menu principal,
as pontuações mais altas de todos os tempos. Nós podemos derrotar os inimigos.
Podemos perder o jogo. Podemos atualizar, talvez
queiramos fazer alguma limpeza, como remover essas
atualizações iniciais do mapa do jogo Isso é um pouco estranho
lá. Mas isso estava lá apenas para fins
de teste. Talvez queiramos aumentar a dificuldade, adicionar
novos inimigos Poderíamos ter nosso
personagem principal, você sabe, mostrando a lança
se quisermos que ela esteja lá, em
vez de meio que sem braços Mas, quero dizer, funciona
do jeito que é agora. E podemos
subir de nível várias vezes. Não está pronto para o
lançamento completo, é claro. Ainda haveria muito trabalho
a ser feito lá, mas tudo está basicamente funcionando conforme o esperado.
Acabou o jogo. Aí está nossa pontuação mais alta.
Talvez o menu principal possa usar uma trilha sonora, que eu possa fazer para
que eu possa fazer mais
um vídeo aprimorado limpar o curso, para
limpar o curso,
mas é
basicamente isso Então, espero que todos
vocês tenham aprendido muito
até o fim. Eu sei que foi um curso
bem longo, 11 horas mais o tempo de execução total
editado. Então, quero dizer, se você chegou
aqui e acompanhou tudo e seu
jogo está funcionando como está, quero dizer, bom trabalho porque na verdade
foi bastante. Ok, então muito obrigado
por assistirem, grosso modo, o final do meu curso de
sobreviventes de roteiros, roteiro GD em Gadot 4.4
61. P60 Aperfeiçoamento de sobreviventes em script ~ Melhorias de jogabilidade e depuração: Então, neste vídeo,
vamos tentar aprimorar o protótipo do nosso script
Survivor Então, primeiro, no
final do último vídeo, eu tenho sete erros
no console. Então, essa é a primeira coisa que
vamos cuidar. Sempre que você vê um erro, é um bom momento para resolvê-lo, depurá-lo e descobrir
o que estava errado Portanto, temos itens retirados que
não têm um item
realmente atribuído a eles Então eu acho que o que
seria realmente útil aqui seria
dizer porcentagem Sul, e então colocamos isso
aqui como porcentagens Ok, então você pode ver
que a mensagem de erro aqui não é tão clara
quanto poderia ser. retirada de um item
precisa ter um item, mas não sabemos qual item realmente falhou na
coleta Então, como você pode fazer isso
no script D de coleta de dois itens
é, no final do script atribuído à coleta, fazer uma porcentagem e, em
seguida, seguir a sequência
com Então, isso substituirá as
porcentagens pelo nó, que será resolvido para um nome de
nó ou, em outras palavras, qual nó realmente não
teve o item atribuído Ok, vamos fazer
isso mais uma vez. Vou jogar um pouco, ver se encontramos novos problemas. Ok, então, como esses itens
são retirados e a parte de saúde, diz
que o item não
está pronto, que é estranho, porque a
exportação na exportação definitivamente
deveria estar fazendo isso Portanto, se o item for igual a nulo
, relataremos um erro Oh, ok, certo, certo.
Então eu cometi um erro aqui. Se isso fosse uma afirmação,
funcionaria bem. Mas o que realmente
queremos fazer é dizer que o item
I é igual a nulo e, em
seguida, inserimos o erro Eu ainda estava na
lógica assertiva lá. Então,
vamos acabar com isso. Se o item for nulo,
enviaremos um erro. Agora, se jogarmos,
deve funcionar, é claro. Caso contrário, sempre
geraria um erro. Então, você pode ver no debugri aqui
embaixo que não há problemas Vou coletar alguns itens. Vamos fazer com que os inimigos os derrubem, e isso deve
funcionar muito bem para isso. Até agora, não
parece que haja
outros erros novos. Eu notei um pequeno problema
de layout da interface do usuário aqui. Então eu acho que se eu pegar
a foice aqui, ela pode meio que reposicionar
essa interface de usuário de alguma forma estranha Oh, ok, isso é
o que aconteceu. A caixa HB estava, na verdade,
se expandindo para ficar maior. Então, para corrigir isso, eu preciso bloquear
o tamanho no lugar. Caramba, eu deveria
torná-lo maior e depois mover isso para a direita. Acho que seria melhor. Ok, então, para essa interface de jogador, precisamos expandi-la um
pouco para que ela tenha
espaço para grelhar. Então, vou entrar na interface do jogador. E então vamos pegar o contêiner do painel
raiz esticá-lo para a direita
para que ele tenha espaço extra. Vou para a interface do Game Play. Vamos mover isso
para a direita. Agora, se eu clicar em Play e por
acaso melhorarmos nossa saúde, e ele a redimensionar, ele não
deve mais
empurrá-la para a
direita, porque ela já tem espaço para caber
no rótulo de texto completo E eu preciso redimensionar um pouco o layout das
armas. Eu o comparei um pouco
incorretamente, então vou alinhar isso
até o topo, clicar em jogar, começar Ok, e isso
parece bem sólido. No mundo, eu
quero remover todos esses
captadores por padrão Eram só para testar. Eles não deveriam estar
no protótipo final, então vou
cortá-los
com o Control X, selecionando todos E acho que quero tornar o jogo padrão um
pouco mais difícil. Então, vou para
o sistema de geração e vamos aumentar
a taxa de amplitude Então, vou reduzir isso
no início para uma taxa de desova
mais alta Adicione também um ponto extra
aqui, mais ou menos assim. Ajuste o guidão,
algo parecido. Eu só quero fazer uma
curva mais íngreme para que
mais inimigos apareçam mais rápido para que eu
possa mostrar uma jogabilidade
mais intensa Na demonstração. Está bem? E todos jogam. Vamos testá-lo
um pouco e ver como funciona. Então
eu vou começar o jogo. Queremos que nossos inimigos
cheguem ao centro. Talvez os orcs sejam
um pouco lentos demais. Eu poderia aumentar a velocidade de
movimento dos orcs
e do esqueleto Portanto, não há realmente nenhuma
necessidade de facilitar as coisas aqui. OK. Então, aí temos nossos
esqueletos e os orcs Então, vou aumentar a
velocidade de movimento dos dois. Vou procurar o controlador estatístico orc
. Vamos mudar as estatísticas dos orcs. A velocidade pode ser, digamos, 35, e então
vamos até o esqueleto Velocidade do controlador Sat de 60. Vou
dificultar as coisas aqui, e então o MX HP
pode chegar a 100. Tudo bem. E o HP orc é 40. Tudo bem. Vamos
jogar. Comece o jogo. Uma coisa que você pode
acrescentar: eu não vou fazer isso aqui, mas ter, tipo, uma explosão de inimigos no início
tornaria
a jogabilidade inicial um pouco mais intensa
se você começasse o jogo gerando instantaneamente dez
caras para virem até Isso pode ajudar.
Mas acho que isso é um pouco exagerado apenas
para o protótipo Então, as obras se movem
um pouco mais rápido, e os esqueletos
estão bem rápidos agora Então, isso definitivamente
será muito mais difícil. Eu preciso pegar o HP
atual e
configurá-lo para 100 no início. Ok, talvez os esqueletos sejam até um pouco rápidos
demais, honestamente Ok, então vamos fixar o HP inicial dos
jogadores, o jogador, controlador de
estatísticas, as
estatísticas do jogador e o HP até 100 E vou acalmar um pouco
os esqueletos. Digamos que 50 velocidades. Eu
acho que isso é muito justo. Ok, nas definições do
nível do jogador, também
vou facilitar
a subida de nível. Então, vou pegar o nível três
e definir isso para cinco. nível quatro será
dez XP, o nível cinco, pode ser 15, o nível seis, pode ser 20 e o nível
sete pode ter 25 HP. E então vou
adicionar mais um para 100. E isso vai ser como aquele
que você realmente não conhece. Na verdade,
vamos adicionar mais um. Digamos que 1.000 novos
níveis de definição. A razão pela qual estou
dificultando minha ida é para que isso
realmente não aconteça. Eu meio
que estraguei tudo. Ou seja, o nível 1.000 leva dez XB.
Não é isso que eu quero. O que eu queria, e vamos
excluir isso, é que o nível nove será
uma definição de nível com 1.000 EXP necessários, acrescente isso Então, isso faz com
que eu não precise planejar essa quantidade de escala
na demonstração do protótipo Seria um pouco
exagerado por enquanto. Então, vamos clicar em Play e eu vou
ver como o jogo se desenrola. Comece o jogo e
esperaremos que os primeiros
inimigos apareçam Ok, eu acho que é um pouco fácil
demais no começo. Eu quero que seja intenso rapidamente. Então, acho que o que vou fazer é realmente criar aquela geração
instantânea de dez caras Então, no mundo, digamos que,
ao exportar V, os spawns iniciais, e eu definirei isso
como N igual a dez O mundo terá
uma referência ao de geração,
portanto, sistema de geração E então, quando estiver pronto,
direi os intervalos iniciais estão acima de zero Então, diremos sistema gerador. Deixe-me ver. Como foram chamadas
as funções? Spawn aleatório. E eu ligo para
isso dez vezes? Espere um pouco. OK. Sim, e
parece que preciso ligar para isso dez vezes ou o
número de intervalos iniciais. Então, por um tempo nos spawns iniciais, vamos chamar
spaorsystem dot Então, dez spawns iniciais, isso deve nos fazer gerar dez caras no
início do jogo Ok, não se esqueça de definir o sistema de patrocinadores no mundo. Então, atribua esse sistema de patrocinadores. Referência direta do nó,
vamos clicar em Play. E se isso funcionar, teremos dez caras no
início do jogo, o que deve tornar
tudo muito mais difícil Ok, sim, são muitos caras para o
início do jogo. Então, só temos que
evitar todos eles. Isso pode realmente ser
muito difícil, honestamente. Eu vou reduzir isso para cinco, e vou mudar isso para cinco
no roteiro, também. Acho que dez caras
no início, quando você
ainda nem
subiu de nível , é muito
lidar com uma só vez Ok, então temos nossos
cinco caras começando agora. Vamos pegar um XP. Vou me atualizar com o
Syth, o que nos dará maneira
extra de atingir
os inimigos. Muito mais fácil agora. E eu vou continuar aqui. Vamos fazer algumas atualizações, já que facilitamos muito a curva
de EXP, então poderemos subir de
nível com bastante Mas devo dizer que
aumentar a velocidade
dos inimigos definitivamente torna muito mais difícil evitá-los, então isso é algo
a se ter em mente Vamos continuar atualizando a lança. Então eu acho que em um certo nível, a lança atinge dois caras ao mesmo
tempo. Já está lá. A lança de nível três
pode atingir dois caras. O que é definitivamente
uma grande atualização. Estou meio que analisando
a jogabilidade aqui. Os esqueletos a 50
velocidades são bem resistentes. 60 velocidades para os esqueletos definitivamente
seriam demais. Vamos continuar
com a lança. Com base nas configurações atuais, na verdade não tenho ideia se a lança ou a
foice são melhores Provavelmente com
grupos grandes como esse, a foice
seria melhor porque, você sabe, ela pode atingir
todos eles ao mesmo tempo Mas, às vezes, um único
alvo também é importante. Quero dizer, estamos apenas
começando a falar sobre como jogar o jogo
agora. Então, isso é uma tonelada de esqueletos, e em algum momento, eles
vão meio que me pegar Podemos ver um
pequeno problema, que é esse tipo de
aglomeração excessiva Então, eu quero que eles não se
acumulem, mas acho que suas formas de
colisão provavelmente
são muito grandes agora Isso meio que
os torna incapazes de se mover. Então, na verdade, encontramos
um bom problema que podemos resolver. Vamos pausar o jogo e depois vou
pegar os esqueletos Em todas as cenas, vamos
assumir a forma de colisão, e vou
reduzi-la bastante Vamos fazer isso como dois
e depois vamos até o orc. Vamos tomar sua forma de colisão. Essa é a forma básica de colisão
corporal do personagem, e vamos pegar essa forma de
colisão, expandi-la e
defini-la como duas também Se pararmos de pausar o jogo, se estiver funcionando corretamente, acho que está Não posso dizer 100%. Então, como sua forma de
colisão é menor, eles se aglomerarão Mas, sim, ainda é muito difícil quando há
tantos caras vindo até você. Se também existissem
projéteis, então você definitivamente tem um jogo
bem difícil neste momento Para que eu possa comprar mais
algumas coisas. Vamos atualizar a
foice desta vez. E vamos ver
o game over screen. Eu provavelmente poderia
correr por um tempo, mas só queremos verificar se tudo ainda está funcionando
com o
protótipo polido, frutado e sólido que está lá dentro E vamos ao menu principal. Nosso tempo sobreviveu. Acho que preciso trazer
isso um
pouco para a esquerda para que haja espaço para o ponto decimal neste caso Além disso, acho que
estamos muito bem. Então, no menu principal, vou expandir um pouco para a esquerda, colocar tudo em uma linha. Isso vai ficar melhor. E talvez eu coloque a música
no menu principal também. Então, vou clicar com o botão direito em um nó. Vamos usar o AudioStream
player e não dois D, porque, quero dizer,
não há dois mundos D agora Estamos apenas vendo
o menu do jogo. Vamos carregar rapidamente
nosso AudioStream,
então.p3 porque preciso
procurá-lo Ok, então vamos
adicioná-lo ao áudio
agora a partir da pasta de áudio. Temos três Red
Hearts Box jump. Também usaremos isso
no menu principal. Vou colocar fones de ouvido para poder testar
isso sozinho. Vamos jogar. Oh,
na verdade eu não reproduzi áudio. Ok, então vamos jogar automaticamente. Sim. E depois jogue. Ok, na verdade, eu quero
verificar o mundo principal do jogo, e eu quero ver o
quão alto isso é. São -40 decibéis. Ok, então eu até quero que seja um pouco mais silencioso
no menu principal Então, vamos fazer com que sejam -45
decibéis. Vou clicar em Play. Teste isso. Ok, e
então vamos para Start Game. É um pouco mais alto aqui.
Talvez a música de final de jogo eu faça um pouco
mais alta do que isso OK. Então, no mundo do final do jogo, eu vou pegar isso e
configurá-lo para menos 35 Acho que deixei tudo muito quieto durante o curso porque simplesmente não
queria que
fosse uma interferência quando eu estava falando sobre isso. Ok, então vamos clicar em Play. começar o jogo.
Ok, isso é bom. Outro efeito sonoro que talvez
eu queira adicionar é que sempre que abrimos a tela de seleção de aumento de
nível, acho que isso poderia
usar um efeito sonoro. Além disso, acho que
estamos com boa aparência. Então, vamos até a tela de seleção de aumento de
nível. Tudo bem, clique em Adicionar um reprodutor
AudioStrem aqui. Deixe-me ver se temos
alguns bons efeitos
sonoros de aumento de nível no projeto. Então, ele estará no menu de interface do usuário
de áudio.
Claro, deixe-me verificar. Ok, o item de uso
parece que funcionaria. Então, vou pegar o
reprodutor de stream de áudio aqui. Vamos colocar um item em uso. Isso não será reproduzido automaticamente, então eu preciso ir para a seleção
LevelUp. Adicionaremos um pop-up
Export var. AudioStream, que
será um reprodutor AudioStream. Então, vamos dizer que
pop-up audiostream dot play, e eu só tenho que
corrigir essa exportação Ok, e então não se esqueça
de adicionar o
AudioStream pop-up na exportação Então, temos que adicionar isso. Poderíamos fazer uma declaração
pronta se
quisermos que a declaração apareça no AudioStream. Lembre-se de configurar o
reprodutor AudioStream para reproduzir som de nível superior Ok, agora vamos clicar em play.
Podemos ir para o Start Game. E vamos testar derrotando
um inimigo, subimos de nível. E então fazemos nosso upgrade. A música continua. E eu acho que isso flui muito bem. É definitivamente bom ter um efeito sonoro real
para o veo up. Então, vamos continuar
com Syth desta vez. O Syth definitivamente
está entrando em guerra aqui. Pode ser OP, na verdade. Ok, então Syth quatro,
vamos ver como isso funciona. Definitivamente, é muito difícil. Isso é muito importante. Como
é basicamente um AOE, provavelmente não deveria estar causando tantos danos,
sejamos honestos Ok, acho que já
vi o suficiente lá. Vou apenas
polir a lança. E torne a lança mais
divertida de realmente usar. Então, vamos atacar o jogador,
a arma de lança. Vamos entrar na definição da
cena. que podemos melhorá-lo Acho que podemos melhorá-lo o quanto
quisermos Nível um curto. Podemos
deixar isso como padrão Nível dois, três,
quatro, cinco. Vamos ver. Para o nível dois, vou fazer com
que cause 20 a 30 de dano e esfrie. Sim, podemos fazer 0,9. O nível três será de 30 a 35. Acho que a lança também pode dar dois golpes no nível
dois. Tudo bem. E, no nível três,
causaremos 30 ou 40 de dano. Ok, então o máximo atinge dois, e então aumentaremos os projéteis para
dois no nível quatro, e isso causará 35 a 45 de
dano com 0,8 de resfriamento E então vamos causar
40 a 45 de dano. Pode ser mais rápido. Vamos
fazer com que o resfriamento seja 0,6. Os projéteis podem ser, por que não? Digamos que
três projéteis. Isso parece muito
maluco, mas ei. E então eu vou fazer uma
corrida rápida com a lança. Vamos ver se a lança pode
até mesmo competir com a foice. Ok, mais lanças. Isso deve nos
dar dois projéteis.
Isso deveria ser muito melhor. Chegar ao nível quatro
foi um pouco difícil. Não vou
equilibrar muito isso, mas queria que
fosse pelo menos suportável Oh, Deus. A desova está
ficando meio ridícula. Oh, eu esqueci de repetir a música. Ok, abra o mundo do jogo. Isso é muito importante.
Então, mundo do jogo. Vamos abrir essa cena. Temos o reprodutor de streaming de áudio. Queremos pegar essa
música e dar uma olhada. Então, acho que precisamos
fazer isso no projeto. Vamos fazer três. Clique duas vezes
nele e ative o loop Tudo bem. Fechar.
E depois reprodução automática Então, em seu reprodutor de streaming de áudio, vamos verificar Looping
on para esse Isso também deve estar na tela do menu
principal, por precaução. Então, aqui estão os parâmetros, continuo repetindo, e depois vou retomar o jogo Então, isso não vai começar até
voltarmos lá. Então, como atingimos a lança de
nível cinco, não
podemos mais selecionar a lança É bom verificar novamente
e garantir que, você sabe, não
se preocupe
ao tentar subir de nível até o nível seis Então, ainda podemos escolher
a foice, é claro. OK. E eu vou me
deixar morrer neste momento. Eu acho que sim. Tudo parece
muito bem. Ah, e a tela de maior
pontuação aqui, se ainda não estiver sendo
exibida corretamente, vamos entrar nela. Então, para obter as pontuações mais altas, para garantir que haja espaço
suficiente aqui, vamos definir um
tamanho mínimo para elas. Vou definir isso
para 60,0 e, em seguida, vamos expandir a
base de pontuação máxima para a esquerda Ok, pegue também
a etiqueta da quantidade, e vamos fazer um
tamanho mínimo de 60, ok? E podemos pegar as pontuações mais altas e torná-las ainda
maiores à esquerda. Tudo bem. E então aperte play. E certifique-se de
que as pontuações mais altas não ultrapassem o limite em nenhum lugar. Então, isso seria bom para
pelo menos mais um dígito, eu acho, sem ultrapassar a borda
e embrulhar nem Ok, então, neste
momento, praticamente, acho que o protótipo
está relativamente polido Tenho certeza de que
podemos fazer ajustes no código e no conteúdo a serem adicionados
ao jogo e
torná-lo um jogo completo Mas no que diz respeito ao curso, mostrando o básico de
como configurar tudo isso, um sobrevivente como o jogo
e o GD Script Gudo 4.4, acho que isso
é praticamente
tudo o que há Então, espero que tenham
gostado acompanhar Long até
o fim. Pode haver alguns
pequenos vídeos de atualização, mas é só isso. Então, obrigado novamente por
assistir Iben Chris, e vejo vocês no
meu futuro conteúdo de vídeo