Transcrições
1. 00: Isso é o que você construirá uma filmagem completa no Unreal Engine Five,
inteiramente em um projeto Eu sou Rob e, ao longo
desses 27 tópicos, esta série levará você
de uma base de código vazia a um jogo jogável finalizado Criaremos nosso próprio movimento de jogador
totalmente personalizado com independência da taxa de quadros,
usando o sistema de
entrada aprimorado e abordando detalhadamente coisas como detecção de
colisões Vamos implementar as classes de
peões para os inimigos
e os aviões dos jogadores com foco na herança,
então
uma classe base, que
alimenta cada tipo de navio, adicionando um sistema de projéteis
que funcionará para ambos os lados,
uma única classe, que Até mesmo as classes de desova que
criamos são configuradas com uma arquitetura que
lidará com inimigos e planos de fundo, e você pode estendê-la
como quiser Também daremos uma
pequena olhada em coisas como design e aprimoraremos o jogo com efeitos de
partículas ,
áudio, trepidação da câmera
e até mesmo Adicionaremos um loop de jogo
completo, para que você tenha um
jogo jogável até o final,
incluindo sua interface de usuário Você pode jogar, morrer,
reiniciar ou sair. O foco será fazer
as coisas corretamente. Vamos analisar arquitetura
limpa, sistemas
reutilizáveis
e realmente entender
por que algo
funciona ou não, e realmente entender
por que algo em vez
de apenas copiar as notas Cada decisão é explicada. Eu pularei propositalmente recursos
integrados do Unreal
e, em seguida, explicarei por que
tomamos Quando algo é contra-intuitivo,
eu chamo a atenção e todos os recursos que
você precisa
acompanhar e obter os
resultados finais são fornecidos, que
significa que você pode se
concentrar apenas na programação e na uma boa estrutura
de projeto todos os recursos que
você precisa
acompanhar e obter os
resultados finais são fornecidos, o que
significa que você pode se
concentrar apenas na programação e na criação de uma boa estrutura
de projeto.
Eu cuidei
da arte para você Seu projeto
de classe será esse jogo finalizado,
totalmente polido, aprimorado e pronto para ser expandido
em uma peça de portfólio, junto com quaisquer novos recursos
que você decidir adicionar Pode haver novos
inimigos, armas, um sistema de pontuação,
o que você quiser A arquitetura será definida de forma que você possa
construir e ampliar. Por exemplo, considerei
o projeto mais ou
menos assim em alguns meses
e adicionei vários novos recursos e ativos
a um projeto estendido. O primeiro vídeo
abordará a configuração
do projeto. Estou
ansioso para ver você lá.
2. 01 — Configuração: A maioria dos projetos irreais se torna impossível de navegar
em um mês. Os ativos ficarão espalhados por toda parte, sem convenções de
nomenclatura, e você acabará passando a maior parte do tempo pesquisando em
vez de tempo pesquisando em
vez Eu criei esta série com a intenção de corrigir
isso desde o início. Ajudarei você a
criar uma
filmagem completa do zero, que cada tópico se
concentrará em fazer as coisas corretamente. Essa é uma boa estrutura,
boa nomenclatura, boa arquitetura,
habilidades que serão transferidas para qualquer projeto em
que você trabalhe Trabalharemos para
criar o jogo que você pode ver em
segundo plano aqui com
base no conteúdo oficial criado pela Epic em seu pacote de
exemplos de conteúdo. Se isso é algo que
desperta seu interesse, então vamos começar e
criar essa base Primeiro, eu recomendo
que você navegue
até o link de download
na descrição. Você verá duas
opções aqui. Nós os aprimoramos em ativos sublinhados Ele contém as
malhas e texturas de regras, caso você queira modificar alguma coisa
no Blender ou no Photoshop Em seguida, você tem que atirar
neles, iniciar o
tutorial de sublinhado, e este é o projeto
completo E esse será o
que você deseja acompanhar junto com os tópicos
que abordamos. Por padrão, isso
será fornecido como uma pasta compactada para você Portanto, você precisa ter certeza de
extrair isso em algum lugar sensato, e começar
do mesmo projeto significa
simplesmente que estamos trabalhando
com configurações idênticas, os mesmos ativos, trabalhando
na mesma escala e assim por diante, que tornará a
solução de problemas um pouco mais fácil se
você tiver problemas A primeira coisa a ver dentro da pasta extraída é
entrar na pasta do tutorial shoot them up
underscore Por padrão, o projeto está
no Unreal Engine 4.27 para máxima compatibilidade se você
quiser trabalhar com uma versão de mecanismo um pouco
mais antiga Se, como eu, você
atualizará
isso para funcionar com o
Unreal Engine five A atualização leva
cerca de 10 segundos. No Windows, você pode simplesmente
clicar com o botão direito do mouse neste
projeto dot U aqui e você tem a
opção de selecionar
a versão do Unreal Engine No menu suspenso, escolha
a versão
instalada com a qual você deseja trabalhar e clique em OK. Você está pronto para ir.
Atualmente, estou trabalhando no Linux, então vou mostrar uma abordagem
alternativa. De qualquer forma, isso é útil. Isso funcionará no Windows
e, na verdade, é uma coisa muito útil de se
saber, pois pode ajudá-lo a corrigir projetos que, de outra forma, não
seriam abertos devido a problemas como
plug-ins ausentes e problemas de plug-in. Então, para fazer isso, vou clicar com o botão
direito do mouse no projeto
dot U. Eu vou abrir o W, e você pode escolher qualquer editor de texto. Isso pode ser o código do Notepad VS. Vou trabalhar com Zed, e podemos ver aqui
no lado esquerdo que, se olharmos para a associação
Engine, ela está nos dizendo que
isso foi feito com 4.27. Nós podemos simplesmente mudar isso. Vou
trabalhar com o 5.6, que provavelmente está
desatualizado no momento que você estiver assistindo,
mas estará próximo o suficiente Feito isso, como
em qualquer editor de texto, podemos simplesmente salvar isso. Podemos fechar a janela,
e agora está pronto para começar. Para começar o projeto,
basta clicar duas vezes
no projeto dot U, e ele começará a ser
carregado em segundo plano , ou seja, no Linux Clicar duas vezes em um projeto U por padrão não
inicia o mecanismo Unreal Se você quiser esse tipo
de integração
com meu instalador personalizado do
UnrelEngine, isso fará coisas
como encontrar todas as versões
baixadas ou instaladas localmente do Unreal, adicioná-las a um lançador
automático aqui, e podemos simplesmente usar o Impress Okay,
e podemos carregar o lançador
bastante padrão
que você normalmente obteria com o que você normalmente obteria Na verdade, não é o
tópico principal do que vamos
abordar, então fornecerei um link
adicional para isso. Você pode verificar isso
na descrição abaixo. Eu fornecerei os scripts de forma
totalmente gratuita, para que você também possa
baixá-los. E isso será
mais aprofundado do que o que eu precisava fazer para colocar o
Linux em funcionamento, pronto e funcionando
perfeitamente com o motor UnRel Agora que estamos dentro do Unreal, sua interface pode parecer um
pouco diferente
da minha , dependendo da versão com a qual
você decidiu trabalhar A Epic tende a reorganizar as coisas aproximadamente toda vez que alguém
fica um pouco entediado Mas podemos nos
concentrar apenas nos conceitos, não nos botões
e nos locais exatos. Eles definitivamente existirão e você estará pronto e
funcionando com rapidez suficiente. A primeira coisa a
verificar é o navegador de
conteúdo ou
a gaveta de conteúdo, que está no canto inferior
esquerdo É aqui que reside tudo
em seu projeto. Podemos clicar aqui e
ver a estrutura do nosso projeto. Dentro da pasta de conteúdo, há uma subpasta que
corresponde ao nome do projeto,
que é o tutorial Shoot them up
underscore, e essa é a convenção de nomenclatura
recomendada pela Epic para projetos e estruturas Dentro disso, temos uma pasta de
ativos que contém coisas como nossas malhas,
texturas e Temos uma pasta de diagramas
para nosso código e lógica, e temos uma
pasta de mapas para nossos níveis Essa é uma estrutura simples, mas pode ser dimensionada para
qualquer tamanho de projeto. A outra coisa que você pode notar navegar por algumas das pastas são coisas como
as convenções de nomenclatura
que foram escolhidas Temos coisas como MM
underscore texture, que significa material
mestre Em seguida, temos o sublinhado MI, seja qual for a finalidade do material, e essa é uma instância material Se usarmos as texturas,
teremos coisas como nosso herói de avião T underscore,
que é T para Acho que o lugar de onde todas essas convenções de nomenclatura não são aleatórias Tudo isso é
baseado no estilo AA. Se quiser pesquisar isso no Google,
você pode encontrar isso aqui, então podemos simplesmente
pesquisar o Guia de Estilo e estamos
procurando a página do Github, a primeira aqui Um link para isso também estará na
descrição abaixo. Nomear coisas é
supostamente um dos problemas
mais difíceis
da ciência da computação, e isso resolve um
desses Eu recomendaria marcar
isso como referência. E então, sempre que você estiver
criando um novo tipo de ativo, se não tiver certeza de como
chamá-lo, verifique aqui
e, por meio da repetição,
isso se tornará automatizado No entanto, é um
recurso muito bom. Ele fornece praticamente
tudo o que você poderia desejar. Você não precisa se lembrar de
tudo de uma vez. Há muitas
coisas aqui. Mas se analisarmos as convenções
gerais de nomenclatura, temos coisas como
malhas esqueléticas, que seriam O material para Bob
seria M nscore Bob, textura para Bob seria T
underscore Bob e assim por diante Se você observar as plantas,
temos coisas como o sublinhado do BP
e, em seguida, também podemos verificar coisas como a estrutura de arquivos e
pastas Então, exatamente como
mencionei aqui, o nome do projeto
e, em seguida, todas as pastas em uma configuração
um tanto lógica e
significativa. Então, essa é realmente a essência de como estruturar
seus projetos, como manter as coisas arrumadas e
como se organizar à medida que avança Para começar, precisamos de um nível
principal para trabalhar com ele. Antes de me aprofundar
nisso,
quero fazer algo e apresentar a
você apenas para facilitar a visualização da minha tela, mas isso também pode ser útil para
você conhecer. Então, vou até as configurações de
edição aqui na parte superior
da tela e
vou para as preferências do editor. É aqui que podemos
alterar diferentes recursos sobre como o editor
é apresentado, os atalhos, as combinações de teclas e coisas assim podem
ser encontradas O que eu
quero mudar é a escala do aplicativo aqui. Vou apenas
mudar isso para 1,25. Isso ocorre simplesmente porque
eu tenho
uma tela bem grande configurada, então ela pode parecer um pouco
esticada e os botões podem parecer um pouco pequenos
para você acompanhar Então, como eu disse,
isso é opcional, mas é útil
saber que isso existe. E há muitas outras
coisas que você pode fazer dentro das
preferências do editor para ajustar a aparência geral do seu editor, caso algo não esteja certo para
você trabalhar No entanto, isso salva automaticamente, então vou fechar
a janela e
agora podemos começar a criar
nosso primeiro nível. Isso é bom e simples. Podemos ir para o lado
superior esquerdo. Temos nosso botão de arquivo e temos a opção
aqui de criar um novo nível. Uma coisa a observar são
os atalhos. Podemos ver todas as teclas
de atalho. Novos níveis são algo com que
costumamos jogar bastante. Portanto, talvez
valha a pena lembrar desde o início para
economizar um pouco de tempo Dentro da nova janela, vamos
selecionar apenas o nível básico, não o mundo aberto. Isso vai ser muito complexo para o que
precisamos agora. E também leva mais tempo para carregar no editor toda
vez que você inicia o backup. Então, clicaremos duas vezes em Básico e agora estamos dentro do
nosso novo nível básico. Então, vamos nos certificar de que também
salvamos isso
corretamente. Por padrão, isso é
chamado de Sem título, o que significa que ainda não o
salvamos. Isso não está armazenado. Se fecharmos o projeto e
voltarmos , perderemos nosso progresso. Então, vamos pressionar
Control em S dentro
da janela de visualização aqui,
Controlando S para salvar Vamos descer até a pasta do tutorial do Shootm up, ir até a pasta Maps e
chamá-la de principal Podemos dar o nome
aqui embaixo. Pressione Salvar ou Enter, e
isso será salvo automaticamente. Dentro da gaveta de conteúdo, podemos acessar nossa pasta Mapas e ver que nosso
mapa está aqui Uma coisa rápida de se observar. UnRel usa o mapa de palavras e o nível de forma
intercambiável A mesma coisa, dois nomes diferentes ,
porque é claro que sim. Podemos ver que aqui, na
verdade, isso é chamado de nível, mas quando
usarmos isso posteriormente, Unreal solicitará que definamos
um mapa específico Outra coisa a ser observada e com a qual
trabalharemos com bastante frequência é a gaveta de
conteúdo Então, em vez de pressionar constantemente
o botão aqui
no canto inferior
esquerdo,
podemos pressionar Control no espaço,
e isso fará com que a gaveta de
conteúdo se abra e feche constantemente
o botão aqui
no canto inferior
esquerdo, podemos pressionar Control no espaço, e isso fará com que a gaveta de
conteúdo se abra e feche E essa parte é
muito importante. É aqui que os iniciantes
sempre perdem o trabalho, ou pelo menos
acham que sim, até voltarem e buscarem ajuda. Sem essa etapa, você fechará seu projeto, o reabrirá e se verá
olhando para um mapa-múndi vazio aberto ou algo
que não esperava Seu rótulo principal ainda
existe, mas o Unreal não sabe que
deveria ser aberto por padrão Então, para mudar esse
comportamento,
vamos para as configurações do
projeto. Vamos editar e
depois as configurações do projeto. No lado esquerdo,
na categoria superior, queremos encontrar a opção de
mapas e modos. E então, no lado direito, você vê o mapa de inicialização do editor. Altere essa lista suspensa do modelo padrão para nosso
mapa principal que acabamos de criar, e isso informa ao mecanismo
Unrel qual nível abrir quando você inicia o projeto
pela primeira vez Também podemos definir
o mapa padrão do jogo aqui como principal. Isso determina o que
o jogador vê se você realmente empacotar o jogo e entregá-lo a
outra pessoa para jogar. Todas essas configurações são salvas automaticamente,
para que possamos fechá-las. Podemos reabrir o projeto, e isso significa que
você retornará exatamente onde parou,
desde que tenha a
chance de salvar o
mapa em que está trabalhando Portanto, isso pode parecer muito trabalho
extra e muita conversa
apenas para o primeiro tópico. Mas esses fundamentos
realmente se compõem. Um projeto organizado permanecerá gerenciável em
10 horas de trabalho, 100 horas e até 1.000 horas, enquanto um
projeto confuso simplesmente não E esse é realmente
o objetivo e o foco de toda essa abordagem
baseada em projetos. As coisas podem demorar um
pouco mais, mas, no final, você entenderá
o que está fazendo e com sorte, eliminará
algumas boas práticas e tornará seus
projetos futuros muito mais intuitivos e
fáceis de trabalhar Mas com isso dito, as
bases estão bem definidas. A estrutura do projeto, a
convenção de nomenclatura e as configurações estão todas
configuradas corretamente. O próximo tópico será
criar nosso peão de jogador, que é algo que você
pode realmente controlar E, como já mencionei,
quero que você
realmente aprenda o que está
fazendo à medida que avança Uma das melhores
maneiras de aprender
não é seguir o passo a passo. Quando você sentir que
entendeu alguma coisa, tente ampliá-la Mesmo para algo
tão simples quanto
fizemos agora, adicione suas próprias pastas, renomeie algumas coisas e
prove para si mesmo que você entende o
padrão, não apenas as etapas vou orientá-lo
sobre isso durante todo De qualquer forma, vou orientá-lo
sobre isso durante todo
o curso do que
estamos fazendo, mas não há muito que eu possa fazer, e muito do trabalho
virá do autoaprendizado Se você fizer alterações
que funcionem bem, coloque-as nos comentários
e discussões abaixo. E se você acha que entendeu alguma coisa e vê alguém postando uma pergunta
que
você acha que pode responder,
tente responder Explicar algo
que você acabou de aprender é uma das maneiras mais rápidas
e melhores realmente bloquear as
novas informações e garantir que você não as
esqueça no futuro
3. 02 — PlayerPawn: Os projetos agora estão configurados e
precisamos de algo para realmente
começar a controlar. No final deste
tópico, teremos um peão de jogador com vigílias.
Ainda não vai se mover. Isso virá a seguir, mas
entenderemos exatamente como e por que o Unreal
decide gerar coisas e onde Uma das principais coisas no
desenvolvimento é planejar com antecedência e realmente pensar
sobre qual é sua meta
atual e
como alcançá-la. Então, simplesmente,
pelos vídeos, sabemos que queremos
controlar esse pequeno personagem em
um pequeno avião azul, para garantir que ninguém
fique para trás. Se você é completamente
novo em tudo, não
quero usar jargões
completos. Então, vou mostrar algumas coisas
realmente básicas. O plano que estamos vendo é algo chamado
malha estática. Então, se formos para as malhas de
ativos, podemos ver aqui que essa
é uma malha estática do nosso pequeno personagem
no plano azul Então, queremos
controlar isso. Se colocarmos isso
diretamente no nível, não
conseguiríamos
controlar uma malha estática Precisamos fazer esse
código baseado em código e usar um tipo de classe de blueprint no mínimo,
para fazer isso funcionar Dentro do Unreal, isso é
chamado de peão, algo que podemos
possuir ou controlar,
essencialmente, apenas um tipo
especial de ator Então, vamos criar nosso peão corretamente com nossa boa estrutura de
pastas Então, vou entrar em
nossa pasta Blueprints. Dentro daqui, queremos
criar uma nova pasta. Podemos clicar com o botão direito do mouse e
pesquisar a nova opção de pasta aqui. Costumo usar o
atalho
Control Shift e N para criar uma nova
pasta lá. Então N para novo. Vou renomear
essa pasta para CR. Essa será nossa principal
mecânica de jogo ou recursos de jogo E então, dentro dessa
grande estrutura de pastas, se clicarmos com o botão direito do mouse, queremos ir até a opção de
classe de blueprint aqui, e isso nos permitirá
criar um novo blueprint, e podemos ver uma variedade de opções
diferentes E é aqui que
entender a hierarquia de
classes da Unreal pode começar a ajudar Resumindo, tudo dentro do UnRel herda de
algo chamado objeto Esse é apenas um contêiner de dados, a classe mais simplificada à
qual temos acesso. Muitas vezes, então, vemos
algo chamado ator. Tudo no
nível no momento está na raiz de uma classe de ator. Teremos atores de malha estática, atores de
câmera, atores leves, mas todos eles são
atores em sua raiz. Adiciona uma presença física
sobre os dados do objeto, que é uma localização,
rotação e escala chamadas
de transformação. E então, os peões com os quais
trabalharemos são apenas um ator com a
funcionalidade necessária. Você verá em alguns tutoriais
que, em vez disso, eles usarão algo chamado classe de personagem,
e isso seria
um exagero para o que pretendemos fazer
com essa filmagem Os personagens incluem coisas como mecânica de
caminhada, gravidade, colisão de
cápsulas,
coisas realmente projetadas para personagens humanóides andando a
pé Vamos
fazer uma nave espacial, então realmente não
precisamos de nada E isso vem com
muitas despesas extras que precisaríamos para trabalhar ativamente Então, você pode ver outros tutoriais
criando coisas como um controlador de tanque usando
uma classe de personagem, e é aqui que
estar ciente de coisas assim permitiria que
você considerasse
que essa pode não ser a melhor solução para o que
você está tentando Como os peões são um ator ou tipo de classe
muito
usado , podemos ver que isso está
aqui na seção comum, então podemos clicar aqui e
isso criará uma nova classe de
peões para E queremos chamar isso de base de peões de sublinhado de
BP, porque essa será
a classe base para qualquer classe relacionada a peões que
criarmos no futuro, permitindo também reutilizar parte da lógica de
nossos inimigos,
nomeando-a pelo que
ela é em geral,
não apenas pelo que ela deveria
fazer antes de tudo,
que funcionará como nomeando-a pelo que
ela é em geral, não apenas pelo que ela deveria
fazer antes de tudo, classe de jogador Antes de prosseguirmos,
outra solução rápida à parte, rápida e de qualidade de vida. UnrelEngine tem algumas opiniões
fortes sobre o gerenciamento de janelas
e, na maioria das vezes, elas estão erradas Então, para corrigir uma das coisas
que estão prestes a acontecer, se clicarmos duas vezes para
abrir nossa planta agora, isso criará
uma janela flutuante praticamente
em qualquer lugar da tela Isso pode ser muito chato. Isso significa que
o Windows pode se perder atrás de outros aplicativos
e coisas assim. Então, se voltarmos para editar
e depois para as preferências do editor. Mesmo lugar que
mostrei anteriormente, onde mudei a escala do aplicativo. Como mencionei,
podemos fazer muitas correções e mudanças na qualidade
de vida. Eu quero descobrir que está no local aberto do editor de
ativos. Queremos mudar
isso do padrão, que está aberto em qualquer lugar, e vamos mudar
isso para a janela principal. Você pode experimentar
coisas diferentes e ver o que pode funcionar melhor para você. Eu gosto
bastante da janela principal. É como trabalhar
em um navegador da web, então, onde cada novo arquivo,
planta, ativo, seja o que
for com o qual você está trabalhando Sempre que você abre uma nova janela, ela cria uma nova guia
e a encaixa como
marcadores na parte superior Então, novamente, isso é
salvo automaticamente, podemos fechá-lo, voltar para a gaveta de conteúdo e clicar duas vezes novamente
para abrir a base da panela Você pode ver que isso se abre aqui, que é exatamente o que eu queria. Se você fez o mesmo que eu, onde você pode ter
aberto isso duas vezes, você pode ser recebido com essa visualização
simplificada somente de dados E isso está perfeitamente bem.
Não precisamos entrar em pânico. Esses são todos os detalhes da aula apresentados a nós essencialmente
em texto ou em formato suspenso. Para voltar ao editor de plantas
completo, queremos apenas essa linha
azul de textura, o editor de quatro plantas abertas, e isso nos levará de volta
para onde queremos estar Ok, então há muitas informações que eu poderia
fornecer agora, mas você provavelmente
esqueceria a maior parte delas. Então, vamos adotar uma forma
mais orgânica e natural de aprender o motor irreal Vamos apenas
trabalhar com novos recursos, e eu os apresentarei à medida que
avançarmos e à medida
que se tornarem relevantes. A primeira coisa que podemos
ver no momento é que estamos no gráfico de eventos
nesta guia aqui. É aqui que
colocamos nossa lógica e código. Nós vamos
voltar aqui mais tarde. Por enquanto, se clicarmos no
ponto de vista, é algo semelhante em
que podemos dar uma olhada e ver como será a aparência de nossa
classe de blueprint As classes de blueprint normalmente são compostas por componentes diferentes, cada um com seus próprios
recursos e funcionalidades No lado esquerdo, podemos
ver o painel de componentes e queremos adicionar nossa
representação visual ,
essa malha estática. Então, se pressionarmos ad e pesquisarmos por malha estática, podemos
ver isso aqui. Essa será
a primeira parte
do quebra-cabeça que estamos
tentando resolver. Com a malha estática selecionada, no
lado direito da janela, podemos ver nosso painel de detalhes. Isso nos diz tudo sobre o componente que selecionamos
atualmente. Podemos ver que temos uma lista suspensa
aqui para a malha estática, e essa é a representação
visual que queremos definir. Sabemos que queremos que esse
seja o avião azul, então encontraremos o herói do avião
e selecionaremos aquele. Dentro desse visor, estou apenas usando a roda do mouse
para rolar para dentro e para fora. Se pressionarmos Alt e
clicarmos com o botão esquerdo, podemos arrastar
e ver o modelo, e se pressionarmos o botão direito do mouse
e
arrastarmos o mouse, podemos mudar o que estamos vendo. Clique com o botão do meio do mouse e mova Will Dolly ou Pan,
acho que está chamando E esse é o
básico para
navegar por
esse visor e
também pela janela de navegar por
esse visor e
também pela visão mundial mais tarde, quando chegarmos à construção de
níveis e Outra coisa que é útil
saber é que se você pressionar F quando tiver algo
selecionado, você se concentra. Então isso é F para foco. Agora, o que acabamos de
criar é nossa malha estática, e podemos ver
no painel de componentes que
temos algo chamado raiz
de cena padrão. Isso mostra a estrutura do
ator, e todo ator precisa de
pelo menos uma raiz de cena padrão, um ponto no espaço onde todo
o resto esteja conectado. A raiz de cena padrão que
temos é apenas um espaço reservado, para que possamos pegar nossa malha estática e arrastá-la até a
raiz da
cena padrão e soltá-la raiz da
cena padrão e soltá-la Então, perna esquerda e agora criamos nossa malha estática, o que é chamado de componente raiz, ou
seja, o elemento básico de nossa classe de
jogador ou nosso peão Outra coisa: quando
chegamos a um estágio que achamos que estamos muito
satisfeitos com o progresso, precisamos ter certeza de que
adquirimos o bom hábito de clicar em compilar e salvar Isso apenas garante
que, se alguma coisa falhar,
não percamos nosso trabalho E, ao compilar, apenas verificamos se
há erros e
detectamos os erros mais cedo Então, agora temos nosso
peão com imagens. Mas é claro que
, se
pressionarmos play, ainda não veremos
isso porque ainda não
dissemos ao Unreal Engine que o usasse E podemos usar algumas entradas padrão de jogo em
primeira pessoa aqui. Então, WAS e D
levarão você por aí. Q e E o
moverão para cima e para baixo
e, claro, o
mouse olhará ao redor. Mas, é claro, essa não é exatamente a funcionalidade que
estamos procurando. Então, no próximo tópico,
corrigiremos isso
examinando a estrutura de jogabilidade do Unreal
Engine Diremos ao motor
Unreal exatamente o que gerar e onde
queremos que ele apareça Mais uma vez, se você estiver
experimentando sozinho, o que eu sempre recomendo, tente adicionar outros componentes
à classe peão Algo tão simples
quanto uma luz pontual, um sistema de partículas padrão, só para ver o que
acontece quando você anexa coisas a diferentes
partes da hierarquia Esse tipo de experimentação é, na verdade, como você fará com que
essas coisas grudem
4. 03 — estrutura de jogo: Com o peão construído,
pressionamos play
e já vimos
que, no modo de jogo, acabamos voando em
torno do que é chamado peão padrão. Então,
precisamos mudar isso. Unreal spawns vem por padrão e ignorou completamente a
classe que criamos Para corrigir isso corretamente, precisamos realmente entender como
a estrutura de
jogo da Unreal
decide o que gerar,
onde, e então podemos dizer a
ela o que fazer em vez disso Então, para começar, uma pequena visão geral
do conceito,
mais uma vez, deixe-me mostrar o que realmente está acontecendo nos
bastidores. Em primeiro lugar,
vou voltar para a janela principal e pressionar play. Dentro do Playode, é
aqui que podemos voar. Algo que é realmente
útil saber é que você pode pressionar F oito para ejetar do jogo Então, eu ainda estou no modo de jogo. Mas eu não estou mais controlando
a pornografia padrão. Agora estou basicamente de
volta ao
modo editor para poder usar WAS e D, clicar com o botão
esquerdo do mouse para dar uma olhada e ver o que
está acontecendo durante o jogo. Se olharmos para o
contorno no lado direito, podemos ver algo
chamado pornografia padrão zero Isso é o que realmente
estamos controlando no nível. E, de fato, tudo
destacado em amarelo aqui foi gerado pela estrutura de jogabilidade UnrelEngine Não colocamos nenhum
desses no nível. Então, quando pressionamos Play, o UnRel
segue uma cadeia específica. Primeiro, ele
verificará um modo de jogo
e, se você não tiver definido um
, usará uma opção padrão. O modo de jogo então
decidirá qual peão gerar. E, novamente, se você
não especificou um, ele usa o padrão, que é literalmente
chamado de peão padrão E isso é atualmente o que
estamos controlando em vez de nosso avião, porque nunca
dissemos à Unreal
que usasse essa classe de avião Então, vamos pressionar Escape
para sair do Modo Play e podemos começar a assumir o
controle do nosso projeto. De volta à pasta principal. Então, se você não está realmente
aqui, os blueprints estão dentro da gaveta de
conteúdo, queremos criar uma
nova classe Blueprint Da mesma forma que antes, clique com o botão direito do mouse e vá para a classe Blueprint E desta vez, queremos criar uma base de modo de jogo única. Vou dar a este o nome de
base do BP Underscore Game Mode. E um modo de jogo é essencialmente algo que podemos considerar como um detentor
de regras. Ele diz ao NRLEngine quais
classes usar para tudo, qual pan gerar, qual
controlador usar, qual Hud exibir Se clicarmos duas vezes para
abrir nosso modo de jogo, podemos ver que isso
parece um projeto normal Poderíamos entrar na seção Gráfico de
eventos de código se quiséssemos, mas tudo o que
queremos está,
na verdade ,
no lado direito do painel de detalhes. Podemos ver aqui as
coisas que acabei de mencionar, o tipo de
controlador Hud padrão , está tudo
exposto aqui O que estamos
procurando é nossa
aula de pornografia padrão aqui. Podemos
derrubar isso e mudar isso para a base pornográfica do BP Underscore Isso é praticamente tudo o que
precisamos fazer aqui. Podemos clicar em
Compilar e salvar para garantir que tudo
isso seja atualizado E podemos realmente sair
do modo de jogo por enquanto. Vou manter isso aberto para dar um pequeno exemplo visual de
algo em apenas um momento, mas isso é
praticamente tudo o que precisamos
fazer dentro do nosso modo de jogo. Como era de se esperar, apenas criar o
modo de jogo não é suficiente. Agora precisamos dizer
ao projeto que realmente
faça uso dele. Então, se voltarmos para a opção de edição no
canto superior esquerdo, iremos para as configurações
do projeto novamente. E, na verdade, estamos
relembrando onde estávamos anteriormente, na seção de mapas
e modos. Você pode ver no lado
direito, temos o modo
de jogo padrão chamado base
do Modo de Jogo. E se deixarmos isso aqui, podemos realmente ver
o que ele estava usando. Então, estava usando uma classe Hod
padrão,
a classe de peão padrão, a coisa que literalmente nos
vimos voando, o controlador do jogador
por padrão e assim por diante Não podemos
alterá-los, e é por isso que precisávamos de uma
classe personalizada para trabalhar. Se derrubarmos essa opção, podemos alterá-la para a base do Modo de Jogo com
sublinhado BP Podemos ver que isso agora está liberado. E o importante
é que agora mudou essa para ser nossa base de peões de
sublinhados da BP A única coisa que eu queria te
mostrar rapidamente é que, se eu mudar isso aqui,
eu poderia descartar este. Vou mudar isso para algo
completamente único. Mudamos isso para
o personagem Arc Vz. Na verdade, podemos ver que
a classe do modo de jogo que criamos
em segundo plano, então nossa base do modo de jogo BP
Underscore foi atualizada em segundo plano
para ser Arc Vz Se clicarmos
aqui e mudarmos esta volta para a base de peões de
sublinhado da BP, eu só queria
destacar que eles estão completamente Então, se mudarmos alguma coisa
aqui, isso será atualizado em nossa classe Blueprint E se mudarmos alguma coisa
em nossa classe Blueprint, isso mudará nas configurações do
nosso projeto se a tivermos conectada
aqui Feito isso, podemos
fechar as configurações do projeto, certificar-se de compilar
e salvar o modo de jogo Se você estiver
brincando com coisas, volte para o nível principal, pressione play, que é O e P, o atalho para entrar no modo de jogo E estamos meio que
no avião agora. Na verdade, estamos
literalmente no avião. Então, outro problema para resolver,
mas estamos chegando mais perto. Se você estava colocando as coisas manualmente mais cedo, se estiver
brincando com coisas, você pode ter outros aviões
no nível como. Certifique-se de se livrar deles apenas para que
não haja confusão, mas podemos
ver o que está acontecendo. Pressionamos play,
entramos no modo play
e, se eu pressionar F
oito para pular de volta, você pode ver que agora ele realmente gerou um avião
para controlarmos O principal problema é que
estamos dentro dela. Eu só queria destacar
outra coisa que está acontecendo com a estrutura de
jogabilidade, que é o uso
do nosso player start. Então você pode ver
isso aqui mesmo no nível. E no esboço, podemos ver é chamado aqui
de player Isso é o que a estrutura
procurará para confirmar onde você
deseja realmente gerar o peão que
deseja controlar Então, se eu mover isso para
algum lugar muito distante, eu movo isso até
o espaço aberto aqui. Se eu pressionar play,
ainda estamos gerando o avião, mas agora estamos surgindo ao
ar Então, novamente, algo
útil para saber. Se não tivermos um
desses, podemos excluí-los, mas o Unreal agora precisa
adivinhar onde queremos
gerar nossa coisa E não é realmente uma
suposição apenas para mostrar o que acontece
com esse cenário Se eu me mover no visor,
estou novamente usando o botão direito do
mouse para olhar ao redor e depois W AS e D para voar
com base em onde estou olhando Se eu pressionar play, podemos ver que o avião agora
vai aparecer na última posição em que minha
câmera estava no visor Então, novamente, algo que
acabei de ver novos desenvolvedores porque pode não estar muito claro o que o
jogador Start estava fazendo, especialmente se você estiver trabalhando em um projeto em que você pode
ter algo como um personagem de terceira pessoa ou um
personagem de primeira pessoa com gravidade, você trabalhará
no nível, algumas coisas,
pressionará play, e então você
cairá repentinamente no espaço, evitando
completamente o nível e ficará um pouco confuso. E isso é só porque
você provavelmente se
livrou da sua largada de jogador. Unreal não sabia onde
gerar seu personagem padrão, então escolheu o último lugar em
que você esteve no editor Se você
acompanhou até aqui, podemos acessar o
botão Adicionar na parte superior. Podemos procurar um
jogador começando aqui mesmo, e podemos simplesmente colocar um
deles de volta no nível. Calma e calma, estamos de
volta onde estávamos. Então, isso só deixa
um problema : estamos procurando
no lugar errado. Isso significa apenas que
precisamos de uma câmera e precisamos dizer ao Unreal
qual usar Para fazer isso, precisamos voltar
à pornográfica
da BP underscore Se você realmente não
tem isso aberto, lembre-se disso na gaveta de conteúdo,
então controle
o espaço e
clique duas vezes na classe base pornográfica Como mencionei, a maioria das
classes é
composta apenas por várias quantidades
de componentes, cada componente tentando preencher uma função ou caso de uso específico. Nesse caso, queremos que
um componente
de câmera veja nossa correspondência estática. Antes de adicionarmos uma câmera,
vou adicionar algo chamado Spring Arm apenas
para apresentá-las. Então, se pressionarmos o anúncio aqui, podemos pesquisar por Spring Farm.
Clicaremos para adicionar isso. E isso é basicamente
um bastão que
manterá a câmera a
uma distância fixa. Ele também pode lidar com
coisas como colisão, empurrar a câmera para
mais perto quando
batemos em paredes e
tentar evitar Não precisaremos desse nível de
complexidade para nosso jogo, mas é útil saber
que esses recursos existem. Outro uso muito útil
do braço de mola é que ele evita que precisemos
afetar diretamente o deslocamento, a posição e
a
rotação Então, vamos mantê-lo
apenas por esses motivos. Com o braço de mola
ainda selecionado, voltaremos
ao botão Adicionar. Vamos
procurar uma câmera. E queremos selecionar a câmera
padrão aqui na parte superior. Você pode ver que isso
é colocado apenas
na câmera no final
da primavera. Isso nos dá um
pouco de tempo para focar no Unreal Engine e na maneira como
ele trata a hierarquia Já vimos o fato
de que
a malha estática agora é
classificada como a raiz da costura Portanto, onde quer que a raiz da costura vá, todo
o resto
segue, incluindo rotação, localização e escala A primavera é então
classificada como filha da malha estática, e a câmera é
filha da primavera Então, o que isso significa é que se eu pegar o componente spring um e depois mudar alguma coisa
na rotação, por exemplo, eu sei que
quero que a câmera olhe
90 graus para baixo
na malha estática. Isso será -90 graus. Podemos ver que a
câmera herda rotação
que
dei à mola. Eu faço a mola um pouco maior, então vou
bloquear o local, e vou fazer com que seja
do tamanho de dez, podemos ver que a câmera
também fica dez vezes maior. Agora, não escalamos a câmera
e a câmera dessa forma, mas eu só queria
mostrar como a hierarquia funciona dentro do irreal
com os componentes No entanto, queremos a
rotação da câmera, então eu recomendo uma rotação
de algo como -90, para que a câmera fique voltada diretamente para o player Se pressionarmos play, podemos
ver como isso ficará. Então, talvez um pouco perto demais, pode ser um pouco
difícil ver o que está acontecendo
com os inimigos
e os projéteis durante o jogo O zumbido da primavera tem
outro recurso, que nos ajudará com isso É chamado de comprimento do braço
alvo, e você pode ver isso novamente
no painel de detalhes. Então, como mencionei,
com a malha estática, quando temos
algo selecionado, o painel de detalhes é apenas todas
as informações sobre os componentes que você
selecionou atualmente. O zumbido da primavera tem
esse valor chamado comprimento do braço
alvo,
que é essa linha vermelha, e podemos definir isso para
algo como 1.200, e isso seria aproximadamente
onde queremos Assim, podemos pressionar
Play e ver que podemos ver um pouco
mais da tela. voltaremos e refinaremos qualquer forma,
voltaremos e refinaremos
coisas assim um
pouco mais tarde Mas, por enquanto, tudo
ficará perfeitamente bem. Mais uma vez, quando você fizer
alterações com as quais está satisfeito, certifique-se de clicar em
Salvar, e isso se parece um pouco mais
com um jogo de tiro de cima para baixo Então, se você está
acompanhando e prestando atenção, agora
vimos que,
se não dissermos ao motor Unreal
qual mapa usar, ele usa um mapa um tanto aleatório Se não dissermos
qual modo de jogo usar, ele usa um modo de jogo padrão. E se você não disser
qual peão usar, ele usa um peão padrão Mas você provavelmente
notou que não
dissemos qual câmera usar, mas ela sabe usar a
câmera que acabamos de adicionar. Então, isso meio que quebra regra que
venho destacando Neste trabalho, porém, tudo ainda
se resume ao comportamento da
estrutura de jogo. Quando a estrutura possuir um peão
pela primeira vez, ela examinará dentro
dessa classe e verificará se há algum componente
da câmera Estou simplificando
isso um pouco, mas é essencialmente o
processo que é realizado Se encontrar uma câmera,
ela será usada por padrão. Se ele não encontrar uma
câmera em sua hierarquia
, ele criará
uma câmera padrão, e a posição em que a coloca
é zero,
que, no nosso caso, está diretamente dentro
da malha plana, é por isso
que estávamos
olhando para o interior do corpo Então, novamente, agora podemos ver por que estávamos olhando para o interior
do avião e como
substituímos isso para agora olhar para
baixo no No entanto, o mesmo tipo de padrão de
todo o resto. A estrutura tem seus processos
padrão, e o importante é que agora
estamos mais conscientes de que temos a
opção de
substituí-los ou conviver com eles. Feito isso, agora
controlamos o que aparece, onde aparece e por qual
câmera olhamos A estrutura está trabalhando para
nós em vez de contra nós. E, novamente, você pode
se surpreender com quantas pessoas
acabam trabalhando contra a estrutura
por um bom tempo. Outra coisa com a qual me familiarizei
bastante quando os alunos simplesmente mergulham de
cabeça nos projetos Quando eu puder
ver o projeto,
depois de trabalharem
nele por um tempo ,
eles terão soluções alternativas para eles terão soluções alternativas para visualizar por meio de câmeras
específicas forçando os peões a serem
acionados em determinados pontos, basicamente
separando a estrutura e combatendo-a em vez Sempre que possível, podemos usar muitos desses princípios básicos de estrutura
e, na verdade, eles nos ajudam
mais do que nos atrapalham Claro, ainda
não temos movimento. Atualmente, temos apenas um peão sentado lá e uma
câmera para olhar para ele Então essa seria a próxima
coisa, adicionar movimento. Na verdade, vou mostrar
a maneira
errada de adicionar movimento primeiro ,
porque é o que você verá em muitos tutoriais diferentes Depois de vermos isso,
mostrarei como
resolver esses problemas, para que você
saiba o que procurar. Se você quiser experimentar novamente, a pequena recomendação, embora ainda estejamos muito cedo
nos tópicos, seria tentar ajustar
a distância ou o ângulo da
câmera, talvez opte por uma configuração um pouco
diferente para o ângulo em que você está
olhando para o avião Pode adicionar uma segunda câmera e ver o que acontece. Qual
deles ele escolhe? E se você estiver fazendo coisas
assim, comece a
tentar descrever o que você está percebendo que
a estrutura está fazendo, o que ela está fazendo e o que
você não espera, ou o que você está
entendendo sobre isso
5. 04 — LegacyInput: Antes que o jogador
possa se mover, o Unreal precisa saber o que
os jogadores estão pressionando Isso pode ser teclas do teclado,
controles, gatilhos. Tudo isso flui
pelo sistema de entrada. Unre pega essas ligações e as converte em valores de entrada, e lemos isso para Portanto, o primeiro passo
será entender como esses valores realmente funcionam. Para começar,
faremos isso por meio sistema de entrada antigo,
que é meio antigo. Para encontrá-los,
queremos voltar
às configurações do nosso projeto. Então, vamos subir para
editar e projetar as configurações. Vamos descer um
pouco mais
do que antes. E podemos ver aqui que
temos a seção de entrada. Como mencionei, isso
é meio antiquado,
e há até mesmo um
aviso aqui sobre o sistema de entrada legado sendo descontinuado.
Isso é bom. Ainda é útil saber
porque é provável
que você encontre projetos
que ainda usam isso. Muitos exemplos e projetos ainda estão
usando esse sistema. Tenha dois
tipos diferentes de entrada aqui. Temos nossos
mapeamentos de ações, que são binários. Eles são
pressionados ou não, perfeitos para coisas como atirar, interagir, pular e assim por diante. Em seguida, temos nossos mapeamentos de eixos, convertem a entrada
do player
em valores contínuos de ponto
flutuante Perfeito para movimento.
Então, por esse motivo, vamos adicionar um
novo mapeamento de eixos aqui, e nomearemos esse
movimento para a direita. Como temos
esse valor de escala aqui que podemos alterar para as diferentes entradas que fornecemos, chamaremos
isso de movimento para a direita Ele também controlará o
movimento para a esquerda tornando a outra entrada
um valor negativo. Nessa lista suspensa, podemos
encontrar qualquer entrada que desejarmos. Pode ser o
teclado, o
mouse, o gamepad, seja qual for
o caso Algo que eu não
sabia por muitos anos quando estava usando o motor
unrel é isso Na verdade, é um botão.
Se clicarmos nele e
pressionarmos a tecla D, por exemplo, isso
rastreará a próxima entrada como D, e isso seria perfeito
para mover para a direita. Se pressionarmos o botão de adição,
podemos adicionar outra encadernação. Vou pressionar isso
novamente e depois pressionar A,
então agora temos nosso movimento para a
esquerda. A única coisa que
mencionei é que, por padrão, esse é
um valor positivo. Se mudarmos isso para um valor
negativo, menos um, isso permitirá que a entrada nos
mova na direção
esquerda Se você quiser
vincular chaves diferentes à mesma associação de entrada, podemos simplesmente adicionar
mais duas como exemplo Podemos adicionar um para
a seta direita e outro para a seta esquerda. Novamente, quando estamos nos movendo para a
esquerda, queremos apenas ter
certeza de adicionar o valor
negativo a esse. Sistema simples e flexível o suficiente para o que
precisamos fazer agora. Como tudo
antes, isso é
salvo automaticamente para que possamos fechar as configurações
do projeto, voltar para a gaveta de conteúdo,
usar o controle no espaço
novamente como uma recapitulação
do atalho e
voltar para a base do atalho e
voltar para a Se você ainda estiver dentro
do visor, vamos querer passar para
a guia
do gráfico de eventos agora Então, aquela que
eu mencionei, é aqui que nossa lógica
vai seguir, e é isso que
faremos imediatamente Aqui, podemos ver alguns nós diferentes que
já estão no gráfico,
e eu estou clicando com o botão direito do mouse
e arrastando para me mover Primeiro, podemos ver que temos
nosso modo de início de jogo, e isso acontece apenas uma vez
quando pressionamos Iniciar Abaixo, temos nossa
marca de evento na parte inferior, e esse evento é acionado continuamente enquanto
o jogo está em execução. Você pode ouvir pessoas
dizerem coisas como
evitamos usar o marcador de
eventos a todo custo, mas isso
simplifica um pouco Para funcionalidades como movimento, onde
queremos que seja suave e responsivo, ou movimento de câmera, física, coisas assim,
é exatamente aqui que a
lógica precisa estar Só precisamos ter
certeza de que o
mantemos limpo e eficiente. Então, finalmente, temos o ato do
evento para começar a se sobrepor. Essa é uma verificação de sobreposição,
uma verificação de colisão para toda
a turma No nosso caso, isso pode ser
qualquer coisa, desde a malha estática, o componente spring um
ou o componente da câmera. É um pouco vago, então eu costumo não usar isso e
lidaremos com as colisões por
componente posteriormente. Então, podemos pegar esse, apertar delete, e
vamos nos livrar dele. Para demonstrar o que o mapeamento de
eixos está fazendo, vamos
descer um pouco, então eu clico com o botão direito do mouse e
arrasto para mover o gráfico Deseja clicar com o botão direito aqui
e
procuraremos a ligação de entrada que
fizemos há pouco. Eu chamei o meu de Move Right. Temos duas
opções diferentes aqui. Temos o evento do eixo
e o valor do eixo. O evento criaria algo muito
parecido com o evento
fornecendo esse pino de execução para
que fornecendo esse pino de execução pudéssemos orientar a
lógica futura a partir disso A diferença com
o valor do eixo é se clicarmos neste. Isso fornece apenas
esse pino verde. Esse pino verde é um valor flutuante
ou um valor em ponto decimal, e isso fornecerá um valor dependendo do
que estamos pressionando Se não pressionarmos
nada, obtemos zero. Se pressionamos para a esquerda,
obtemos menos um, e se pressionamos para a
direita, obtemos um positivo Na verdade, posso mostrar isso em uma demonstração muito simples, e recomendo isso para qualquer pessoa que esteja aprendendo novas partes
do motor Unreal Vamos puxar
esse pino de execução aqui, arrastá-lo para o
gráfico e soltá-lo, e então vamos
procurar a palavra string de impressão. Portanto, isso apenas fornecerá uma mensagem de depuração em nossa tela, no lado esquerdo,
se pressionarmos play Então, podemos ver que
aqui está enviando spam para a janela
com a palavra Agora, para evitar que seja
enviado spam porque está sendo executado 120 vezes por segundo, queremos reduzir isso e alterar a duração
para 2 No momento, isso está sendo
impresso por 2 segundos e vamos transformar isso em zero. Isso então se torna uma impressão mais
constante por aqui, então agora é só
imprimir a palavra olá. Obviamente, não
queremos que isso diga olá. Queremos que isso nos mostre
o que está sendo pressionado. Então, vou pegar
o valor flutuante aqui, puxar desse pino e
soltá-lo na entrada O motor Unreal
é inteligente o suficiente para converter automaticamente nosso float em uma sequência de texto,
então isso é um viés legível Então, se clicarmos em compilar
e reproduzir novamente, você pode ver
que agora isso
está imprimindo zero, porque eu não estou
pressionando absolutamente nada Se eu pressionar a seta para a esquerda, ela imprime menos um,
a seta para a direita, obtenho um positivo e
o mesmo para A e D. Então, podemos ver que está funcionando. Temos
algo acontecendo aqui. Portanto, imprimir o valor
mostra os dados, mas ainda é apenas um número
, no que nos diz respeito. Então, vamos fazer algo muito rapidamente para tornar esse
efeito algo visível Ainda não vamos adicionar
movimento. Vamos chegar lá
em um tópico separado. No entanto, se retirarmos nossa string de
impressão, esse pino de execução aqui e pesquise defina a
escala At três D. Queremos esse nó aqui, e tudo o que vamos fazer
é afetar
a escala geral do nosso ator com base na
direção em que estamos pressionando. Para fazer isso, precisaremos
apenas de um pouquinho de espaço no meio. Então, estou apenas movendo alguns
nós por aqui. Vamos manter a
matemática muito, muito simples. Isso é totalmente
descartável e é apenas para visualizar partes
do conceito , podemos pegar nossa escala de
ator definida três D No entanto, podemos pegar nossa escala de
ator definida três D, e podemos controlar isso pela direção
que estamos pressionando. Então, podemos fazer a escala
do ator zero menos um ou um E se adicionarmos alguma entrada analógica, poderíamos tornar
esse valor muito simples Vamos fazer nosso movimento de
obtenção que valorizamos aqui, então vou pegar isso pressionar Control em D para duplicar E vamos simplesmente
conectar isso aqui. Então, como eu disse, muito,
muito simples. Isso não será útil
para nenhum tipo de cenário de caso de
uso real. Eu só queria que você
se familiarizasse
um pouco com um pouco de projeto
antes de mergulharmos no movimento Mas se clicarmos em compilar,
isso apenas garante que tudo tenha sido verificado quanto a erros e esteja funcionando.
Clique em salvar
para não perdermos
nada do progresso E uma coisa que acho que
vou fazer é
voltar à edição e depois às configurações
do projeto. Eu conectei meu gamepad
e, se voltarmos
para a seção de entrada, basta adicionar
uma nova entrada aqui, clicar neste botão e
moverei o controle
analógico para a esquerda Então, o manípulo analógico esquerdo, eu movi no eixo X,
que é esquerdo e direito Podemos deixar isso como um número
positivo se
quisermos inverter o movimento
analógico Então, por exemplo, se eu puxar para a
esquerda, vou para a direita. Então é por isso que talvez queiramos
adicionar um valor negativo. Mas como o analógico tem
uma amplitude de movimento completa e é inteligente o suficiente para saber tomar a
direção certa como positiva, a direção esquerda
receberá automaticamente esse valor negativo Então, podemos fechar isso.
Podemos entrar no modo de jogo Nós meio que quebramos o
avião no momento. Então, no momento, estamos
imprimindo zero na parte superior. que significa que estamos passando
o número zero para o X, Y e Z da escala do nosso plano, e é
por isso que não podemos vê-lo. Se eu pressionar A, então estamos
invertendo o tamanho, então estamos vendo a
parte inferior porque agora estamos fazendo do plano a escala
desse negativo E se eu pressionar D, estamos tornando a escala do
plano positiva um. A razão pela qual eu quero
usar o manípulo analógico é que podemos
visualizá-lo um pouco mais para que eu possa obter alguns movimentos suaves apenas
movendo o manípulo analógico Se você ver o número
no topo, isso está entre zero e menos um porque estou me
movendo para a esquerda E se eu movê-lo para a direita, vamos entre
zero e mais um. Então, apenas uma espécie de visualização
de como podemos fazer uso desses valores e encaixá-los em uma lógica
muito simples Novamente, estamos recebendo
outra conversão. Isso está tomando nossa
direção de movimento, então menos um, zero ou um, multiplicando isso por todas
essas propriedades de escala Então, as
propriedades da escala são irreais. Você tem o X, Y e Z. Só para visualizar isso em
algo simples, como um Eu vou entrar aqui só
para te mostrar isso. Se quiséssemos
alterar as propriedades ou a escala desse objeto, poderíamos pegar apenas o eixo X, e você pode ver que está
ficando mais longo. Poderíamos escalar no
eixo y para torná-lo mais largo. E, novamente, podemos mudar o eixo
z para torná-lo mais alto. Muito bom e simples, e isso é
realmente tudo o que estávamos fazendo aqui no código, mas estamos
apenas normalizando isso Então, todos eles são zero, menos um ou um,
com base na entrada Então, como eu disse, código
completamente inútil, descarte
completo, mas espero que isso torne
a entrada e a forma como
podemos utilizar esse valor um
pouco mais Feito isso, confirmamos que nossa contribuição está funcionando. A pornografia em si ainda não se move. Essa parte será
a próxima a chegar. E no próximo
vídeo, vamos transformar essa entrada em um movimento
real do jogador.
6. 05 — PlayerMovement: Mas configurado e testado, é
hora de fazer o
avião realmente se mover. Mais uma vez, ainda
faremos as coisas
da maneira errada, primeiro movimento dependente da
estrutura com uma espécie de movimento rápido,
preencha, mas funcionará E você pode estar se perguntando por que estou ensinando
conscientemente
a coisa errada Isso ocorre porque esse código exato aparecerá em muitos lugares. Isso vem dos exemplos épicos de conteúdo
oficial, que significa que você o verá
em outros tutoriais que fazem referência a
projetos mais antigos que você pode herdar,
e tenho certeza de que em
muitos Quando percebi isso,
decidi que essa seria uma oportunidade perfeita
para levar você a um ponto no final
deste vídeo em
que você verá o bug, entenderá por que isso acontece e
saberá como corrigi-lo. Então, precisamos ainda estar dentro da nossa base de peões de sublinhado da BP Na verdade, podemos nos livrar de todo o código que
temos no momento. Vamos nos livrar dessa
escala e imprimir a sequência de caracteres. Isso foi apenas para
demonstração e depuração. Para o movimento, isso
é muito simples. Só precisamos considerar isso como nossa direção de movimento. Adicionaremos algum tipo de velocidade
variável um
pouco mais tarde e queremos
compensar a localização
do nosso avião a cada toque. Podemos fazer isso
puxando do eventi,
o pino de execução aqui Vamos
pesquisar algo chamado set actor location. E esse será o
nosso nó, que está dirigindo e
controlando
diretamente para onde nos movemos. Para fazer isso funcionar, precisamos
calcular um deslocamento, levando em consideração a localização atual do
avião e, em seguida, onde queremos que ele esteja Podemos fazer isso usando
outra função embutida. Podemos clicar com o botão direito do mouse
no gráfico do evento e eu vou pesquisar
por Obter localização do ator. Se passarmos o mouse sobre elas quando as
encontrarmos também, caso você não
saiba, poderá ver dicas de
ferramentas sobre o que
essas funções fazem Então, isso retorna à localização
dos componentes raiz, que sabemos ser
nossa malha estática, essencialmente nos dizendo onde
estamos em qualquer quadro. disso,
retiraremos desse pino vetorial o pino
amarelo aqui e
procuraremos o símbolo de adição, ou você pode digitar add e
queremos o nó AD. Podemos fazer algumas matemáticas vetoriais muito
simples. Então, o que temos
aqui é que nossa
posição atual mais um deslocamento será igual a onde queremos
estar, para que possamos conectar
isso diretamente Um problema que
enfrentamos no momento é que
queremos
controlar diretamente o eixo Y. Então, quando você estiver
trabalhando com o Unreal, vou voltar
ao nível apenas para dar um exemplo
rápido aqui Quando se trata de
direções e movimentos, se você não tiver certeza de para
que lado deseja se mover, podemos simplesmente fazer algo
como pegar nossa malha Coloque isso no nível e
obteremos esse widget aqui, que nos mostrará as
direções que você pode seguir dentro do Unreal A principal coisa a ser
lembrada desde o início é que o vermelho, que é o eixo X, está
à frente no mundo. Y, que é verde, é direita e para a esquerda no
mundo ou para os lados, e Z, que é azul
, é para cima e para baixo Isso é muito útil porque Unreal Engine os codifica por
cores Então, se olharmos
no painel de detalhes à direita, podemos
ver aqui que temos X, Y e Z, e que
tem um pequeno ícone de pílula mostrando vermelho, verde e azul Temos o mesmo para
rotação e escala. E, como mencionei brevemente antes, essas três variáveis, localização, rotação e escala, são apenas uma
estrutura que compõe o trans e cada uma dessas
variáveis, como a localização, e é apenas uma estrutura de valores individuais de
ponto flutuante. No exemplo em que
mostrei que esse
projeto se baseia, o avião obviamente se move de um lado para o outro e só de um lado para o outro, como antigos invasores espaciais, e estamos tentando
recriar isso, então sabemos que precisamos nos
mover no eixo Y. Então, de volta ao nosso código, isso significa que precisamos de alguma forma
expor essa variável aqui Super simples de fazer. Podemos clicar com o botão
direito do mouse no pino amarelo e temos
a opção de dividir o pino da estrutura. E é por isso que
mencionei que elas são chamadas de estruturas. Eles vêm em muitas formas
diferentes, mas normalmente são apenas uma combinação de variáveis
diferentes, criando um tipo específico de variável com um caso de uso
diferente. Nesse caso, é a localização do movimento
tridimensional. Se dividirmos o pino da estrutura, você pode ver que isso
é revertido em seus valores individuais de ponto
flutuante, o X, o Y e o z, e já
temos nosso
movimento configurado Esse é o nosso movimento para a direita, que
podemos simplesmente conectar ao eixo Y. Então, o que estamos fazendo
agora é pegar nossa localização atual
e, a cada quadro, estamos adicionando um, zero ou menos um à direção Então, se pressionarmos play, podemos ver que agora temos algum
tipo de movimento. Então, A e D me farão
mover para a esquerda e para a direita, assim como os arokis esquerdo e direito Então, estamos um passo mais perto de
onde queremos que esteja. Agora, isso nos coloca em uma pequena situação
aqui, onde agora
temos um problema em que este é
um jogo dependente da taxa de quadros Então, vou mostrar
algumas coisas sobre
as repercussões
disso e como você pode testar e
ver isso por Então, no momento,
lembre-se de que estamos movendo uma unidade por quadro se
pressionarmos um botão. Então, se eu estiver rodando a
120 quadros por segundo, são 120 unidades por segundo. Um motor rL calcula as
unidades em centímetros. Portanto, atualmente, isso está
se movendo em
torno de 120 centímetros/segundo Agora, se eu voltar
ao modo de jogo, entrarei
na janela principal aqui e
apresentarei algo chamado comandos do console, onde podemos executar
comandos simples para testar coisas. Eu também vou me
livrar rapidamente desse avião de teste aqui. Então, de volta ao Playmode, clique no
visor para ter certeza de que você tem
controle total do E você quer
encontrar a chave Tilda. Na maioria dos teclados, isso fica
ao lado da linha de números. Se você pressionar a tecla Tilda, poderá ver um pequeno console aparecer na parte inferior
da tela aqui Vou habilitar um comando de console muito
simples, que é declarado space FPS Se eu pressionar Enter, podemos
ver o
lado direito da tela. Agora estou exibindo o número de quadros que estou executando por segundo. Vou pressionar a tecla
Tilda novamente, digitar T dot max FPS ou One Word e depois espaço, e então vou definir isso
para 30 Agora podemos ver no
lado direito que limitou meus quadros a 30
quadros por segundo Agora, considerando o que
mencionei há pouco, se a 120 quadros por segundo, eu estava movendo 120
unidades por segundo, isso agora significa que
obviamente estou me
movendo a 30 unidades por segundo. Então, estamos jogando o mesmo jogo, temos o mesmo código de
movimento, mas o movimento é
drasticamente diferente Se eu colocar isso de volta,
vou reduzir para 300. Estou rodando a cerca de 300 FPS. Podemos ver que agora estamos nos
movendo consideravelmente mais rápido porque agora estou
movendo 300 unidades por segundo Vou colocar isso de volta para 30 e
você pode ver o contraste. Agora, você provavelmente pode começar a
ver por que isso não é o ideal. E isso é o que chamamos de dependência da taxa de
quadros quando um jogo é executado especificamente
com base no hardware Assim, jogadores com
sistemas mais rápidos se moverão mais rápido e jogadores com
sistemas mais lentos se moverão mais devagar É um bug que aparece em muito
mais jogos do que você esperava. Então, antes de começarmos a
pensar em criar o que é chamado de independência da taxa de
quadros, vamos ajustar o resto do nosso código de movimento por enquanto , para que tenhamos
tudo com que trabalhar No momento, mover
apenas uma unidade por quadro obviamente
não é muito notável, então vamos querer
multiplicar nossa velocidade por um valor Podemos fazer isso com muita
facilidade. Novamente, trabalhar com matemática dentro de plantas
é relativamente simples Podemos extrair do nosso carro alegórico
aqui o que queremos multiplicar. Arraste
isso para o gráfico. Pesquise o asterisco, o símbolo de multiplicação
ou a multiplicação de tipos, e podemos inserir esse
resultado no Y. Isso significa que agora
teremos nossa direção de movimento multiplicada por uma velocidade de movimento, que podemos definir como algo
aleatório por enquanto, como dez, e esse será nosso novo deslocamento
que aplicará cada quadro que Então, agora estamos nos movendo mais rápido,
mas ainda teremos problema
de
independência da taxa de quadros em
que se eu alterar a taxa de
quadros em que estou executando, agora
estou me movendo muito mais rápido. Então, isso está se tornando
ainda mais perceptível. Eu só queria me concentrar
aqui também. O que acabei de criar aqui é o que chamamos
de número mágico. Esse número, nesse contexto, quando eu voltar a isso
em um ou dois meses, é bem provável que
você
esqueça exatamente o que esse número estava representando sem
olhar para trás no código. Eu lhe dou a pergunta,
por que isso era dez? Por que não foi 100? Por que
não foram 1.000 e assim por diante. Para aliviar isso um
pouco, e novamente, focando nessa boa
prática de programação e tentando manter nosso código organizado
desde o início Vamos extrair
esse pino verde aqui, e eu vou fazer
algo chamado promover isso para uma variável, e você pode ver a opção
aqui para promover
isso para uma variável. Então, clicaremos nisso. No lado esquerdo, é
onde as variáveis residem. Podemos pegar esse nome, e eu vou
renomeá-lo para velocidade de
movimento Então, agora, de relance,
no mínimo, isso nos dá uma ideia do
que esse valor está fazendo Então essa é a velocidade na qual
esperamos nos mover, multiplicada por uma direção sendo adicionada à nossa localização ativa Ele começa a parecer um
pouco mais como um romance em uma página, e você tem uma ideia do que
o código fará, mesmo sem
investigá-lo completamente, que é o que
queremos que nosso código faça, torne-se legível por humanos Portanto, temos nossa variável de
velocidade de movimento. Podemos clicar em compilar aqui, apenas para
verificar se o número dez está
preenchido porque
já tínhamos esse valor
como um número mágico Então, de volta ao bug da
taxa de quadros. Precisamos garantir
que, independentemente da velocidade em
que nosso
sistema esteja funcionando, obtenhamos o mesmo
tipo de movimento. Isso não é apenas para
o resultado do jogador, mas como designer,
quando estamos criando nosso jogo, estamos
ajustando tudo. Queremos que tudo seja tão
suave, reativo e responsivo
quanto esperávamos Ajustamos todo o jogo
para ser jogado de uma maneira específica. E, obviamente, isso
será completamente arruinado se alguém
que estiver jogando em um sistema duas vezes mais
rápido que o nosso obtiver um resultado
diferente O que precisamos para isso é
algo chamado de segundos Delta, às vezes chamado de Delta simplesmente o número
de segundos que passaram desde
o último quadro. Em vez de usar
esse pino aqui para nosso cálculo,
porque, é claro, ele teria fios sobrepostos
e começaria a introduzir o código de
espaguete Vamos
clicar com o botão direito do mouse no gráfico e
pesquisar os segundos Delta. Você pode ver aqui
que temos a opção obter segundos do World Delta, e podemos conectá-la
e fazer uso dela. Simplesmente,
queremos pegar todos
os valores que
temos aqui e
multiplicá-los pelos nossos segundos
Delta. Então, o mesmo de novo. Vamos pesquisar
multiplicar, inserir isso, inserir o cálculo
no resultado e chegaremos
mais perto do que queremos Agora, permita-me
demonstrar rapidamente o que segundos
Delta estão realmente fazendo e o que o
valor representa. Uma maneira muito rápida de
fazer isso. Quero colocar uma sequência de caracteres impressos,
como vimos antes. Vou definir isso como zero
para a duração,
pegar o nó de segundos Delta, duplicá-lo e conectá-lo apenas para que possamos
ver o que está sendo impresso Nos meus 300 FPS, não
vamos usar esse número, então vou limitar
isso de volta para 120 A 120 FPS, estamos obtendo
um valor em torno 0,008 segundos
entre cada quadro Se eu limitar isso de volta para 60, veremos isso
cair para 0,016 E então, se
reduzirmos isso ainda mais para 30, obteremos
um número de 0,033 Então, aproximadamente, não exatamente, mas aproximadamente metade do número cada vez que reduzimos
a taxa de quadros pela metade. E veja como isso é
útil e como corrige nossos problemas
dependentes da taxa de quadros. Se você estiver executando a 30 FPS, cada quadro o moverá ainda mais, mas essas são etapas maiores, mas você está dando menos
etapas por segundo Já a 120 FPS, cada quadro está movendo você menos Essas são
etapas menores, mas você está dando quatro
vezes mais etapas dentro delas. E o resultado final
é que a distância total por segundo permanece
praticamente a mesma. E isso é se você está
rodando a 30 FPS ou 120 FPS. Temos independência de taxa de quadros, e essa é a diferença
entre um jogo que parece justo em todos os hardwares, em comparação com pessoas experiências
diferentes em sistemas
superiores ou inferiores. Uma coisa a observar, como agora
estamos multiplicando nossos valores por esse número
incrivelmente pequeno, a velocidade em que estamos nos
movendo obviamente parecerá muito mais lenta,
muito lenta, quase muito lenta Então, precisamos entrar e considerar isso
na velocidade de movimento. Vou aumentar
isso para algo como 500 em vez
de dez, clicar em compilar e jogar,
e vai parecer
mais ou menos o mesmo O principal, novamente, é
que o que estamos vendo é um salto de 30 a 120 FBS Parece mais suave, mas não estamos visivelmente indo
mais rápido A única diferença
que estamos vendo é a suavidade
do movimento devido à taxa de
quadros que estamos vendo. Então esse é
realmente o objetivo aqui. Então, com isso, o
movimento funciona. Resolvemos o
problema da estrutura,
mas na verdade não está
bem resolvido . Podemos notar que é muito
rápido quando o movemos. Se pressionarmos uma direção, estaremos
instantaneamente a toda velocidade. Assim que lançamos,
somos interrompidos instantaneamente. Não há aceleração,
não há impulso. Veículos reais não
funcionam dessa maneira. Até mesmo nossos filhos mais
velhos terão algum peso, então precisaremos considerar adicionar aceleração suave E toda essa abordagem que
estamos adotando no momento, a localização
do ator no set. Fazendo isso, cada quadro
não tem integração física, nenhuma resposta de colisão adequada
e está perfeitamente bem É por isso que ele é fornecido
nos exemplos de conteúdo do Epics. O padrão funciona
porque é simples, não porque é a melhor prática. Então, temos movimentos.
Entendemos o bug de estrutura que
tivemos e como corrigi-lo, e sabemos por que essa abordagem é comum e por que não é ideal. Em seguida, moveremos os sites. Vamos adicionar um pouco de aceleração,
inclinação rotativa, geralmente
com o objetivo de algo que
pareça mais com uma aeronave Se você quiser
experimentar, pode sempre tentar
adicionar movimento vertical É o mesmo padrão. Basta usar o eixo diferente, o eixo X em vez
do Y, ou adicionar a ele. Provavelmente, você também precisará
introduzir uma nova vinculação
de entrada , uma pequena dica.
7. 06 — suavidade em movimento: No momento, nosso movimento funciona
tecnicamente, mas parece muito robótico Início instantâneo, parada instantânea. Abordaremos
isso neste vídeo adicionando pouco de aceleração e rotação
bancária, para que pareça que você está realmente pilotando algum tipo de aeronave
Arcade Usaremos algo
chamado interpolação, que é a suavização
entre dois pontos ao Essa também será a
próxima etapa para herdar os bugs do épico conteúdo
oficial de aprendizagem Nós o encontraremos,
reconheceremos e o corrigiremos um
pouco mais tarde. Então, agora, o problema
é que nossa velocidade está sendo
tirada diretamente da entrada. Aqui, temos o movimento para direita multiplicado
pela velocidade do movimento Então, se estivermos pressionando para a direita,
isso é um multiplicado por 500. Vamos direto para a
velocidade de 500 unidades por quadro. Se estivermos pressionando
para a esquerda, isso é menos um multiplicado por 500, então estamos fazendo com que menos 500 sejam aplicados diretamente
à nossa velocidade de movimento É por isso que obtemos esse início
instantâneo e parada instantânea. É claro que,
assim que soltamos uma tecla, multiplicamos
o valor por zero,
então vamos direto para a velocidade de movimento de
500-0 Para um movimento suave,
precisaremos de dois valores diferentes. Queremos uma velocidade alvo, que é onde queremos
estar, e precisamos nossa velocidade atual, que é
onde estamos no momento. Ou use-os para se mover
gradualmente entre nossa velocidade atual e
nossa velocidade alvo. Para começar, podemos criar
facilmente um novo flutuador ou a
velocidade atual que
vamos rastrear Podemos pegar nossa
velocidade de movimento aqui, clicar com o botão direito do mouse ou pressionar
Control em D para duplicar. Vamos chamar isso
de velocidade atual. E o que
faremos é pegar esse valor que estamos calculando
aqui, essencialmente nossa velocidade de movimento, e esse será o alvo que usaremos um pouco mais tarde Se quiséssemos arrumar isso, definitivamente
poderíamos tornar
isso mais legível visualmente Se eu mudar isso, podemos pegar esse cálculo aqui. Vou pressionar
Control em X para cortar isso, controle em V para colar acima, vamos extrair isso aqui e vamos promover isso
para uma nova variável. Vamos promovê-lo para algo que chamaremos de velocidade alvo. E podemos conectar
isso aqui. Você verá por que, em um momento, isso não está realmente mudando
nada no momento, mas tornará as coisas
um pouco mais legíveis Agora, além de
esconder as coisas para que tenhamos um pouco
mais de espaço para trabalhar, lembre-se de que precisamos
reconectar nossa velocidade alvo que
estamos calculando agora A única diferença é
que basicamente
demos um nome a esse alfinete. Então, novamente, é um
pouco mais legível. Vamos atingir
nossa velocidade alvo. E se colocarmos
isso diretamente
no pino de fluxo Y que agora
está exposto, isso automaticamente
conectará isso para nós. Algo que você
me verá fazer com bastante frequência, também, é o que eu
fiz ali mesmo. Então, esses pinos,
meio que os fios estavam flutuando
um pouco Se você pegar vários nós, pressione um taco que alinhará automaticamente
os fios para Assim, podemos manter as coisas um
pouco mais arrumadas à medida que avançamos. Outra coisa que é útil
saber é que se você mouse sobre o pino
aqui, por exemplo, e pressionar um taco sem
realmente pegar as notas, ele pegará o nó
que está conectado e também
os alinhará Então, não é algo que você
absolutamente precise fazer, mas eu só estou mencionando
isso porque eu percebo que eu faço isso com memória muscular, então eu vou fazer isso enquanto
estou falando às vezes E eu só queria que você soubesse os atalhos
que estou usando Ok, então de volta
ao tópico principal. Queremos
suavizar esse movimento com uma
interpolação flutuante Se clicarmos com o botão direito do mouse no gráfico de
eventos aqui, procuraremos
por F interp two Essa é uma
interpolação baseada em flutuação para um determinado valor. Podemos ver aqui algumas
coisas que foram dadas. Então, começamos com
nosso valor atual, que é, como mencionei,
onde estamos agora. O alvo é onde queremos
estar para preenchê-los diretamente. Já temos esses valores e eles são nomeados de acordo. Assim, podemos pegar nossa velocidade atual e colocá-la
aqui na corrente. Então, vamos sair
da nossa corrente e atingir
nossa velocidade alvo. Então, basta arrastar e
soltar isso também. Você pode ver que, em seguida,
precisamos inserir o horário Delta. Então, temos os segundos
Delta aqui. Vou selecionar esse
, pressionar control, na verdade, duplicar com meu
mouse aqui embaixo, e podemos conectá-lo aos segundos Delta. O tempo Delta aqui mantém a taxa de quadros de interpolação E independente,
com algumas peculiaridades Mas, novamente,
voltaremos a isso quando virmos esse problema e o
abordaremos mais tarde. E, finalmente,
temos a interação que
controla a rapidez com que aceleramos em direção à velocidade alvo
que nos é dada Valores mais altos aqui significam
uma resposta mais rápida. Valores mais baixos significam que parecerá
um pouco mais flutuante. Vou começar com
o valor de quatro, que funcionou perfeitamente
bem nos testes. E então, é claro,
não queremos nenhum número mágico em nosso código. Então,
vamos partir daqui. Vamos promover
isso para uma variável. Vou dar a este
um nome sensato algo como movimento
interpreta velocidade Então, agora temos os
quatro F interp dois. O resultado dessa
interpolação
se tornará nosso novo valor de velocidade
atual Muito importante aqui.
Vamos precisar nos
dar um
pouco mais de espaço. Vou remover a sequência de
caracteres impressos aqui. Não
precisaremos mais disso, e vamos passar isso para cá por nove. Vamos evitar
qualquer código de espaguete
e vamos manter as coisas arrumadas à medida que avançamos Isso precisará ser
calculado aqui. Precisamos primeiro da nossa velocidade alvo, seja, o valor que
sabemos que vamos atingir E também precisamos definir agora. Então, usando um nó
como esse definindo o valor da nossa velocidade atual. Algo que acho que ainda não
abordei é que temos formas
alternativas de trazer nossas
variáveis para o gráfico. Se mantivermos pressionada a tecla control
no teclado e agarrarmos, por exemplo, a velocidade
atual e
arrastá-la para o gráfico,
isso fornecerá um nó. Esse nó fino é
chamado de getter. Basicamente, fornece o
valor. Nós podemos ler isso. Está obtendo valor para nós. Se mantivermos pressionada a tecla Alt e fizermos
a mesma coisa novamente, pegue a velocidade atual e
arraste-a para o gráfico,
mas agora segure a tecla Alt. Isso está fornecendo
algo chamado setter. Então, isso
é o oposto. Isso nos permite escrever
no valor que temos aqui. Então, isso nos
permite ler o valor. Isso nos permite
escrever no valor. Queremos manter
a versão gravável aqui
na velocidade atual, então vou me
livrar do getter E queremos levar
nosso valor aqui. Como acabei de dizer, é
assim que nossa
velocidade atual será rastreada Então, vamos conectar
isso à velocidade atual, e só precisamos ter
certeza de conectar os pinos de execução aqui E só para tentar
encerrar isso e garantir que isso faça sentido, porque eu entendo que isso pode parecer um
pouco confuso Precisamos saber, antes
de tudo, o que estamos pressionando e a que velocidade
estamos tentando atingir, é por isso
que atualmente estamos definindo primeiro a velocidade alvo. Então, se imaginarmos que estamos calculando isso desde
o primeiro quadro, já
sabemos que nossa velocidade
alvo é movimento multiplicado por ou mais precisamente, nossa
direção pela velocidade de movimento, multiplicada por Delta, então
obteremos um valor de 500 multiplicado por qualquer valor pequeno
baseado na Portanto, temos uma
meta clara a ser alcançada. A primeira vez que
executarmos isso, obviamente, velocidade
atual
provavelmente será zero. Então, vamos partir de
nossa velocidade atual de zero, então não estamos nos
movendo para,
digamos , 100 unidades de movimento para
fornecer um bom número claro. Vamos considerar o
tempo de Dw novamente
para manter esse quadro
independente, mais ou menos,
e temos nossa velocidade de movimento, a velocidade de movimento de interpolação
, para fornecer diferentes níveis Então, no próximo quadro, obviamente, a velocidade
atual teria sido calculada com base nisso
para ser um pouco maior. Então, vamos partir
dessa velocidade um pouco maior. Digamos que dois ou três, e então vamos
partir desse valor de dois ou três, ainda tentando chegar às 100 unidades de velocidade que
precisamos alcançar. E vamos fazer
isso continuamente ao longo do tempo, que proporcionará
essa suavização Então, a última coisa é que não queremos usar a
velocidade alvo diretamente. É só isso que
queremos usar seja qual for a
velocidade no momento. Então, vamos deletar esse. Vamos pegar
nossa velocidade atual. E, novamente,
vamos arrastar isso
para nosso pino verde aqui, e isso o
conectará automaticamente para nós. E é isso. Está
praticamente pronto para testar o movimento suave. Então você pode ver aqui, enquanto eu estou
indo para frente e para frente, no momento em que eu solto a tecla, temos um
pouco de suavização acontecendo à medida que descemos
a nenhuma velocidade Então, temos alguma desaceleração
e aceleração chegando aqui Agora, como estamos
fazendo isso com o tempo, o movimento pode parecer um
pouco mais lento Então, uma das outras coisas realmente
úteis de promover nossos números mágicos em variáveis é que eu posso simplesmente pegar
a velocidade de movimento. Talvez eu possa dobrar isso, então
vamos definir isso para 1.000 porque está
um pouco lento. Não precisei
ler o código. Eu não precisava descobrir
onde isso estava acontecendo. Isso é muito bem chamado,
então eu sei que isso está controlando a velocidade com
que eu vou me mover. Eu posso apertar play. Eu
posso testar isso novamente, e temos um plano de
sensação completamente diferente acontecendo. Então, isso está se sentindo muito
melhor. Isso realmente exagera um pouco mais a
aceleração e a desaceleração. E, novamente, tudo isso foi feito alterando uma propriedade completa
do sistema geral de movimento simplesmente pegando a velocidade de movimento
e conectando-a Obviamente, adicionamos
o movimento suave, é por isso
que precisávamos
fazer essa emenda. Se você quiser brincar com coisas, pode
fazer algo semelhante, pegue a
velocidade de interpolação do movimento e veja se você quer que ela leve mais ou menos tempo
para atingir o valor final, velocidade atual
que estamos Então, esses são apenas alguns
ajustes variáveis aqui com base em como você deseja que
seu jogo, seu avião seja preenchido Um princípio de design que eu
ouvi muito cedo e que
sempre ficou comigo é sempre tentar exagerar a variável Então, se você não tem certeza do que
eles estão fazendo, ou não tem certeza se
queria que fosse muito
mais rápido ou muito mais lento é o dobro ou o triplo do
valor que você está trabalhando Eu poderia definir esse 4-12 porque você quer
atingir um extremo primeiro, descobrir se funciona,
se está muito alto muito baixo e depois
refiná-lo no meio Então, eu posso ver que está quase
me sentindo bem novamente. Há alguma aceleração e desaceleração, mas não muita Então, o que eu talvez queira
fazer é
reduzir isso para seis, porque 12
é definitivamente muito alto, e estamos nos sentindo um
pouco melhor aqui. Agora, como eu disse, para mim, gosto muito
da sensação disso aos quatro anos, mas apenas um princípio geral de
design é levar o valor
ao extremo, duplo, triplo, metade de algo , seja
qual for o caso, e você rapidamente
poderá se
concentrar em como queria que sua
propriedade parecesse Para meus propósitos, vou
manter a velocidade de
interação do movimento em quatro e podemos passar
para o próximo recurso Então, agora adicionando a rotação
bancária. Na verdade, isso
vai ser muito simples. É essencialmente uma repetição
do que acabamos fazer com algumas funções ligeiramente
diferentes. Essencialmente, à medida que nos
movemos de um lado para o outro, queremos que o avião se incline
um pouco para que
pareça um pouco mais
com uma aeronave real Uma rápida atualização
sobre o eixo aqui. Acho que ainda não toquei
nisso no outono. Vou pegar uma malha
estática muito rapidamente. Eu não preciso acompanhar. Isso é só para visualizar
o que estamos fazendo. Vou pressionar E dentro do ponto de vista para
entrar no modo de rotação, e podemos ver nossos eixos Então, eu mencionei antes, temos essa transformação,
a localização, rotação e escala que
compõem a posição no espaço mundial do nosso ator.
Os locais são muito simples. Temos X, Y e Z, que
são para frente, para os lados, para cima
e para baixo. Rotação, é
relativamente simples. mesma coisa.
Temos três cores. Temos o vermelho, o verde e o azul, então o
X, o Y e o z. Mas se passarmos o mouse sobre
eles, podemos ver aqui que eles realmente têm
seus próprios nomes exclusivos Temos o rolo, o
tom e a perna. Agora, isso não
importa muito, mas se você estiver
tentando ajustar esses recursos, adicione sua própria funcionalidade
e nem terá certeza de quais eixos devo
girar ou algo Eu só queria
mostrar um pequeno visual aqui que, na verdade, é
muito simples de descobrir. Então, nesse caso, eu
quero que o avião se incline em uma direção com
base em como ele está se movendo Então, se eu tentar apenas
algumas coisas aleatoriamente, se eu tentar a verde
e ver o que isso faz, podemos pegar o
valor verde aqui e eu vou deslizar isso
para fazer isso girar E podemos ver que isso nos
dá uma espécie de rotação para cima e para baixo
do avião aqui. Isso provavelmente seria bom se você estivesse
avançando e retrocedendo Talvez você possa adicionar um
pouco disso para exagerar o movimento de
avançar e retroceder Se eu pegar o z e
fizer a mesma coisa, eu só pego
aqueles que eu sei que não funcionam para começar e
os tiro do caminho Podemos ver que isso está girando
em torno dos eixos do avião. Então, novamente, não será
muito útil a menos que estejamos fazendo quatro
tons ou algo assim. Então, o que
queremos usar será o eixo X aqui. Então, à medida que nos
movemos para a
esquerda e para a direita, vamos
querer inclinar um pouco e rolar assim, com base
na direção em que estamos indo. Então é assim que você pode
facilmente entrar, brincar com os
diferentes widgets aqui, girar em uma determinada
direção e ver qual eixo você deseja
aplicar a rotação Como eu disse, isso foi apenas
para demonstração visual. Vou deletar a malha estática. Vamos voltar para a base da panela. Mova isso um
pouco e podemos continuar com a rotação. Para a rotação aqui, temos algumas
funções muito semelhantes que já usamos. Vamos extrair a localização do ator
do conjunto, e você provavelmente pode adivinhar que vamos
pesquisar algo chamado rotação do ator do conjunto. Isso é muito parecido,
atualizações na rotação, e isso será em
cada quadro porque estamos lançando
isso no evento Agora, vamos querer usar uma função muito semelhante também, queremos usar uma
interpolação para Agora, para rotação, não
usamos a interpretação F, vamos usar
algo chamado interpretar dois. Então, estamos clicando com
o botão direito aqui. Pesquise a interp two, y, a rotação, e vamos
pegar essa aqui A outra razão pela qual estamos
fazendo isso dessa maneira que poderíamos potencialmente pegar apenas um único
valor flutuante porque só
queremos
fazer isso no X. Poderíamos fazer algo muito semelhante aqui e usar uma interpretação F. Agora, estou mantendo isso
em paridade, linha por
linha , com o projeto de exemplos de
conteúdo do Unreal Engine Então é exatamente
assim que eles fizeram. Eles usaram uma interpretação F para a localização e uma
interpretação R para a rotação. Então, eu queria mostrar novamente
o código que existe e como podemos corrigi-lo caso surjam dúvidas, por que estamos fazendo isso de forma
um pouco diferente Mas a principal coisa aqui é que
isso
ainda é muito útil porque podemos ver que obtemos as mesmas propriedades que
precisamos para nos alimentar. Temos uma rotação atual,
então, onde estamos no momento, temos uma rotação alvo para a
qual queremos girar E temos o tempo Delta para tornar essa
taxa de quadros independente, novamente, mais ou menos. E então temos
a velocidade de intercalação, que é a suavização Então, a corrente é
realmente muito simples. Temos outro ajudante
muito semelhante ao que usamos antes Se clicarmos com o botão direito do mouse
no gráfico de eventos e pesquisarmos por Obter rotação de
atores. Isso fornecerá, como a localização get actor que usamos, a rotação do ator
nesse determinado quadro. O alvo é uma espécie de número
aleatório arbitrário, e eu digo que só porque
tudo o que o exemplo épico fez foi pegar
a velocidade atual,
então vou controlar o arrasto da velocidade
atual para o gráfico para
obter a velocidade atual que estamos
movendo e
multiplicá-la então vou controlar o arrasto da velocidade
atual para o gráfico para
obter a velocidade atual que estamos por um valor Então, a partir
daqui, vamos selecionar multiplicar. E eu acho que o deles era
algo como 1,5. Então, vamos pegar
qualquer velocidade em que estamos nos movendo, seja um valor positivo
ou negativo, multiplicando isso por 1,5 E esse será o
alvo para o qual queremos girar no eixo x. Algo que eu
queria te apresentar. Nós já vimos aqui. O uso do pino de
estrutura dividida para levar nosso vetor de três pontos até seus pontos flutuantes individuais. O rotador é exatamente o mesmo. Poderíamos simplesmente clicar com o botão direito pino da estrutura
dividida e colocá-lo
no X, Y e Z. Isso pode ficar um pouco
confuso quando você tem tantos
flutuadores diferentes Então, uma coisa que
pode ser bastante útil
e, mais do que
tudo, é apenas para
organizar o código, é que vamos
extrair do alvo aqui e procurar algo chamado make Queremos essa
opção inferior aqui, e ela funciona exatamente como
o nome sugere. É criar um rotador a partir de
X, Y e Z individuais. Ele mantém esses dois flutuadores sozinhos,
então são mais fáceis
de ler, e nos permite simplesmente inserir
nosso valor aqui no X, apenas uma maneira diferente de chegar
ao mesmo objetivo que
fizemos Nenhum deles é
menos ou mais eficiente
e, na verdade, pode se resumir ao que é mais legível
em um determinado caso Eu não diria que isso
é muito ilegível, porque é apenas um vetor
que dividimos . Onde está isso? Já
existem vários carros alegóricos, e dividir mais carros
alegóricos neles acabou por se desenrolar um
pouco Como vimos
anteriormente, queremos nosso resultado final seja a
nova rotação que temos aqui, então vou pegar
essa interpolação
e inseri-la no novo E isso só nos deixa com
algumas coisas para preencher. Então, queremos nosso horário Delta, então eu vou vir aqui, pegar um delta mundial de segundos, pressionar Control ID aqui para duplicá-lo e conectá-lo E então só precisamos da
nossa velocidade de interpolação. Então, novamente, isso está
se movendo no meio. Acho que estou testando que um valor de cerca de dez
funcionou muito bem, e esse é um daqueles valores que
você simplesmente volta e ajusta para obter a
sensação de rotação exatamente como deseja Novamente, não há números mágicos,
então, a partir daqui,
promoveremos uma variável. Dê a esta o nome de velocidade de interposição de
rotação. E com isso, estamos
praticamente prontos para testar isso. Embora uma coisa
tenha se destacado para mim. Isso atua essencialmente como um fator de inclinação ou força de inclinação, em vez de ter esse número
mágico que vamos extrair daqui, de
remoto para variável Vou usar o fator Tilt, que agora está
realmente pronto para ser testado Assim, podemos clicar em
compilar, pressionar play e ver que
temos alguns serviços bancários Agora temos outro
problema, que eu esqueci completamente que
iria acontecer Então, vamos corrigir isso em um momento, mas no setor bancário, a
rotação está realmente funcionando. Então, agora que eu potencialmente
causei enjôo a todo mundo, a câmera está inclinada
com o avião Confirmamos isso,
no mínimo. O motivo pelo qual os
problemas com a câmera acontecem é que a câmera herda a
rotação da mãe Nós realmente vimos isso
na hierarquia. As câmeras estão conectadas
à mola, o braço da mola
à malha estática, e estas estão acompanhando toda
a rotação e localização aplicadas à mistura estática.
Isso é muito simples de corrigir. E uma das razões pelas quais eu
queria usar o hum de mola que
esqueci de marcá-lo com o hum de mola selecionado no painel
de detalhes no lado direito Esse componente exclusivo nos
fornece uma solução A Epic sabia que esse tipo de coisa
seria um problema em potencial. Então, eles nos deram
algumas caixas de seleção aqui. Podemos desmarcar o
tom, o U e a rotação herdados. Lembre-se dos nomes dos
X, Y e Z da rotação. Então, se os desmarcarmos,
isso basicamente significa que não permita que o braço da
mola siga
a rotação do componente
principal E como as câmeras são
derivadas do braço de mola, isso também se aplica
ao componente infantil da
câmera. Então, se clicarmos em
compilar,
pressionarmos play, podemos entrar e ver que
podemos ver bem a rotação E não estamos recebendo aquele movimento de
câmera
potencialmente nauseante que
tínhamos há pouco Outra coisa que acabei de perceber com a goma de primavera selecionada, eu
também tinha essa marca marcada. Faça o teste de colisão Se você teve algum problema em
que a câmera parece
estar se movendo ou sendo
jogada no
chão ou algo assim, isso é potencialmente
porque
o teste de colisão está o teste de colisão O que está acontecendo aqui
só para visualizar isso? Se alguma coisa for detectada entre a câmera e a
coisa que ela está vendo aqui, então algo com
colisão neste ponto
no braço vermelho
da mola, aí
que o
teste de colisão está acontecendo Se alguma coisa passar por isso, é aí
que a
câmera
tentará se mover automaticamente para fora
do caminho ou se esconder atrás de algo
para evitar a colisão Muito útil para coisas como jogos em
terceira pessoa em você pode ter a câmera
roçando na parede e ela ficará um
pouco mais perto
do jogador . Então, esse é um recurso
muito bom. No entanto, em um jogo como
atirar neles , como estamos criando, podemos ter problemas em
que a câmera parece instável se projéteis traços e coisas
assim
passarem pela
câmera, pela linha da E, novamente, isso é outra
coisa que você vê em projetos
iniciantes em que a câmera está meio instável ou com falhas Provavelmente é
porque eles têm algum tipo de teste de colisão acontecendo entre a câmera
e o que você está olhando Então, vamos desligar isso. Não precisaremos disso para
esse tipo de jogo. Com isso feito, a
câmera permanece nivelada. O avião pousa naturalmente,
parece muito melhor. Então, agora
finalmente podemos ver onde exemplo da
Epic
se divide um pouco. Só queria mencionar que isso não
é uma sombra o projeto de exemplo, para a
Epic ou algo parecido. Estou mencionando
isso apenas porque percebo que essa é uma oportunidade perfeita de
ensino, algo que é
amplamente abordado usado por tantos canais de
tutoriais diferentes, inclusive
eu, que você
verá um código quebrado até mesmo em fontes
oficiais Então, saber disso e
ser capaz de
cuidar disso
será muito valioso. Então, o problema que estamos
enfrentando no momento é se
vamos jogar no modo. Com uma taxa de quadros alta, vou reativar minhas estatísticas de taxa de quadros Então, 120 FPS, isso
parece meio bom. No entanto, se eu reduzir isso
para 30 FPS, concentre-se em quanto a
rotação está sendo aplicada Então, novamente, você pode ver que não é apenas o caso de um
deles parecer um pouco mais suave e um
deles parecer um
pouco menos suave devido
à taxa de quadros Isso é literalmente uma
diferença na mecânica, mesmo código, mesma entrada, rotação
completamente diferente A 30 FPS, estamos quase girando a asa
pelo chão, dependendo da distância entre
o avião e o E essa é uma dessas coisas. Nem mesmo está quebrando a jogabilidade. Mas se você configurou um
sistema para ter uma aparência super suave
e exatamente como você
deseja, ele parece ser
o mais atraente para o jogador
, mas alguém um sistema de especificações mais baixas joga com
um sistema de especificações mais baixas joga
e recebe
o segundo resultado Obviamente, você ficará
desapontado, pois eles não estão tendo a
experiência que você pretendia E é por isso que é
muito importante focar nisso. E isso é o que eu
quis dizer com esse bug existe nos exemplos de
conteúdo oficial da
Epic, mesmo código, mesmo problema, enviado na documentação atual E é por isso que confiar cegamente até mesmo em exemplos oficiais,
até mesmo documentação
inicial de piedade, pode ter bugs Portanto, sempre teste casos extremos e fique atento a
coisas assim. Isso é o que eu realmente estou
tentando transmitir. Mencionado anteriormente,
vai ser um pouco longo demais
para esse tópico. Então, isso é algo que
vamos
corrigir um pouco mais tarde, e vamos reconstruir completamente o sistema de
movimento Mas, por enquanto, vamos apenas
reconhecer que o bug existe. Ainda é
perfeitamente possível trabalhar com isso. É uma base perfeita
para construir ainda mais. Voltaremos e
reformularemos totalmente
o sistema de movimentação e corrigiremos todos os
bugs quando terminarmos E agora que vimos
a recompensa por não usar números
mágicos, temos
nossa velocidade de movimento,
controlando o quão rápido você pode ir, velocidade de interpolação de
movimento, que é rapidez com que você
atinge essa velocidade, nosso fator de inclinação sobre o quanto o avião se inclina nas
diferentes velocidades e até mesmo a velocidade de
interpolação de rotação, que é a rapidez com que
chegamos a esses valores de inclinação. Tudo isso é ajustável
sem tocar na lógica. Se você quiser uma ação rápida de
arcade, podemos aumentar
a velocidade de interação Se você quiser um
espaço lento e flutuante, pode abaixá-lo. A sensação do jogo
, então, vem
dos números. Então,
podemos deixar isso aí. Temos um movimento suave, um tanto satisfatório,
com um bom sistema bancário E sim, há o bug
da taxa de quadros ao qual voltaremos, mas pelo menos sabemos
disso e corrigiremos isso mais tarde. Em seguida, podemos atualizar para
o sistema de entrada aprimorado. Este é o substituto
moderno da Unreal para o sistema de entrada antigo
que estamos usando atualmente Se você quiser
experimentar, como eu disse, agora
você tem todos esses
valores prontos para usar. Tente adicionar um pouco mais de
inclinação à rotação e potencialmente, adicioná-la
com os movimentos para frente. O mesmo padrão, eixo
diferente para a rotação
e o movimento, se você ainda tiver isso
em uma direção.
8. 07 — Input aprimorado: Configuração do movimento e trabalho
até um ponto testável. Lembre-se de que o
sistema de entrada antigo que estamos usando, como
mencionei, está obsoleto A entrada aprimorada é
a substituição moderna. Há uma configuração um pouco
mais inicial, mas é significativamente
mais flexível Temos coisas como esquemas de controle com
troca automática, zonas mortas
integradas, revinculação de tempo de
execução e todas as
coisas que você mesmo precisaria
codificar usando
o Então, vamos começar a migrar. A primeira diferença principal é que
o sistema de entrada aprimorado , na verdade, tem seu
próprio conjunto de classes. Então, volte para
a pasta de plantas, clique com o botão
direito aqui ou pressione Control Shift em n para
criar uma nova pasta, e chamaremos isso de entrada A entrada aprimorada divide
as coisas em duas partes. Temos nossas ações de entrada, que definem o que pode acontecer como disparar, mover, reiniciar. E então temos algo
chamado contextos de mapeamento de entrada, que definem quais botões acionam as ações
mencionadas anteriormente, fornecendo uma separação
de preocupações E a razão pela qual essa
separação se mostra útil é que
isso permite que os
esquemas de controle mudem
sem a necessidade de reprogramar toda a lógica
do jogo No código, podemos simplesmente chamar o sistema de entrada para alternar
entre controles de menu, controles jogabilidade,
controles de veículos, seja o que for. Eles podem compartilhar os
mesmos mapeamentos de ações com os botões específicos, mas podem ser executados em
contextos diferentes Uma linha de código e
temos tudo trocado. Dentro da pasta de entrada,
vamos clicar com o botão direito e eu vou para a categoria
Entrada aqui. Podemos ver que temos a seção
de ação de entrada, então criaremos uma delas. Dê a isso o nome de
IA Underscore Fire. Vamos selecionar este
controle mamário , na verdade, para duplicar. Precisamos de mais dois deles, então
vamos duplicar isso duas vezes e chamaremos um
IA de sublinhado de movimento
e o outro de sublinhado de IA Em seguida, queremos abrir nossa classe
IA underscore move. Vamos clicar duas vezes para abrir
isso. E a principal coisa que
queremos ver é que aqui temos o tipo de valor. Por padrão, isso é definido como booleano
digital ou bola, e isso é muito semelhante
ao que configuramos nas configurações
do projeto com
os mapeamentos de ações Precisamos excluí-los de qualquer maneira. Vamos voltar para
Editar, configurações do projeto. Vamos descer para inserir novamente. E só para contextualizar, o booleano
digital que seria
ativado ou desativado seria se
tivéssemos criado um
mapeamento de ações aqui Por exemplo, poderíamos ter
criado algo chamado fogo, amarrado isso a um botão e feito esse disparo toda vez que
quiséssemos chamar um projétil Enquanto estivermos aqui, também
vou me livrar
dos mapeamentos de ações para que não
tenhamos mais nada Isso também causará um
pequeno bug em nosso código, mas facilitará a localização
e o aprimoramento das
coisas quando estivermos
fazendo nossa atualização de código Então, vamos apenas pressionar Delete para nos livrarmos de nossos
mapeamentos de acesso também Novamente, isso
evita automaticamente que possamos fechar isso e voltar para
o sublinhado IA Nossas ações de entrada de
disparo e reinicialização. Ambos precisam de barras
digitais, e é por isso
que eu
não as abri Eles estão perfeitamente
bem por padrão. Ou estamos apertando o botão de
disparo ou não. É o mesmo para
o botão de reinicialização. Para o movimento, porém,
queremos reduzir isso
e usar
esse flutuador D do eixo um, fornecendo
essencialmente a mesma
coisa que um mapeamento de eixo, fornecendo um valor
de menos um a um positivo ou zero se
nada estiver sendo pressionado Então essa é a única mudança
que precisamos fazer dentro da nossa ação de entrada. Podemos pressionar Salvar.
Podemos fechar este e voltar
para nossa pasta de entrada. Então, agora queremos chegar
ao nosso contexto de mapeamento. Isso vai ser quais
botões serão acionados, quais ações. Se clicarmos com
o botão direito do mouse
na pasta aqui, voltaremos para a seção de entrada
e, desta vez, criaremos
um contexto de mapeamento de entrada. A
convenção de nomenclatura será IMC. Sublinhe e, em seguida, o nome da coisa pela qual isso
será responsável Só teremos um tipo de entrada neste projeto mais
simples. Então, vou chamar isso de
principal para nossa entrada principal. Clique duas vezes para abrir isso e podemos ver como funciona. Agora, isso meio que
representa as configurações do projeto que
estávamos editando anteriormente. No canto superior
esquerdo, queremos clicar nesse botão de adição
e soltá-lo. Precisamos tornar cada uma
dessas entradas única, é por isso
que ela está sendo classificada
atualmente, então não podemos adicionar
mais mapeamentos até que tenhamos algumas
propriedades exclusivas nesta Se soltarmos isso, podemos definir
isso como Ia underscore fire E então, se derrubarmos
a categoria
aqui, é aqui que podemos começar a fazer o mesmo tipo de mapeamento
que vimos anteriormente. Então, se eu quiser que
a funcionalidade de
disparo seja chamada na barra de espaço, posso pressionar o botão aqui, pressionar barra de espaço e temos Se eu também quiser que ele reaja
ao clique esquerdo do mouse, posso clicar aqui e clicar com o botão esquerdo
do mouse. Também farei a mesma coisa última vez com o gamepad Vou pressionar o botão novamente e pressionar o botão
frontal inferior, o botão A no gamepad,
e temos esse limite Então, agora temos três botões diferentes ou
três entradas diferentes, que podem chamar a função de disparo quando começamos a
implementá-la Queremos fazer a
mesma coisa novamente nossas outras ações de entrada. Então, vamos pressionar o sinal de mais. vincular algo
ao reinício Isso vai ser bom e simples,
então eu vou fazer isso primeiro. A mesma coisa novamente, poderíamos ter potencialmente R para reiniciar, e talvez eu também adicione
um para o gamepad e faça
dele o botão Iniciar Então esse é o botão especial do
lado direito. Só para observar, estou usando a
tecla Shift para a esquerda e pressionando as setas, que fará com que
tudo volte ao normal Se você quiser alguns
atalhos aqui, segure Shift, pressione o botão esquerdo
e você pode ver que isso desdobra cada Portanto, uma boa maneira rápida de desdobrar
ou desmoronar perfeitamente quando estamos passando mapeamento final que eu queria criar
será o movimento. Então, vamos adicionar mais um
desses. Vamos vincular isso a um movimento de sublinhado Vamos deixar isso lá embaixo. E, novamente, vamos querer
adicionar algumas chaves aqui. Se começarmos da mesma
forma que fizemos anteriormente, clicaremos no botão aqui,
pressionaremos D para ter um movimento
padrão para a direita
e, em seguida, clicaremos em
outro, pressionaremos A para obter nosso movimento para a esquerda. Agora é aqui que as coisas
mudam um pouco, e isso é exclusivo das configurações de entrada
aprimoradas. Embora os tenhamos definido
como um eixo unidirecional,
um valor de ponto flutuante para
nosso movimento de sublinhado IA, você pode ver que na verdade
não temos
nenhum valor flutuante para alterar
aqui para inverter nenhum valor flutuante para alterar
aqui para o A e
fazer as coisas se moverem para a esquerda Em vez disso, é aqui que
entram os modificadores com o sistema de entrada
aprimorado Então, se clicarmos no
sinal de mais no modificador, podemos soltá-lo
e você poderá ver várias
funcionalidades úteis pré-integradas Podemos adicionar coisas como
zonas mortas para manípulos analógicos, escalares
automáticos e
coisas assim,
que podem ser aplicadas
à entrada Aquele que queremos está aqui, então queremos negar o valor O padrão será
um. Se negarmos isso Isso é o que
nos dá um negativo. Tão agradável e simples de usar apenas uma abordagem um pouco
diferente. Eu vou fazer a
mesma coisa novamente. Eu só vou adicionar mais dois. Um para a seta direita.
Um para a seta esquerda. Adicionaremos esse mesmo modificador
na seta para a esquerda. E, finalmente,
adicionarei uma entrada final por movimento
e moverei o manípulo
analógico esquerdo novamente. Agora, a mesma coisa
acontece aqui. Não precisamos adicionar negativos aqui porque o Unreal sabe que um stick analógico tem um potencial esquerdo e
um potencial direito no eixo x, ele retornará automaticamente um
negativo quando eu
pressioná-lo para a Isso é tudo
configurado e pronto para ser usado
no movimento de
sublinhado do IMC Então, clicaremos em Salvar e
podemos fechar este. Não precisaremos editar
nada lá novamente. Então, isso pode ter parecido
um pouco entediante. Como mencionei, ele
tem uma configuração um pouco mais inicial, mas você só precisa
configurá-la uma vez, e esses ativos podem
ser copiados para dois outros projetos com muita facilidade se você descobrir que está
usando padrões semelhantes E o principal é
que, em projetos maiores, isso começará a economizar
muito mais tempo, pois é muito mais flexível do que
o sistema de entrada antigo. Agora queremos voltar
para nossa aula de pornografia. Essa é outra em
que eu realmente preciso que você se concentre, porque
essa é a etapa que todo mundo geralmente esquece com o sistema de entrada aprimorado O contexto de mapeamento existe, mas nada
o está usando ainda. E, diferentemente do sistema de entrada
antigo, nosso
sistema de entrada aprimorado precisa estar explicitamente vinculado a uma classe Podemos fazer isso
com muita facilidade, e essa é a etapa que todo mundo
muitas vezes esquece de fazer Desde o início do jogo,
podemos clicar com o botão direito do mouse
em algum lugar perto daqui e
procuraremos a função
integrada do controlador G player. O controlador do player é
o que está recebendo a entrada diretamente de nossos dispositivos
físicos, transformando-a em irreal
e decidindo como
gerenciá-la em toda a panela
que ele possa estar Isso também pode se aplicar à IA, então essa seria
a entrada que a IA está dando ao peão
controlado pela IA Do controle,
vamos
retirar o pino aqui e
procurar algo chamado subsistema de player local de
entrada aprimorada G. Um nome muito bonito
aí. este aqui
com o F rosa, então
isso indica que é uma função. Ele
retornará apenas um determinado valor, que é aquela entrada aprimorada, o subsistema de player
local E a partir daqui, essa é a
função que realmente precisamos. Vamos chamar o contexto de mapeamento de
anúncios. Bonito e claro. Podemos ver exatamente o que
isso fará. Isso adicionará um contexto de mapeamento
específico, aquele que
acabamos de criar para ser vinculado à classe em
que estamos atualmente. Então, vamos nos certificar de
conectá-los ao pino de execução, colocar aqui o contexto de mapeamento
que queremos usar, e só temos aquele em que temos o IMC underscore Man No
entanto, a forma como você
pode usar isso , como mencionei, é que você pode ter um controlador específico mais
avançado, que monitora o que você pode estar fazendo durante o jogo
. Durante os momentos de jogo, isso
garantiria que o contexto de mapeamento estivesse
usando o IMC do jogo, e você também pode ter algo
como um IMC do menu principal , para poder navegar com o teclado no menu principal Quando o jogador pressiona
pausar ou escapar, o controlador do jogador
seria responsável por alterar
o contexto de mapeamento para ir
da jogabilidade ao menu E é aí que isso se torna
muito, muito flexível. Como mencionei, é um
pouco exagerado para o tipo de projeto
que estamos criando, mas é útil saber,
e você pode realmente aproveitar isso em
qualquer um de seus projetos E o que eu realmente
quero levar para casa novamente, essa etapa é fundamental. Já vi tantas pessoas
configurarem tudo perfeitamente. Eles têm todas
as informações configuradas. Toda a
funcionalidade de movimento estaria funcionando corretamente. Eles apertam play e
nada acontece. Você passa uma hora depurando e finalmente
percebe que se
esqueceu de vincular o esqueceu de vincular Portanto, não seja essa pessoa.
Então, a última coisa que
queremos fazer aqui é substituir a
entrada antiga que tínhamos. Se clicarmos em Compilar, porque
removemos a entrada antiga das configurações
do projeto, isso é o que eu quis dizer
: na verdade, receberemos um erro
ou aviso muito útil aqui embaixo Agora está nos dizendo
que está tentando
referenciar algo que
é um eixo desconhecido. Se pressionarmos esse texto
sublinhado aqui, isso realmente
nos levará direto para
onde os problemas estão
ocorrendo. Tão agradável e fácil. E tudo o que precisamos fazer
é pegar esse nó que não existe mais nas configurações
do projeto. Pressione delete. Podemos clicar com
o botão direito do mouse aqui e queremos pesquisar
nosso movimento de sublinhado de IA A mesma coisa, muito semelhante
à entrada antiga.
Temos duas opções. Obtemos os eventos de ação, que criariam um nó
como esse, onde temos um pino de execução e
a variável flutuante, ou podemos usar a ação do eixo
aqui, o valor da ação A mesma coisa que
o valor do eixo
que tínhamos anteriormente. Então,
vamos selecionar esse. Isso nos dará apenas
o valor do ponto flutuante, e podemos conectá-lo novamente. Portanto, o código em si é
praticamente idêntico. Nada
realmente mudou. É assim que
vamos configurar a entrada
aprimorada para nos fornecer
essas informações. Isso torna a transição
relativamente perfeita, e toda a nossa lógica de movimento
permanecerá exatamente a mesma Se apertarmos play,
podemos testar isso. Então A e D estão fazendo
a mesma coisa, esquerda e direita, e esse
é o manípulo analógico novamente. Então, tudo funcionando exatamente
como esperávamos. Tudo o que precisamos fazer é
atualizar a camada de entrada abaixo do nosso código principal
. E é isso. Agora temos o sistema de entrada
aprimorado em nosso projeto, totalmente configurado, que exigiu um pouco
mais do que a configuração de entrada antiga, mas é muito mais flexível
e definitivamente vale a pena Posteriormente, usaremos mais recursos,
como
eventos de incêndio para fotografar, acionar
entradas retidas em um loop
e, em seguida, também o único botão de reinicialização de
disparo O próximo tópico
que queremos abordar,
porém, serão
nossos limites de jogabilidade. No momento, podemos voar
até a afinidade, que não é muito bom
para qualquer disparo E, claro, se você
quiser experimentar, pode tentar adicionar
coisas como modificadores de zona
morta para a entrada do
manípulo, ver como temporizadores ou pulsos podem funcionar usando Nenhum código é necessário e apenas
algo com que brincar.
9. 08 — Limites: Novo sistema de entrada, ainda temos esse problema em que
atualmente podemos voar para o infinito. Eventualmente, você enfrentaria algum tipo de problema de
precisão de ponto flutuante, mas muito antes disso,
o jogo se tornaria jogar e, o mais
importante, muito chato Para esse tipo de jogo,
vamos querer uma câmera fixa e algumas paredes delimitadoras,
algumas paredes invisíveis A câmera que temos atualmente está
acoplada ao peão
e, para fotografá-lo, uma câmera nivelada
faria mais sentido Então, se voltarmos para a base do painel de sublinhado da
BP, podemos pegar a seleção de controle do
braço de mola, a câmera, e
simplesmente excluí-las Se apertarmos play, agora estamos de
volta dentro da nave, então
recuperamos o problema, mas estamos prestes a
corrigi-lo imediatamente. O principal é
que agora você conhece a estrutura
de jogo e sabe por que estamos
examinando o interior de nossa nave. Caso contrário,
volte alguns tópicos. Se voltarmos
ao nível principal, queremos apenas adicionar uma câmera. No topo, logo
acima do mirante,
há um pequeno cubo,
que é nosso botão de adição Se colocarmos isso abaixo, queremos procurar a câmera opcional. Muitas das opções
aqui tendem a mudar categoria a cada poucas versões
irreais, então a pesquisa pode ser
um pouco mais rápida porque a vida é muito curta
para procurar câmeras Um que queremos é
nosso ator de câmera. Isso será lançado
diretamente no mundo se
selecionarmos isso. A câmera precisará
ver onde o jogador
aparecerá,
e já sabemos novamente, pela estrutura de jogabilidade, como estamos gerenciando isso e
onde isso acontecerá Então, um bom
atalho rápido aqui para você. Se você pegar o início do jogador, que é onde o
jogador aparece, iremos ao painel de detalhes
no lado direito, clicaremos com
o botão
direito na propriedade da
localização e poderemos copiar a
localização real do início do jogador Se pegarmos a câmera,
faremos a mesma coisa, mas
clicaremos com o botão direito do mouse aqui e
colaremos a propriedade
que acabamos de fornecer. Então, agora temos a
câmera diretamente no ponto de partida
do jogador. Também queremos dar alguma rotação a
isso. Então, dentro do visor, podemos pressionar F para focar
na câmera Se quiser, você pode entrar no modo de
rotação e
usar os widgets aqui Agora eu sei que, para nossas necessidades,
queremos apenas girar a câmera -90 graus
no eixo Y. Então, vou fazer isso
no painel de detalhes, e agora estamos olhando
diretamente para o chão. Isso pode estar um
pouco perto demais. Então, a próxima coisa que
vamos querer fazer é mover a câmera para
cima no eixo Z. Então, novamente, se pegarmos
o valor Z aqui, colocarei um valor de 2.400 Acho que isso é semelhante ao
que tínhamos anteriormente. Agora podemos ver que vamos
olhar diretamente para a largada do jogador e para onde o
avião vai desovar. Talvez você não fique tentado a pressionar play e ver o que acontece A razão é simples se tivéssemos cinco, sete,
20 câmeras na cena? Como ele saberia
qual escolher? Como com as outras regras
que estamos definindo, queremos controlar
isso e definir isso manualmente. Então, com o
ator da câmera selecionado, queremos apenas pesquisar
neste painel aqui, no painel de detalhes,
queremos pesquisar algo chamado ativação
do Autoplayer Podemos ver que temos
essa opção aqui. A ativação automática para o jogador está
atualmente configurada para desativar. Se colocarmos essa opção
e selecionarmos o jogador zero, esse será o
primeiro e único jogador em nosso jogo para um jogador. Então, agora a estrutura sabe
usar a câmera que
acabamos de selecionar. Se apertarmos play,
podemos ver isso. Precisaremos fazer
alguns ajustes para centralizar tudo corretamente, mas agora estamos analisando
aproximadamente onde queremos estar Então, com o
posicionamento da câmera,
queremos que o jogador fique mais próximo
da parte inferior da tela, como
invasores do espaço e, novamente, recrie
um pouco a configuração nos exemplos de conteúdo
que estamos usando O problema com o
editor e a usabilidade aqui é que o início do player não tem nenhuma visualização Portanto, será um
pouco difícil ver onde
a nave do
jogador realmente surgirá e
posicionar a câmera adequadamente Então, um truque rápido que
eu queria apresentar podemos adicionar uma
esfera ou forma temporária, algo parecido com isso, para mostrar
onde o jogador começa. Se formos até o
botão Adicionar aqui em cima, podemos acessar nossa opção de formas. Sei que ainda tenho
a localização armazenada desde o início do player
mais cedo, quando a copiei Vou desfazer a
busca pelo Autoplayer aqui, clicar com o botão
direito do mouse e colar a localização do
player E eu olho para essa esfera, que está diretamente no início
do jogador. Se pegarmos o ator da
câmera novamente, isso ajudou
porque agora podemos ver exatamente o que a câmera
estará olhando. Pressionando F, eu
volto a
olhar exatamente para a câmera e podemos arrastá-la
até o lugar certo Então, se levarmos a
câmera para frente ou pudermos fazer com que os
jogadores avancem, qualquer uma delas ficará
perfeitamente bem. O principal é que
queremos que a nave
do jogador esteja mais ou menos aqui embaixo. Então, essa é uma maneira agradável e
fácil de colocar as coisas em posição de forma
agradável e rápida. Se eu pegar a esfera,
posso deletar isso. Obviamente, não queremos
que isso fique no laboratório. Podemos pressionar play e colocar os jogadores mais perto de onde
queríamos que estivessem. Outra dica da câmera
que eu só queria mostrar muito rapidamente é se
pegarmos a câmera novamente, enquanto você está
brincando com as coisas. Se você não quiser que essa janela de
demonstração seja desativada
automaticamente ao selecionar outra coisa, podemos escolher este pequeno ícone de
alfinete aqui embaixo, que fixará essa
janela no seu visor Então, se você precisar entrar, mova os jogadores
para algo ao redor para ver o que está acontecendo pela
visão da câmera, outra dica rápida de que
podemos manter isso na
tela temporariamente. Quando você quiser que isso
desapareça, basta pressionar o pino novamente e ele se soltará da janela
de exibição Apenas algumas coisas
para começar a se familiarizar
e se familiarizar. Vou pegar outra
forma aqui. Acho que já mencionei
isso algumas vezes, mas se você pressionar F com
um objeto selecionado, estará focando no
objeto que deseja olhar. Você pode clicar para girar
diretamente ao redor do objeto. E outra coisa
que pode ser bastante útil é que, se estivermos colocando
algo assim, podemos segurar uma tecla Shift, clicar com o botão esquerdo na direção do widget
e arrastá-la Então, se começarmos a
arrastar um objeto aqui e depois pressionarmos Shift, se ele estiver se movendo, podemos
realmente fazer com que
a câmera no visor continue rastreando o
objeto que estamos Muito útil se você está
tentando reproduzir alguma coisa e não
quer continuar movendo-a,
movendo a câmera, movendo-a novamente e assim por diante Então, apenas algumas dicas rápidas para
se familiarizar
com o visor. Agora vamos querer começar a analisar os limites. Mais uma vez, no botão Adicionar, procuraremos algo aqui chamado volume de bloqueio. Podemos ver como temos a
opção de bloquear o volume. Vamos selecionar esse
, e o que nos é
dado é esse cubo invisível Isso representará
nossa parede invisível, e só queremos
colocá-la em todo o nível para bloquear onde o jogador ou os inimigos possam bater. Para colocar isso em prática, vou fazer a
mesma coisa novamente. Vou
clicar com o botão direito do mouse e colar o local de
início do player . Isso nos
colocará aqui. Para este, podemos colocá-lo no lado esquerdo
da nossa zona de jogo,
que eu sei que, por meio de
testes, seria um bom ponto de 1.240 negativos Isso colocará isso um pouco acima. Pronto
perfeitamente no eixo Z. Isso é alto o suficiente para que o avião realmente
colida com isso Se colocarmos isso na posição
X de zero, isso colocará esse
tipo de meio nível
no eixo Ford. E então o que queremos
fazer aqui é dimensionar a caixa para cobrir toda
a extensão. Agora, uma maneira de
fazer isso é
tornar o eixo X
aqui muito mais longo. Isso mudará a caixa. Isso é meio que esticar
o ator real. Quando estamos trabalhando com
coisas como volumes, temos outra opção. Então, vou voltar
para a maneira ideal de
trabalharmos com eles alterando
as configurações do pincel aqui. Então esse é o tamanho da caixa que
temos atualmente, que tem 200 centímetros de diâmetro. Então, se definirmos isso para algo
muito maior, adicionarei
alguns zeros aqui Então, teremos uma
caixa de 20.000 unidades apenas para garantir que estamos encapsulando
toda a zona de jogo e um pouco mais,
provavelmente Mas está perfeitamente bem. A razão pela qual queremos
fazer isso é porque
isso está alterando a escala
do componente real interno,
esse componente da caixa de pincéis. Já esse valor aqui em cima é a escala de todo o ator
real. Então, se conseguirmos manter esse
uniforme e limpo ao mesmo tempo, se alguma vez
precisarmos verificar as coisas no código, será um pouco
mais fácil trabalhar com ele. E, novamente, apenas mantém nossa
estrutura um pouco mais organizada. Enquanto estivermos
aqui, vou deixar a altura um
pouco maior Então, talvez queiramos definir isso
para algo como 1.000
no Z apenas para
ter certeza de que estamos definitivamente bloqueando
absolutamente tudo. Outra coisa que pode ficar
um pouco confusa é que, se for um
pouco difícil de ver, temos opções para
alterar a opacidade, podemos adicionar um volume
sombreado na tela e começar a ver
onde está o Novamente, isso não
aparece no modo de jogo, mas aparece
pela câmera, o que torna um
pouco mais fácil de ver. E o principal
é poder
avaliar onde o
volume de bloqueio realmente ocorrerá Feito isso,
vou pressionar Control em D depois de selecionar o
volume de bloqueio que configuramos. Vou definir isso para 1.240, então temos isso no
lado direito do campo de jogo Então, o YX está aqui. E só para torná-lo visível,
como no lado esquerdo, vou
rolar de volta para baixo. Ative o volume
sombreado da tela e os dois terão a
mesma aparência . Esteja ciente também. Acho que quando
duplicamos as coisas, Unreal tenta mover o ator
duplicado em várias unidades qualquer maneira para que elas
não Então você pode ver que no volume
do lado direito, temos alguns deslocamentos no X.
Isso na verdade não
causaria nenhum problema Mas só para acalmar as
vozes e meu cérebro, vou colocar isso de volta em
zero e tudo de novo, bem arrumado e
bem Com várias
alterações como essa feitas, talvez
você queira
pressionar Control Shift e S para salvar tudo em
que estamos trabalhando. Então, agora podemos entrar no playode. Vamos olhar
pela nossa câmera. Vai ser um
pouco difícil de ver
porque não podemos ver o volume
real de colagem aqui Então, se quiséssemos testar
coisas e ter certeza que
sabemos exatamente quando poderíamos
estar atravessando uma parede, outra opção, um
pouco demorada aqui, é que poderíamos voltar às formas.
Poderíamos adicionar um cubo Deseja acessar as configurações de
colisão no painel de detalhes
no lado direito
e, apenas para garantir que
verificaremos apenas nosso volume de bloqueio, podemos selecionar a predefinição de
colisão
aqui e transformá-la aqui e transformá-la Examinaremos mais sobre a colisão
um pouco mais tarde, mas isso é apenas para
obter algo visual Então, novamente, vou voltar
aos detalhes, colar isso no local e colocar -1.240 Para maior rapidez e
simplicidade, vou mantê-lo aproximadamente do mesmo tamanho. Não precisa ser exato, então vamos pegar o cubo No eixo Y, precisamos fazer
essas duas unidades no Y para obter aproximadamente o tamanho do nosso volume de
bloqueio e, novamente, vamos torná-lo muito
maior no X para que ele abranja tudo e
maior novamente no Z. Não
precisamos ser
tão cuidadosos Aqui. O principal é
que é apenas algo visual para que possamos ver se e quando o jogador estaria
atravessando a parede, para que
possamos ver isso aqui. O principal motivo é
que eu sabia que a colisão não
funcionaria e só queria eliminar
imediatamente o fato de que estamos realmente passando
pela área de ligação, que deveria estar
colidindo conosco O motivo pelo qual eu
queria apresentar isso, pois sabia que isso
iria acontecer, nos dá um pequeno exemplo
de como podemos fazer a depuração Isso é muito importante
no desenvolvimento,
na verdade, entender
como resolver problemas,
resolver as coisas e
descobrir o que está acontecendo. Já meio que
resolvi um dos problemas. A primeira coisa é que não
saberíamos se estivéssemos apenas voando se
realmente atravessamos a parede ou não. Então, já descartamos o fato de
não estarmos alcançando a parede Podemos chegar ao
ponto da parede e ir mais longe e nenhuma
colisão está acontecendo Então essa é uma opção
da lista de verificação
completamente preenchida. Se eu pegar o volume de bloqueio à esquerda aqui,
tentaremos corrigir esse primeiro. O primeiro suspeito pode ser as propriedades de
colisão que
acabei de mostrar a você Então,
no lado direito do painel de detalhes, voltaremos às propriedades
da colisão Em caso de colisão, podemos ver que essa predefinição está configurada
para parede invisível Se deixarmos isso de lado, podemos dar uma
olhada no que isso significa. E esta será uma breve visão geral
da colisão. Novamente,
haverá muito mais profundidade sobre isso em tópicos futuros. Mas, por enquanto, tudo o que precisamos
saber é que temos três tipos
diferentes. Temos
Ignorar, sobrepor e bloquear. Ignorar faz o que
você pensa. Ele ignora todos os outros
aceleradores e interações. Overlap é
procurar duas coisas que estão no
mesmo espaço físico, mas que não se tocam fisicamente com coisas como física
e se bloqueiam E então temos o
bloco, que seria dois objetos físicos se
impactando e tentando
se afastar para que
não habitassem o
mesmo espaço físico Resumindo, a parede invisível é
configurada exatamente como queremos. Está configurado para bloquear absolutamente
tudo no mundo. A propósito, esse é o nosso segundo
suspeito. Sabemos que estamos
alcançando a parede e sabemos que a
parede está colidindo. A próxima coisa é que vamos
analisar a colisão das panelas Então, se vamos
para a classe de peões, vamos para a malha estática, e a colisão
no momento está sendo tratada na Então, no painel de detalhes, novamente, vamos querer rolar para
baixo e encontrar a colisão Apresentaremos as predefinições de
colisão e podemos ver que isso está
configurado para bloquear todas as Agora, isso realmente
não importa. Novamente, o importante
dessas caixas de seleção aqui. Isso também está marcado para bloquear
absolutamente tudo. E se voltarmos
ao mundo muito rapidamente, teremos um
curso intensivo de colisão aqui, podemos ver que a parede
invisível está configurada para ser seu tipo de objeto e
configurada como estática mundial A pornografia em si é definida como
dinâmica mundial. Então, isso está tentando bloquear objetos estáticos
do mundo, e isso está procurando bloquear objetos dinâmicos
do mundo. Então, enquanto esses dois
quiserem interagir, devemos ver algum bloqueio
físico. A propósito, esse é o terceiro
suspeito. A colisão de pornografia está,
na verdade, configurada corretamente. E isso realmente deixa a
única coisa:
provavelmente fizemos algo
errado em nosso código. E alerta de spoiler, eu já
sei que esse é o problema. Então, se entrarmos no gráfico de eventos do evento, passaremos para
nossa
função de localização do ator definido aqui. E essa é uma daquelas
coisas em que
seria muito difícil depurar e realmente saber que
esse é o problema sem realmente ter
experimentado isso Duas coisas a serem observadas aqui
são os booleanos de varredura e teletransporte
na chamada Se passarmos o mouse sobre a varredura, podemos ver aqui que a descrição que obtemos é se varremos o
local de destino acionando podemos ver aqui que a descrição
que obtemos é se varremos
o
local de destino acionando
sobreposições ao longo do caminho.
Isso é muito importante. Também controlamos
se paramos perto do alvo se algo
for bloqueado por alguma coisa. A parte realmente importante aqui é que, se não
tivermos essa opção ativada
, não verificaremos nossa posição está bloqueada, o
que significa que não
acertaremos nada Resumindo,
desmarcar a varredura é, tecnicamente, meio nos teletransportar para o
local em que queremos Então, se marcarmos isso,
clicarmos em compilar e salvar, voltaremos e testaremos novamente. Agora podemos ver que quando estamos sobrevoando,
agora estamos sendo bloqueados. Portanto, não precisamos
alterar nenhuma das predefinições de
colisão Falaremos sobre eles
um pouco mais tarde. Isso significa,
também, que a parede do
lado direito funcionará porque está configurada
exatamente da mesma maneira, então está perfeitamente bem. Era uma coisa muito
simples, muito fácil de ignorar
em nosso código Então, eu queria incluir
isso só porque, como mencionei, as coisas
nem sempre correm perfeitamente, e você precisa se
sentir confortável depurar e tentar
resolver as coisas que você
logicamente acha que poderiam
ser parte Essa é uma daquelas coisas que acaba sendo uma pegadinha
muito comum É muito fácil
perder. É muito difícil de depurar se você não sabe
o que está procurando Mas se isso tivesse falhado, até mesmo eu ,
como desenvolvedor experiente, eu estaria meio que fora dos possíveis caminhos de pensamento que eu
poderia ter percorrido, e teria que
ter simplesmente acessado Google, o RDI ou algo parecido
e tentado descobrir se alguém tivesse
um problema semelhante Então, basta uma rápida limpeza
dos limites agora. Eu vou voltar para dentro.
Vou me livrar desse cubo branco aqui. Isso
foi só para visualização Agora sabemos que estamos
desovando no lugar certo e estamos sendo
bloqueados pelas duas paredes aqui.
Então, com isso feito. A câmera está fixa. Agora está
no lugar onde queremos. Os limites estão definidos e,
quando começarmos a adicionar inimigos, eles detectarão as paredes
e saltarão entre elas. Obviamente, depois de
implementarmos esse código. Antes disso, porém, vamos começar
a analisar os materiais, os mais tipos de
elementos visuais do nosso projeto. Poderemos personalizar
a aparência de nossas naves para que todos os inimigos não pareçam idênticos ao jogador. Como sempre, se você
quiser experimentar, no momento,
tente algo simples. Tente adicionar um limite superior e
inferior, especialmente se você
já tiver algum movimento para frente e para trás Mais uma vez, mesmo
processo, eixos diferentes, só para você se familiarizar e
experimentar coisas diferentes
10. 09 — Instâncias de materiais: No momento, se começarmos a
criar nossos inimigos, eles se parecerão exatamente
com o nosso jogador. Mesmo avião azul, não há como
realmente diferenciá-los. É por isso que nossos
materiais chegam, permitindo que envolvamos
cores e imagens diferentes em nossos três modelos D
para
diferenciá-los e adicionar alguma variedade Não criaremos
materiais do zero, pois essa seria sua
própria toca de coelho E, como mencionei,
estamos focados principalmente em programação, práticas e projetos,
os três Ps. Mas vou mostrar
como podemos criar variações de
cores a partir do que
eu realmente forneci. Embora não criemos
novos materiais do zero, quero mostrar a vocês os
materiais que já temos. Se examinarmos os materiais da
pasta de ativos, conforme mencionei anteriormente com as convenções
de nomenclatura, temos algumas coisas
aqui para analisar Temos dois sublinhados MM
na água e na textura, e temos quatro sublinhados MI, que são as instâncias
materiais Mm, que é um prefixo
para material mestre. É aqui que a lógica real do
sombreador acontece. Abrimos a base da textura, não
editaremos
nada aqui, mas eu só queria mostrar
a vocês algumas terminologias e detalhes com
os quais você deve
se familiarizar Se passarmos para o
lado esquerdo do gráfico aqui, isso é muito parecido com o gráfico de
planta que podemos clicar com o botão
direito do mouse e arrastar para
mover A principal coisa que temos são três entradas de amostra de textura Temos a cor base,
que é nosso mapa de cores,
os azuis, o
grão da madeira, a tinta E tudo isso foi retirado do mapa
Ubi no modelo de três D. Em seguida, temos nossa textura
normal ou o mapa normal, que adiciona detalhes
da superfície sem geometria,
aquelas saliências, nervuras, linhas de
painel e assim por diante, tudo falsificado ao manipular a forma como A última coisa importante
é a textura do ORM. Nesse caso, isso é algo que
eu criei pessoalmente e tenho um fluxo de trabalho um pouco
diferente. Eu criei isso como um ORME
especificamente desta vez. São essencialmente quatro imagens em tons de cinza
agrupadas em um único
arquivo de textura, canais RGBA A principal razão para isso é que todos os dados contidos neles podem ser extrapolados em escala
de Isso economiza memória e é um
pouco
mais fácil de trabalhar. Nesse caso, o canal vermelho
é a oclusão do ambiente. É aqui que a luz
terá dificuldade em alcançar. O canal verde é rugoso, criando uma superfície espelhada lisa versus fosca em O canal azul é
metálico. Isso é binário. Isso é metálico
ou não metálico, e o
canal Alpha é emissivo, mostrando quais partes Algo que é útil observar
ao trabalhar com materiais é
que, em vez de apenas ter essa
representação esférica aqui, podemos alterar o que
aparece neste visor com um truque útil Se abrirmos o desenho de conteúdo e entrarmos na pasta de malhas, pegue uma malha que você gostaria de
visualizar com seu Nesse caso, será
o herói comum. Não precisamos fazer
nada com isso. Só precisamos que isso
seja selecionado. Podemos voltar ao material e até
lembrar
o que
selecionamos atualmente dentro da gaveta de
conteúdo Pode mudar a representação, a visualização
do nosso material aqui para ser coisas como um
cilindro, um plano, um cubo E então, especificamente,
esse ícone de tijolo aqui. Se você tiver uma malha estática
selecionada e clicarmos
nela, ela nos dará uma
representação, visualização do nosso plano ou da malha que atualmente
selecionamos no desenho do conteúdo Portanto, isso pode ser muito
útil para visualizar as coisas
e ver exatamente o que
é responsável Mas e quando você está alterando propriedades
diferentes e recebendo esse feedback
imediato? Em seguida, quero que você se
concentre nesses nós nomeados em todos os lugares. Eles são chamados de nós de reraiz
nomeados. Em vez de fios se estendendo
por nosso gráfico,
algo como um quadro de evidências de
teoria da conspiração. Em vez disso, podemos escolher criar conexões
nomeadas apenas uma vez
e, em seguida, podemos
referenciá-las
em qualquer lugar dentro do nosso
Shader. Completamente opcional. Você nem sempre os verá usados em outros exemplos,
mas, novamente, permite que eu mantenha toda a minha lógica
de Shader
no lado esquerdo e depois chame as coisas quando eu precisar delas
no lado direito Uma daquelas coisas
em que a ferramenta existe, então por que não usá-la Como mencionei, porém, eu não
recomendaria alterar nada dentro do
material principal , a menos que você
saiba o que está fazendo
ou, pelo menos,
faça uma cópia e faça alguns ajustes
nela para que você sempre tenha algo em que
recorrer O principal motivo é que o
próximo tópico que examinaremos são as instâncias materiais
e a forma como a instância funciona é direcionar as informações
diretamente desse material principal. Então, se algo ocorrer aqui, você potencialmente quebrará
todas
as instâncias que dependem disso. Então, de volta à pasta de
materiais, se você se mudou, para economizar um pouco
de tempo, podemos usar um ponto de partida bastante lógico. Já temos um avião. Ele tem a maioria das
texturas e tudo configurado exatamente como precisamos, e esse é o reprodutor de avião MI
underscore Então vá em frente e pegue
este, pressione control, na verdade, para duplicar e renomear
este para avião inimigo, mantendo o MI na Se clicarmos duas vezes
e
abrirmos isso, agora podemos começar a
analisar instâncias materiais. Podemos ver que isso
é muito diferente do nosso material principal. Uma coisa para ficar de
olho aqui está
no lado direito do painel de detalhes. Algo que devo mencionar, você provavelmente está
percebendo padrões aqui Toda vez que estamos em um painel,
sejam materiais,
plantas, componentes,
vasos de visualização, quando você pega algo, normalmente
há um
painel de detalhes em algum lugar para fornecer
informações sobre o que
você está vendo, que é definitivamente uma das coisas boas
do Unreal Quando você começa a aprender
partes dos conjuntos de recursos, isso é transferido para diferentes recursos dentro do mecanismo. Mas o que eu estava prestes a dizer é se olharmos para o painel de detalhes, temos o pai
sendo indicado aqui, e isso mostra que essa é da textura de sublinhado MM. Então, podemos
clicar duas vezes nisso, e isso nos leva de volta ao material que
acabei de mostrar a vocês. Então, como mencionei,
todas as informações vêm diretamente
desse material principal. Outra coisa, seria bom visualizar o avião novamente. Então, só para recapitular, volte
para a pasta de malhas, pegue o avião e pressione o ícone de tijolo aqui dentro
da instância do material As principais coisas que queremos
mudar são as texturas. Podemos ver que isso
é muito diferente. Não temos nenhuma informação
do gráfico ou desse sombreador aqui Tudo isso é
usado especificamente no material principal. Dentro da instância, o
que temos, em vez disso são coisas que eu escolhi
especificamente expor Tudo isso com nomes de notas
grandes aqui, as texturas, a cor da textura Essas são
variáveis parametrizadas que eu expus para que possamos
vê-las na instância Então, o que queremos
observar se abandonarmos as categorias de Dan é essas são todas as
coisas que acabei de mostrar: as propriedades expostas. Ao expor essas instâncias
internas,
obtemos um
ambiente de trabalho muito agradável, onde podemos simplesmente fazer uma alteração e ver essa atualização imediatamente Então, podemos fazer isso para obter
nosso primeiro tipo de inimigo. Se colocarmos essa cor base de
textura, então as informações de cor, vamos
procurar o inimigo verde. Acho que vou deixar
os inimigos verdes. Eu forneci várias cores de textura
diferentes aqui se
você quiser expandir isso e criar seus próprios tipos de inimigos. Acho que incluí amarelo, roxo, talvez laranja ou vermelho. Vou escolher a textura da cor base
verde, e podemos ver que isso
mudará imediatamente nossas informações sobre
a planície. A maioria das texturas normais
e OIME provavelmente
são praticamente as mesmas,
mas eu as exportei individualmente
por textura quando
as criei Então, podemos muito bem seguir em frente
e pegar o normal. Então, vamos
procurar o verde novamente e vamos encontrar
o herói verde puro. Mas desta vez, queremos
a textura normal. E, finalmente, vamos
reduzir o espaço OIME e
procurar o verde novamente,
e vamos substituí-lo pelo verde herói OI ME Ok. Então, só para
ter certeza de que estão exatamente com os modelos que fiz dentro do liquidificador,
caso alguém estivesse curioso, alinhados
exatamente com os modelos que fiz
dentro do liquidificador,
caso alguém estivesse curioso, eu os texturizei
e coloquei todas essas informações
no Substance Então, como mencionei, você pode ver fluxos de trabalho semelhantes, mas ligeiramente
diferentes Tudo se resume ao artista e à pessoa
que os está fazendo. A principal coisa a
observar, porém, é que recebemos esse feedback
imediato. Assim que mudamos alguma coisa, não
há recompilação, vimos a nova textura
aplicada ao material, o que é um dos principais
benefícios das instâncias do material Definitivamente, não é exclusivo
desse benefício, e devemos sempre tentar usar instâncias
materiais sempre
que possível, em que as coisas compartilhem propriedades,
características e valores
semelhantes que podemos expor Portanto, além das texturas,
esse seria um ponto final perfeito se você estiver satisfeito com a
aparência que está Eu só queria
fornecer um pouco mais de informações sobre instâncias
materiais, o que elas fazem e como
podemos usá-las. Então, algumas das outras propriedades
que eu expus aqui são valores de ponto flutuante
ou cores que podemos alterar e substituir
diretamente a cor geral ou
a tonalidade que está sendo aplicada
ao material
ou coisas como o quão
especular é o Portanto, a especularidade é
muito fácil de ver. Se eu marcar a especularidade aqui, isso
nos permitirá editar isso E, no momento, estamos em 0,5, especularidade
aproximadamente média Essa é a quantidade de luz
refletida de uma superfície, fazendo com que as coisas pareçam um
pouco mais plásticas ou mais
parecidas com borracha quanto maior
a especularidade parecidas com borracha quanto maior
a especularidade Geralmente, não temos nada com o qual
interagimos
diariamente que
tenha zero especularidade Portanto, começar em
torno 0,3 ou 0,5 é
algo realista. Se reduzirmos isso para zero, obteremos esse feedback imediato. Quer dizer, eu tenho uma superfície
completamente emaranhada e completamente não
refletiva. Se colocarmos tudo
isso em um, então a luz está
voltando muito, muito mais Então, novamente, você pode ajustar
recursos como esse e tentar ter uma ideia de como você gostaria
que
o seu fosse Você também pode
brincar com coisas como uma máscara colorida
ou uma tonalidade colorida Então, se usarmos a máscara de
cor aqui, essencialmente uma porcentagem
normalizada de 0 Portanto, zero é sem mascaramento
e um é mascaramento total. Se ativarmos a
cor da textura, esses dois funcionarão juntos. Portanto, a máscara de cor está mascarando a substituição da
cor da textura Se eu tornar isso algo
realmente óbvio, como uma cor vermelha, e depois desligar a máscara,
tornando-a 100% eficaz, permitindo
que 100% da
cor apareça. Então, ele muda para o valor um. Agora temos um avião totalmente rosa. Portanto, podemos controlar
isso com muita facilidade. E o melhor de
tudo isso é
que recebemos esse feedback imediato e a atualização imediata quando
estamos fazendo essas alterações. Se você quiser que isso seja um
pouco mais sutil,
poderíamos mudar a máscara de cor
para algo como 0,5, e estamos permitindo que apenas metade dessa cor
apareça. Reduza para
0,2 e obteremos apenas uma tonalidade azul muito clara
no topo do nosso plano verde Reduza tudo para zero, e não teremos nenhuma
cor aparecendo. Então, outra coisa com a
qual você pode jogar, junto com as diferentes
texturas que você pode usar, e então as
propriedades emissivas funcionam da mesma maneira Agora, eu não tinha nada aqui para realmente fazer brilhar, como faróis ou
algo parecido Portanto, a emissão era mais uma forma de fornecer
propriedades diferentes com as quais brincar. Se eu ativar a intensidade emissiva, precisamos dar a isso um
valor maior que zero E então, se ativarmos
a cor emissiva, no momento, ela é preta Agora, obviamente,
preto é apenas zero, zero, zero no valor RGB Então, se multiplicarmos o
preto por um ou 100, ainda
teremos
preto, o que não é nada Então, precisamos dar uma
cor a isso se mudarmos isso para algo como
amarelo ou laranja, e talvez precisemos aumentar
a força um pouco mais. Na verdade, essa é uma
daquelas coisas em que, ao explorar
diferentes texturas,
algumas delas, percebi que não
precisaria de
um canal
emissivo repleto de texturas Então, se você quiser
contornar a propriedade emissiva, pode
entrar na textura OME aqui e mudaremos isso
para o plano azul novamente. aviões aqui são azuis. Teremos que diminuir o tom disso um
pouco. Talvez, mas há algo
mais parecido com um ou 0,5, então não está
substituindo completamente a cor E você pode fazer o
avião inteiro brilhar um pouco aqui. Portanto, você também tem controle sobre a propriedade emissiva Como eu disse, infelizmente, não
pensei em
modelar alguns
faróis com antecedência, mas queria aprimorar as propriedades emissivas para que você
pudesse fazer
o você
pudesse fazer avião inteiro brilhar
e se divertir Pode ser útil se você quiser animá-lo
explodindo ou Você pode fazer com que ela brilhe entre sua
cor normal e, tipo, um vermelho antes da explosão
acontecer, uma ideia Só para ajudar a visualizar o que está acontecendo aqui
e como essas texturas,
especialmente o OIME, especialmente o OIME Eu sei que isso pode
ser muito confuso. Vou apenas desligar
isso e
atrasá-los porque não
quero substituir nenhum deles E vou
transformar a textura novamente em verde para
o OIME, como eu sei, que foi
cozido especificamente para essa propriedade de cor Eu só queria mostrar
rapidamente as texturas
e o que está acontecendo Então, quando digo que eles foram incorporados em canais diferentes, se entrarmos na pasta de
texturas, descobriremos que
realmente não importa qual
deles, para ser honesto. Podemos simplesmente encontrar
o herói azul claro e eu vou
abrir o canal OIME Então, normalmente, na maioria das texturas, as cores e tudo o que estamos vendo aqui
vem
dos canais RGBA, todos
combinados ao mesmo tempo Se você tirar um pouco, tudo o
que você vai acabar com são cores meio
turvas e estranhas como essa, onde vermelho e azul somados
obviamente nos darão Vermelho e verde nos darão uma espécie de
cor laranja e assim por diante. Então, não o usaríamos dessa forma. Com o processo ORME, é
um pouco diferente. E isso é porque o que eu
fiz, no canal vermelho, é nossa oclusão ambiental Portanto, qualquer coisa que seja
branca essencialmente não bloqueada por nenhum outro
elemento do modelo. Então, a luz está nos
impactando totalmente, e então qualquer coisa que
vá para cinza ou preto tem algum tipo de oclusão de outra
parte do modelo,
como o rolamento da roda íntima e coisas assim E aplicará
um pouco de sombreamento
falso para
enfatizar as sombras No canal verde,
essa era a nossa aspereza. Então, novamente, indo de
um valor essencialmente de zero a um, áreas
diferentes
parecem ser mais aproximadas essas áreas aqui fornecem
algum tipo de detalhe aproximado, enquanto elas serão
muito mais suaves. O azul era o metálico,
então, novamente, era metálico
ou não Então, essa seria a
frente da hélice. Existem algumas pequenas peças
de metal
nas rodas e outras
pequenas características como essas. E então o canal Alpha
foi incorporado e, como
você pode ver aqui, isso é essencialmente
o corpo inteiro
do avião que foi
incorporado ao canal emissivo Então, retirando essas informações
e
multiplicando-as nossas propriedades de
cor e coisas assim
no material, podemos manipular elementos
específicos modelo por meio
de
nossos canais Portanto, é uma
maneira inteligente de fazer as coisas. Isso economiza memória
e nos dá um pouco mais de flexibilidade
em nossos materiais. Apenas algumas outras coisas antes de encerrar esse tópico Se você quiser
brincar com mais materiais, apenas para mostrar
algumas maneiras diferentes de
criar diferentes instâncias de
materiais. Eu mostrei como duplicar nosso material original do player O controle em D
duplicará isso. Se você sabe que
só quer criar algo completamente novo, um material totalmente novo para
brincar com eles, basta acessar o material
e selecioná-lo. Se você já tem
um material mestre com o qual
trabalhar e
deseja criar uma nova instância, clique com o botão direito do mouse
no material mestre aqui, navegue até o topo aqui e crie uma nova instância de
material. Isso lhe daria
algo muito semelhante ao avião
do jogador ou
qualquer outra coisa que eu tinha anteriormente, e teria apenas alguns valores pré-preenchidos
padrão, essencialmente o mesmo resultado. Então eu vou me livrar desse.
Não vou precisar guardar isso. Só queria mostrar como você pode
trabalhar com eles. Dizendo
isso porque provavelmente é um
dos tópicos mais fáceis de abordar, e não vamos nos aprofundar muito mais do que temos aqui. Definitivamente, recomendo
dedicar algum tempo entre os tópicos para pausar os vídeos
e dar um passo atrás Talvez crie algumas
instâncias de material com cores diferentes. isso lhe daria a opção Posteriormente, isso lhe daria a opção de ter um inimigo verde, um inimigo roxo, um inimigo vermelho, o que se adequar à sua
visão do jogo. Você também pode tentar
dar chips
diferentes, valores de secularidade diferentes, adicionar um pouco de propriedade missiva
a alguns deles
ou dar-lhes uma tonalidade de ou dar-lhes uma Então, se você realmente quiser
começar a aprender mais sobre o motor e realmente
entender o que está acontecendo, considere isso como uma pequena lição
de casa entre
este tópico e o próximo e tente criar alguns
exemplos materiais entre eles Mas feito isso, esse é o nosso material meio que coberto, e estamos prontos
para usar um material inimigo que possamos começar a criar
nossas novas classes. Usando instâncias de materiais,
conseguimos criar essa nova variação sem
tocar em nenhuma camada, usando a única
classe de material principal que eu forneci, com toda
uma gama de possibilidades para que ocorram instâncias
de materiais
11. 10 — EnemyMovement: hora de criar alguns
inimigos. Aviso justo, primeiro
faremos isso da maneira
abaixo do ideal Você pode questionar algumas das opções se souber
o que é irreal Mais uma vez, isso é
totalmente intencional
e, desta vez, é para
nos permitir refatorar nosso trabalho A refatoração faz parte de
qualquer desenvolvimento real. É pegar a base de código ou
projeto que você já tem, melhorar o código que
está funcionando e que você deseja manter e remover o
que não precisa. Quero ter certeza de que
terei
a chance de passar por isso com você para que eu possa mostrar como tornar o processo um
pouco mais indolor Mas é claro que, primeiro,
precisaremos de algo que
nos permita refatorar Para fazer isso, vamos
criar nosso peão inimigo. Então, se navegarmos até
a gaveta de conteúdo dentro do blueprint
e da pasta principal,
clicaremos com o botão direito do mouse aqui e acessaremos
a opção de classe blueprint
e criaremos uma nova classe Vamos dar a este o nome
de BP Underscore pawn Enemy. Entre para abrir isso, e
isso será quase idêntico ao que
já configuramos para nosso player. E isso é essencialmente parte
do problema inicial aqui. Vamos duplicar vários trabalhos que já
fizemos Posteriormente, abordaremos a
melhor solução, mas, por enquanto,
vamos aproveitar o que tínhamos antes
com nosso jogador. Então, no painel de componentes, sabemos que queremos adicionar
uma nova malha estática. Vamos pegar
nossa malha estática e colocá-la na raiz da cena
padrão. Com a malha estática selecionada, vamos
para o
lado direito no painel Detalhes
e optaremos por usar o herói do plano de sublinhado
SM Claro, não queremos que
seja da mesma cor. E se você não consegue
ver seus materiais no painel de detalhes no momento, basta clicar na malha estática e encontrar
o outro componente. Selecione a malha estática novamente e você pode ver que agora temos
nosso material selecionado. O elemento zero é o
corpo do avião. Essa é a
cor principal e o detalhe. elemento um é um slot de material
separado criado exclusivamente para
a hélice de madeira Isso nos permite fazer coisas como animação baseada em
vértices através do sombreador para fazer a hélice
pareça estar se Um pouco complexo
para este projeto, mas os recursos existem se você
quiser estendê-lo posteriormente. Se
derrubarmos o elemento zero, queremos procurar
o material inimigo. E, claro, se
você seguir as etapas extras recomendadas
entre os tópicos, talvez tenha alguns
materiais diferentes para escolher. Selecionaremos
este, e você verá que meu avião ficou verde, então isso deve se destacar em relação ao
modelo e material padrão do avião do jogador. Em seguida, vamos querer adicionar um pouco de movimento ao nosso inimigo. Então, se passarmos para
o gráfico de eventos, faremos a mesma coisa de antes, removemos a sobreposição inicial do Acta Não vamos usar isso e
podemos nos concentrar no evento ti. Algo que é sempre útil adquirir
hábitos é realmente planejar com
antecedência os recursos que você
implementará. Poderíamos fazer isso, por
exemplo, analisando o
projeto de exemplos de conteúdo no qual estamos
baseando isso e detalhando as principais funcionalidades e recursos que os inimigos terão A primeira é que o movimento não é o mesmo dos jogadores. Não tem
aquele impulso falso ou esse tipo de
pseudofísica acontecendo É mais rápido,
eu apenas me movo para a esquerda, direita e para baixo na tela.
Então, temos movimento diagonal. Isso nos permite planejar um
pouco com antecedência , porque também
podemos ver as coisas quando o inimigo bate na parede e ela
muda de direção. Portanto, sabemos que precisamos fazer alguns
movimentos
para os lados e para frente
e, quando eles atingem
as paredes, precisamos fazer algo para
compensar a mudança direcional Estruturar nossos projetos
dessa forma
nos permite dividir
logicamente um problema maior em subproblemas que serão mais fáceis de resolver, e podemos dar
um passo de cada vez Então, para começar, a primeira
coisa que vamos querer
fazer é realmente adicionar
o deslocamento do ator,
o mesmo tipo de
deslocamento posicional que tínhamos Então, a partir do
pino EventiceExecution aqui, vamos
pesquisar a localização Então, novamente, muito parecido com o que
fizemos no player. Também queremos usar a mesma abordagem
para descobrir onde
o ator está no momento e seguida, adicionar um deslocamento a isso Então, usaremos a localização do ator
get e faremos coisas muito
semelhantes antes. partir daqui
,
procuraremos adicionar ou simplesmente pressionar
o botão de adição. Vamos descobrir o cálculo primeiro antes de conectar
qualquer coisa
e, depois de
terminar e pronto,
podemos conectá-lo e
testá-lo para ter certeza de que estamos começando com o
pé direito Já sabemos que
não queremos números mágicos, então podemos muito bem
criar algumas variáveis que eu
já posso ver que
precisaremos. O primeiro será um valor de
ponto flutuante para a velocidade de movimento. Só uma dica rápida aqui. Se você criar uma nova variável aqui, por padrão, ela
será um booleano Na verdade, podemos manter este
. A forma como estamos dirigindo o
movimento será verificar se
estamos nos movendo para a esquerda ou para direita. Então, enquanto temos isso? Vamos chamar
isso de movimento B para a esquerda. Então, isso era apenas para
dizer que sempre que você criar uma nova variável, você
receberá um booleano Um atalho que eu gosto de
usar, sabendo que
preciso de um valor de ponto flutuante
para a velocidade de movimento, semelhante ao que
usamos antes Podemos puxar
esse alfinete verde aqui. O verde indica que os segundos Delta são
um valor flutuante. Coloque isso no gráfico e clique em Promover para variável. Vamos dar a essa o
nome de velocidade de movimento. E essa é apenas uma maneira rápida de
obter uma variável do tipo que você está procurando
sem precisar usar o menu suspenso e
encontrá-la no gráfico Você pode fazer isso de qualquer
maneira, mas é
bom se precisarmos de um
vetor, por exemplo, podemos encontrar um vetor aleatório, colocá-lo no gráfico,
promover a variável e dar a ela um nome assim. A única coisa é que
precisamos fazer uma limpeza, então excluiremos os nós Ainda não precisaremos deles. Mas eu só queria
apresentar maneiras diferentes de trabalhar com o editor gráfico do Unreal
Engine O vetor foi apenas um exemplo, então selecione isso e exclua essa variável também. E
estamos prontos para continuar. Quando se trata do
movimento, já
abordamos a
independência da taxa de quadros e por que precisamos dela, para que
possamos incorporá-la desde o início. Se clicarmos com o botão direito do mouse e
pesquisarmos os segundos do Get Wild Delta , podemos usar isso em nossos próximos
cálculos. Para o movimento, vamos
querer medir nossa velocidade de movimento. E se clicarmos em Compilar e apenas certificarmos de que isso
tem uma variável, definiremos isso para
algo como 250 Isso seria
perfeitamente adequado para testes. E, como mencionei,
precisaremos de dois cálculos separados. Vamos querer um
para o movimento lateral e outro para o
movimento para frente na tela Para o movimento para frente,
podemos medir nossa velocidade de movimento. Podemos multiplicar isso por
um valor para inverter isso, então vamos considerar isso como negativo porque a tela abaixo, como mencionei,
é um valor negativo, e se você quisesse
subir na tela, seria um valor positivo Portanto, o movimento para frente do inimigo é, na verdade,
relativamente simples. E, é claro, queremos
multiplicar esse resultado por segundos
Delta para manter a taxa de
quadros independente Então, esse seria essencialmente nosso movimento para frente
pronto para ser testado. Para o movimento lateral,
vamos querer
fazer algo com
nosso valor booleano Então, vou pegar
a velocidade de movimento
e duplicá-la Vamos querer fazer
algo muito semelhante aqui onde vamos pegar
um nó de multiplicação, mas obviamente não
vamos querer
multiplicar apenas um ou menos um Precisamos transformar isso em algum tipo de operação
condicional A forma como vamos usar o booleano é um stick verdadeiro
ou falso Nós diríamos que estamos
nos movendo para a esquerda ou não estamos nos movendo para a esquerda,
então estamos nos movendo para a direita. Agora, se você tentou
isso, nr converterá
um booleano em uma multiplicação de
ponto flutuante Infelizmente, os booleanos
só são lidos como zero ou um, zero quando é falso,
um quando é verdadeiro Obviamente, isso
significaria que isso não funcionaria para nosso caso de uso atual, porque se estivéssemos multiplicando por
zero em vez de nos movermos para a esquerda, isso apenas pegaria
a velocidade do movimento multiplicaria por
zero, o que
cancelaria qualquer O que poderíamos fazer, porém, se pressionarmos Alt e clicarmos com o botão
esquerdo aqui, podemos usar algo
chamado de nó de seleção. Então, a partir
daqui, vamos pesquisar por Selecionar. E queremos essa opção na parte inferior. Isso
nos dá algumas opções. Se estivermos trabalhando
com coisas como números inteiros como curinga aqui, você pode ver que adicionamos qualquer
número de números Seja qual for o número inteiro que você colocar aqui, ou seja,
qualquer número inteiro, se você colocar um número
inteiro de um, por exemplo, poderíamos dar a
isso um valor negativo aqui Em vez disso, o que queremos fazer é usar nosso booleano Vamos
inserir isso no índice aqui, o curinga, e
o Unreal mudará isso para
ser um booleano para E podemos ver que
isso agora está definido como verdadeiro ou falso. Então, a maneira de
lermos isso para tornar isso mais intuitivo
e fácil de entender
é que, se quisermos ir para a esquerda,
estamos nos movendo para a esquerda? Se isso for verdade, então
o valor precisa ser menos um porque queremos mudar
para um valor negativo. Se mover para a esquerda é
igual a falso, então não estamos nos movendo para a esquerda, então queremos que o valor seja um. Então, essencialmente, isso
está indo para a direita. Isso está se movendo para a esquerda, e isso vai ser positivo e
isso vai ser negativo. Portanto, uma boa
maneira simples de usarmos um valor booleano para essencialmente ativar o movimento para a esquerda ou E então, quando você fizer
a mesma coisa novamente, usaremos nossos segundos Delta. Vamos fazer nosso cálculo aqui, multiplicá-lo por segundos
Delta para garantir que ambas as direções sejam independentes da taxa de
quadros, e poderíamos essencialmente
começar a conectar Então, só para manter as coisas organizadas, vou
puxar o pino vetorial aqui e pesquisar por make vector Então, já vimos isso antes.
Isso nos dará apenas os três valores de
ponto flutuante expostos. A frente em desenrolar
está no eixo X. Sideways está no eixo y,
e é mais ou menos isso. Nós podemos conectar isso.
Poderíamos testar isso e teríamos
um inimigo em movimento. Então, se clicarmos em compilar, salvar, voltaremos ao nível principal, podemos
simplesmente derrubar nosso inimigo Realmente não importa onde isso vai
ficar, desde que esteja um
pouco acima da
tela do player. Vou fazer
uma
rotação de 180 graus no eixo z, para que fique
voltado para o jogador. E então podemos clicar em play, e
devemos ver isso se movendo
para baixo na tela. Temos isso se movendo na
direção diagonal, que é a
parte inicial do problema. Então essa é uma
das etapas resolvidas. Acho que notei um
pequeno problema aqui. Parece que
vamos
atravessar a parede invisível. Então, sim, definitivamente fizemos o inimigo ultrapassar a parede invisível. Acho que está
dentro dos limites. Como mencionei, algo que
é muito fácil de esquecer, e acabei de fazer
isso de novo, é que
queremos garantir que
pressionamos o botão de varredura, então certifique-se de que
estamos varrendo e que não
devemos ter a mesma
funcionalidade do player, mas vamos simplesmente bater na parede
invisível Perfeito. Então essa é a
próxima parte do problema. Essa é a próxima etapa
que precisamos resolver. Quando o inimigo atinge a parede, queremos pegar essa informação e alternar a direção do
movimento E nós já meio
que temos isso configurado. Então, ainda temos nossa jogada.
Vamos mudar isso para verdadeiro e fazer com que eles se movam para a esquerda em relação à direção do
inimigo. Logo antes de
passarmos por isso, eu queria examinar
algumas
informações sobre o
tipo geral de organização do código,
coisas que poderíamos
melhorar aqui, mesmo
antes de fazer uma grande refatoração coisas que poderíamos
melhorar aqui, mesmo antes de fazer uma grande Eu coloquei
isso propositalmente para
torná-lo mais legível e compreensível Mas, na verdade, esse é um código
muito ruim antes mesmo de entrarmos no que
precisamos refatorar mais tarde Agora, a primeira coisa
é que eu só quero fazer com que as pessoas
comentem, algo
que eu
ainda não mencionei Se pegarmos um nó, por exemplo, e
pressionarmos C, podemos fazer um comentário. Uma espécie de
autodocumentação destinada a nos lembrar
o que algo era, por que o cálculo está
sendo feito, como foi. E também torna as
coisas mais legíveis à distância. Você não precisa
comentar tudo. Você pode ter visto
certos desenvolvedores compartilharem parte de sua base de código, e pode ter
havido comentários espalhados por toda parte Você pode ter visto coisas
assim em que eles têm uma variável ou algo
muito simples chamado velocidade de movimento, e eles fizeram um comentário dizendo apenas velocidade de
movimento. Isso é completamente arbitrário. Não faz nada.
Não é útil. E contanto que você esteja
nomeando suas variáveis corretamente ou com
alguma boa intenção, já
sabemos que
isso é velocidade de movimento porque esse é o
nome da Portanto, não precisamos
comentar assim. No entanto, se pegarmos isso e expandirmos para cobrir
todos esses nós, o que poderíamos fazer é mudar isso para dizer algo como mover a
direção, seguir em frente. E poderíamos até
tornar isso mais útil porque, se pressionarmos F dois para
voltar a renomear isso, também
poderíamos explicar
por que estamos usando menos um como multiplicação porque isso não
tem um valor Não tem a real
utilidade de ter uma variável. Portanto, é meio que válido ter um número mágico
aqui, mas,
à primeira vista, podemos esquecer por que menos
um está sendo aplicado, para que possamos deixar um comentário apenas descrevendo
o que está acontecendo Então, podemos dizer aqui que estamos
multiplicando isso por menos um para mover os inimigos
especificamente para baixo na tela Então faça uma coisa muito parecida.
Poderíamos pegar esses nós, pressionar C e fazer um comentário semelhante a
este. Este realmente não
requer nenhuma explicação. Eu acho que isso está bem claro. Se estivermos nos movendo para a esquerda,
pegue o valor relacionado à direção em que
queremos nos mover. A principal coisa que obtemos
ao fazer isso é que, se
começarmos a reduzir o zoom do gráfico, agora
podemos ver essa seção sem realmente
examinar o código Esta seção é para
avançar. Isso é para movimentos laterais. Se você já precisou se aprimorar
rapidamente e encontrar um trecho específico de código para corrigir algo ou
verificar novamente, sabemos exatamente
onde estão,
apenas o uso de comentários.
Eles podem ser úteis. Você não precisa
usá-los em todos os lugares, mas definitivamente em lugares onde você acha que pode esquecer o que está fazendo se voltar
em um ou dois meses. Agora, o principal problema que
queremos corrigir agora, porém, vou
excluí-los é que
atualmente estamos fazendo
várias duplicações Temos os segundos do G World Delta multiplicados duas vezes
aqui individualmente. Então, uma coisa que poderíamos
fazer, e isso pode não ter sido completamente
óbvio para começar, mas em vez de multiplicar os valores individuais de
ponto flutuante aqui, podemos multiplicar Então, se pegarmos os resultados
desse vetor make
que criamos, extraia daqui e
pesquise por multiplicar Podemos pegar um dos nossos segundos Get
world to Delta, pressionar Control X para cortar isso e controlar B para colar e
, em seguida, conectá-lo aqui. E RL converte isso em um
vetor multiplicado por um flutuador. Podemos inserir esse
cálculo aqui. E então podemos nos
livrar desse nó aqui, então não precisamos
mais desse múltiplo e conectá-lo. E podemos nos livrar
desses dois nós. Não precisamos nem um pouco disso e depois conectamos isso de volta ao Y. Então agora temos algo
um pouco mais organizado Não temos tantas
multiplicações acontecendo. Estamos pegando o vetor
inteiro agora, que fará a
multiplicação de X e Y
ao mesmo tempo em
relação aos nossos segundos Delta, garantindo que tudo
seja
independente da estrutura de todo o
cálculo Então, essa foi apenas uma
rápida organização do código. Então, se clicarmos em compilar e salvar, veremos que obtemos exatamente a mesma resposta para que
nada mude Ele parece e se move da
mesma forma que antes. A última coisa antes de deixar este tópico para uma
noite antes de fazer o fator Ru é que
todo inimigo começará
a se mover na mesma direção
e na mesma velocidade, que será um
pouco chato Se adicionarmos
alguns inimigos, podemos simplesmente segurar a tecla Alt e arrastar um widget aqui para
duplicar imediatamente Então, estou apenas segurando a tecla lt, pegando a
direção do widget e arrastando em uma direção que
duplicará o que Se apertarmos play, vai parecer algum tipo de
nado sincronizado Todos estão indo exatamente na mesma direção, na mesma velocidade. Vai ser um
pouco chato. Então, se voltarmos
ao início do jogo, mostrarei
como randomizar primeiro um
booleano para , pelo menos, mudar a direção em que
os inimigos
individuais podem estar se movendo.
Na verdade, isso é muito simples. Vamos segurar a tecla Alt e arrastar o movimento da lança para a esquerda
ao lado do início do evento. Ou você pode simplesmente colocá-lo
no pino de execução aqui. E então, a partir da variável,
queremos arrastar do pino aqui. Vou procurar
algo chamado bola aleatória. Então,
obteremos um booleano aleatório e definiremos isso
no BignPlay Tão super simples. 50% de chance de nos
movermos para a esquerda ou para a direita. Então, se pressionarmos play,
todos escolheram
seguir a mesma direção e
fizeram isso de novo. Podemos ver que há alguma
randomização, então isso é bom. Eles nem sempre
vão seguir exatamente na mesma direção. Então, um pequeno
exercício de aprendizado para você. A abordagem para fazer uma flutuação aleatória é
um pouco diferente, mas demore alguns minutos, pause
o vídeo e veja se você consegue implementar algo semelhante
com a velocidade do movimento Portanto, aumente a
velocidade de movimento e veja se você consegue encontrar alguma funcionalidade
integrada que o UNR possa ter
para nos permitir inserir um valor aleatório no
ponto flutuante Você pode randomizar isso
entre algo como 250, que atualmente é nosso
padrão, e talvez 500, para que cada inimigo se mova a uma velocidade ligeiramente
diferente Pause o vídeo,
experimente e comece a testar o quão confortável
você está se sentindo com o sistema de diagramas Ok, então
vou explicar como eu
teria feito isso. Se conectarmos isso e espero que
você tenha experimentado, novamente, eles serão muito valiosos
para realmente aprender a usar os planos, em vez de
apenas seguir meus passos Mas para que tenhamos
o mesmo código, no mínimo, ou
algo a partir do qual derivar. O que eu faria é pegar
minha variável de voo aqui. Vamos comprar
um apartamento aleatório. Essa é a única coisa que
pode ter te confundido, e você pode
ter querido experimentar algumas opções diferentes. Mas, em vez de
usar apenas flutuação aleatória, que
forneceria qualquer número, isso poderia ser muito
rápido ou muito, muito lento. Portanto, não é muito utilizável. Você também poderia ter tentado coisas como flutuar aleatoriamente do stream Mas o que eu
usaria seria essa flutuação aleatória no alcance Então, se selecionarmos
este, ele nos dará apenas dois pontos para escolher
do nosso mínimo, que eu
diria que seria 250, e dobraremos isso
para 500 como o máximo. Portanto, alguns aviões podem
obter esse mínimo de 250, outros podem obter 500 ou um valor intermediário. E lá vamos nós. Podemos ver que todos eles
começam em velocidades completamente diferentes, o que, novamente, tornará
as coisas um pouco mais interessantes quando começarmos a adicioná-los e eles estiverem funcionando corretamente no nível, ricocheteando nas paredes
e coisas assim Com isso, porém, os inimigos estão se movendo e
colidindo com as paredes Eles ainda não saltam e também não
interagiriam com o jogador Então, antes do grande fator Ruf, veremos a seguir a detecção de colisões, fazendo com que as coisas realmente aconteçam quando objetos se tocam
12. 11 — EnemyCollision: Tenha inimigos que se movem, mas
eles não reagem a nada. Idealmente, quando um inimigo atinge algo, precisamos
verificar o que é. É uma parede e, em caso afirmativo
, alterne a direção. Se for o jogador, podemos ver novamente no projeto de
exemplo que ele aplicou dano a
si mesmo e foi destruído. Então, o que
faremos é
destruir automaticamente o inimigo
se ele tocar no jogador. Os projéteis
se comportarão sozinhos, então pensaremos
nisso um pouco mais tarde Isso não será um
problema a ser considerado aqui. Uma coisa a mencionar é que
o sistema de colisão irreal é flexível e poderoso, o que, infelizmente, significa
que
é um tanto complexo Pelo menos quando você começa a
trabalhar com ele depois de experimentar algumas iterações
diferentes de diferentes tipos de coisas que
deseja fazer com ele, acho que ele clica muito rapidamente e é um
sistema bastante confortável de se trabalhar Então, vamos voltar
para o inimigo panorâmico. Podemos usar isso para
testes. Se pegarmos a malha estática e abrirmos a seção de colisão
no lado direito, basta rolar até aqui e
encontrar nossa categoria de colisão Se deixarmos isso cair, podemos ver a colisão predefinida aqui.
Vamos deixar esse aqui. Podemos vê-lo configurado como
bloqueado ou dinâmico. Portanto, esta é a nossa configuração de
colisão atual. O tipo de objeto também é
definido como dinâmico mundial aqui, então esse é o canal de
colisão com o qual esse objeto se identifica É por isso que, quando pressionamos play, o inimigo para nas paredes. Essa é uma
colisão física ou física em que os dois estão se bloqueando
e tentando não
habitar o mesmo espaço físico Agora, se derrubarmos
essa e
mudarmos para
sobreposição ou dinâmica, ou
seja, o equivalente,
mas para sobreposições,
clicaremos em
compilar e jogaremos mudarmos para
sobreposição ou dinâmica, ou
seja, o equivalente,
mas para sobreposições,
clicaremos em
compilar e O que veremos é que agora eles voltam pelas paredes. Agora, sob o capô,
algo está sendo disparado. Há uma mensagem
sendo enviada dizendo que esses três inimigos
acabaram de se sobrepor à parede Mas como não é uma interação
física, é apenas uma notificação e essencialmente, uma
observação de que eles estavam passando
pelo mesmo espaço. Você pode
pensar em bloqueio versus sobreposição como
um jogo de corrida Queremos que as paredes e os arredores
bloqueiem os veículos. Se colidir com eles,
você é parado. Queremos que os postos de controle
se sobreponham. Obviamente, queremos
saber se um veículo
passou por um posto de controle
e a que horas isso aconteceu,
mas não gostaríamos que esses
postos de controle começassem a impedir
fisicamente o prosseguimento dos
carros Isso seria um
pouco chato. Então, se voltarmos
para o peão inimigo, isso foi só para mostrar
como eles funcionam de forma diferente Também temos a terceira
opção. Temos a opção de ignorar. Agora, isso
provavelmente é bastante óbvio. Isso configurará isso para ignorar
todos os tipos de colisão. Poderia fazer isso, por exemplo, acessando a opção sem
colisão
e, embora
pareça que está configurado para bloquear,
isso está na verdade no código, lendo a opção Ignorar Agora, não haverá
nenhuma mensagem disparada. Nada sabe realmente que o
avião está passando por ela. E isso é bom para objetos que não precisam ser adicionados à pilha de chamadas e
à pilha de
verificação de colisão . Muito
bom para o desempenho. Mas, geralmente, trabalharemos com sobreposição ou bloqueio, dependendo do que
precisamos que eles façam Nesse caso, podemos
voltar ao padrão, que
é a dinâmica de blocos. Eu fiz isso
apenas pressionando aqui. Você pode ver a pequena seta. Se você quiser redefinir
as propriedades para o padrão, basta pressionar isso,
e isso voltará ao que era antes de ajustarmos
as coisas Com a malha estática
ainda selecionada, queremos rolar ainda mais para
baixo no painel de detalhes
até a parte inferior. E temos essas opções
aqui, os eventos. Agora, não vamos
passar por todos eles. Novamente, as coisas em que
mais nos
interessaremos serão
o impacto de um componente. Isso acontece quando duas
coisas se
bloqueiam fisicamente e um
componente começa a se sobrepor
e, às vezes, na extremidade do
componente Eles são chamados quando
dois objetos sobrepostos entram
ou saem Portanto, podemos obter a sobreposição final
porque, como vimos, colisões
sobrepostas
permitem que os objetos
habitem o mesmo espaço habitem Queremos vincular
nossa verificação de parede à função de início de
batida do componente on aqui Isso cria um novo
evento de cliente para nós, então a função, que é chamada toda vez uma colisão é detectada
em nossa malha estática Então, se você se lembra,
toda vez que criamos nossa classe e tínhamos aquela função padrão, realmente não
precisávamos da verificação da função actor hit,
que sempre excluímos. Isso foi essencialmente algo
semelhante,
mas, como mencionei,
para toda a turma. Já que agora podemos nos concentrar
e
verificar especificamente se apenas a
malha estática foi atingida, podemos fazer
algo depois Esses nós, na verdade, fornecem
muitas informações. Por exemplo, se
clicarmos com
o botão direito do mouse no pino da estrutura de ocorrência aqui e
selecionarmos
a opção de dividir a estrutura,
podemos ver todas as informações que podemos recuperar sempre que algo nos
atinge ou
atingimos algo. Podemos
descobrir a hora. Podemos descobrir se o
bloqueio foi bem-sucedido. Podemos ver o
local real do impacto e o ponto de impacto. Podemos obter coisas como
a rotação a partir disso, o tipo de
material físico e assim por diante. Não precisamos de tudo isso no
momento, mas é útil,
novamente, quando você começa a ficar mais avançado e confortável
com o irreal Se quiser fazer coisas sofisticadas
com coisas como penetração de
balas ou o tipo de resultado que acontece
quando duas coisas colidem, você pode definitivamente mergulhar
aqui e entanto, clique com o botão direito em qualquer um
desses pinos recombine o pino da estrutura
apenas para arrumar esse As principais coisas com as quais costumamos trabalhar quando
trabalhamos
com colisões são
saber um pouco de informação sobre
o outro ator,
porque, no momento,
não sabemos o que nos atingiu Só sabemos que fomos
atingidos quando isso foi chamado. Pode ser a
parede, pode ser um jogador, pode
ser outro inimigo. Então, isso vai se tornar
útil para ler mais tarde, então podemos também promover
isso para uma variável agora, e chamaremos isso
de ator de sucesso. E é por isso que eu só queria
dedicar um momento rápido para percorrer diferentes
maneiras pelas quais você poderia até mesmo considerar
abordar a solução desse problema,
descobrindo o que nos atingiu Em muitos projetos estudantis
que eu reviso e com os quais trabalho, vejo muitos lançamentos porque muitos
tutoriais muito básicos que você pode encontrar on-line tendem a mostrar como transmitir
para outros objetos, porque é uma maneira rápida e simples de
obter Em nosso projeto, o que estamos fazendo é relativamente pequeno e
simples,
então, na verdade, não pareceria muito ruim. Mas se você fosse
seguir esse caminho, talvez tivesse algo que
acabasse parecido com isso. Eu só vou fazer uma rápida
pausa. Corte rápido Como eu disse, isso é essencialmente
o que você acabaria com. A maneira como um elenco funciona, e eu quero apresentar
a vocês o elenco de qualquer maneira, a forma como o elenco
funciona é que, quando estamos trabalhando com
nosso outro ator, se
destacarmos o alfinete aqui, podemos realmente ver
o que está sendo devolvido. Então, vou clicar em compilar. E eu passo mouse sobre as informações do outro
ator Isso está nos mostrando
que isso está fornecendo uma referência para o ator. A razão é que, se
nos lembrarmos hierarquia
de herança da
Unrelengin, tudo com o qual
podemos interagir
no mundo que tem
uma presença física,
essa transformação precisa
ser de um essa transformação precisa
ser Então, ao fornecer um alfinete aqui, que é o objeto mais básico que podemos encontrar
no mundo, um ator, podemos garantir que possamos
comparar tudo e, em seguida, nos
concentrar especificamente no tipo de ator, funcionalidades
e recursos extras
que ele contém Agora, a maneira de
fazer isso, ou eu já vi isso muitas vezes em muitos
tutoriais, é que
eles mostram que você
pega algo como o ator que você atropelou
e nós contrariamos isso E o que é isso é
essencialmente uma pergunta. Está dizendo que esse ator genérico, eu posso ver que o
ator genérico existe. É especificamente o
tipo de base de peões, que para nós é o jogador Se for, então isso é
verdade, sim, é uma base de panela, então
faça isso aqui. Então, chamaríamos a função
específica da classe do jogador,
que, como mencionei, é aplicar dano ao jogador
e depois se distrair Se não for, então, se
fizermos essa verificação e ele voltar como não sendo
o jogador que atingimos, então acertamos outra coisa.
Então, iria para o elenco f. E então você veria
pessoas fazendo um segundo elenco. Então, ficamos como uma
cascata de fundição, que é E se entrarmos em projetos
muito maiores, você pode ver que só temos
três coisas a considerar. Mas se tivermos
coisas diferentes, como picapes obstáculos
e muitas outras coisas que
talvez precisemos considerar, teremos uma cachoeira em cascata muito
maior Mas a próxima coisa que você pode
fazer novamente é
voltar aqui e
dizer que o objeto genérico, o ator genérico, é
especificamente um inimigo? Se for, faremos as coisas
do inimigo, o
que, no momento, ainda não decidi como
vamos lidar com os inimigos. Acho que eles vão se superar
gradualmente, mas precisamos fazer essa função. Caso contrário, verificaremos novamente. Então, podemos
usar algo como o volume de bloqueio, se as
coisas estiverem bloqueando o volume, se isso for verdade, então sim, batemos em uma parede e
mudaremos de direção. Portanto, essa é uma maneira de
você ver isso feito. Pode ter sido assim que
você pensa em fazer isso se estiver ciente do
que o elenco faz. E eu só queria fazer um resumo geral de por que não faremos
isso e por que devemos tentar evitar
isso sempre que possível É outra coisa que
se repete com muita facilidade como a
declaração geral de nunca usar carrapato Você ouvirá as pessoas dizerem que
nunca use o casting. Novamente, isso é
realmente muito simplificado. Há vários motivos pelos
quais gostaríamos de usar a fundição onde ela possa ser totalmente segura e
muito barata de fazer. Está um pouco fora
do contexto desse tópico. Então, no momento, vamos apenas dizer,
eu vou deletá-los. Não faremos isso
simplesmente porque
não queremos esse efeito de
cascata Onde estamos verificando por objeto. Então, para simplificar as coisas, vou
dividir isso em duas coisas diferentes para este projeto que queremos
muito verificar. Queremos verificar a parede
e queremos verificar
o jogador humano. Acho que, apenas para criar o jogo
e para fazer com que ele se sinta melhor, acho que vou
deixar
os inimigos se
enfrentarem para que o jogador só precise considerar o caminho
que está tomando entre o
impacto e as paredes. Então, isso realmente
os torna muito, muito simples. Para começar, podemos fazer uma
verificação muito simples. Podemos clicar com o botão direito do mouse
no gráfico do evento e pesquisar
por Obter peão do jogador Portanto, essa é uma função embutida. O motor Unreal está sempre rastreando o que é classificado
como peão do jogador, que é o que o jogador
humano Então, quando pressionamos
play, essa seria a nave azul. Então,
o que podemos fazer aqui? Isso evita a fundição, o que
é uma coisa útil. Não precisamos obter todas
as informações
dessa outra classe. Isso também significa
que, se tivéssemos mais recursos, como deixar o jogador escolher entre cinco
classes de plantas diferentes com navios completamente exclusivos, novamente, não precisaríamos
comparar cada navio exclusivo Só precisamos saber se
o que
atingimos é uma nave de jogador, e saberíamos disso
a partir desta verificação aqui. Então, podemos retirar desta caixa
e procurar por dois iguais, ou
seja, apenas dois sinais de igualdade. E vou desengatar isso
para torná-lo um
pouco mais legível Conecte isso de volta.
Podemos apenas dizer: É o ator de sucesso? Então, a coisa com a qual
acabamos de colidir também
é especificamente
a coisa que o jogador
está controlando Podemos então extrair
nosso booleano aqui. Podemos procurar uma filial.
Podemos inserir isso em nosso pino de
execução e simplificar o código que
precisamos verificar. Então, se a coisa que
atingimos for o jogador, se isso for verdade, então
vamos causar nosso dano. Então, talvez queiramos apenas uma sequência de caracteres impressos aqui para nos
lembrar de voltar. Então, vou usar uma
string de impressão porque ainda não temos funções de
danos e
coisas assim, mas vou torná-la grande e negrito para que, toda
vez que isso acontecer, isso nos lembre de
voltar e alterar o código. Então, é aqui que
aplicamos danos ao jogador. E então, a destruição de nós mesmos é, na verdade,
muito simples Só precisamos chamar a
função destroy actor. Podemos colocar isso
aqui. E isso na verdade, faz parte do conjunto de
recursos, já feito. Então, agora, se eu deixasse os aviões
inimigos
caírem, eles estariam prontos
para causar danos, embora ainda não tenhamos saúde
e tudo mais, e então eles se
destruirão. Agora, partindo do galho falso, novamente, na
verdade, muito simples, agora nos diz que,
se vamos
permitir que os inimigos se superem
, não estamos
preocupados com isso, o que significa que ,
se batermos em outra coisa terá
que ser uma parede. Essa é a única
outra coisa com a qual
podemos colidir
neste projeto Então, podemos fazer isso
a partir da ramificação falsa aqui. E o que queremos
fazer é
definir o movimento para a esquerda. Então, vou conectar isso
ao pino de execução. Mova isso para cá. E, novamente, apenas para considerar a maneira como
você pode fazer isso. Quando você está se
acostumando com o fluxo de código, você pode ficar tentado
a usar um Banchon então estou apenas pegando Isso os
conectará automaticamente e você poderá fazer
algo assim. Portanto, verifique o valor do movimento para a esquerda. No momento, estamos nos
movendo para a esquerda? Se sim. Então, se a esquerda for verdadeira, então
queremos que isso seja falso, e se a esquerda não for verdadeira, então queremos que isso seja
invertido e transformado em verdadeiro Então, essa é definitivamente uma
maneira de fazer isso. Mas, novamente, eu só quero mostrar uma
maneira limpa de fazer isso. Então, se colocarmos isso de volta aqui, podemos movê-los para fora do caminho. Na verdade, vou
excluí-los do nosso booleano aqui,
vou puxar e
pesquisar algo chamado bola de nó ou não A maneira como isso
funciona é basicamente se isso for verdade,
isso retornará falso. Se isso for falso,
isso retornará verdadeiro. Então, podemos pegar esse valor
e, essencialmente, ele
sempre
inverterá qualquer que seja o booleano
atual Então, se estivermos nos movendo para a esquerda, isso nos
fará mover para a direita, e se estivermos nos movendo para a direita,
isso nos fará mover para a esquerda. Então, uma
versão simples e bonita do que poderia ter sido uma
estrutura de ramificação extra da qual não
precisávamos. E
é mais ou menos isso. Ou seja, nossa saúde
sendo
contabilizada quando abordamos esse
assunto um pouco mais tarde,
a destruição ao entrar em
contato com o jogador
e, em seguida, a mudança de
direção quando batemos em uma parede Então, se voltarmos e
apertarmos play, podemos ver que eles estão se
recuperando, que eu acho que seria uma implementação
perfeitamente boa, dependendo de você E então, se eles
atingirem o player,
podemos ver no canto superior
esquerdo a sequência impressa
estava sendo chamada e eles estavam sendo removidos. Então, novamente, tudo
se resumirá ao design. Se você quiser que eles se
recuperem, podemos deixar essa
funcionalidade ativada Se você quiser que eles se
superem gradualmente, mostrarei isso quando
entrarmos mais tópicos de colisão,
um pouco mais tarde Mas é isso. Agora temos
uma implementação funcional. E, como mencionei, a razão pela qual
isso está funcionando é toda vez que uma colisão é detectada nesta classe agora, será automaticamente disparada Ele está rastreando todas
essas informações sobre o que foi atingido
e o que aconteceu, e então
extrapolamos a partir dessas informações o
que é
relevante apenas para o nosso projeto Vamos fazer
algo muito inteligente com os projéteis, então também não precisaremos considerar projéteis quando eles
atingirem o inimigo Isso será tratado
no código do projétil. Então, tudo o que o inimigo precisa
saber é o jogador
e as paredes, que na verdade é outro princípio de
programação, que é muito
importante, especialmente em linguagens como C plus
e blueprint, porque basicamente ainda se baseia nesse fluxo de trabalho no engem real O conceito geral é
que tentamos tornar uma turma o mais específica
e pequena possível. Então, foi feito para fazer uma
coisa e uma coisa bem. Um exemplo de código incorreto
em uma classe inimiga
seria rastrear quais captadores
o jogador pode ter segurado, verificar coisas como qual
projétil acabou de atingi-lo, quanto dano esse
projétil deve causar e coisas assim, porque
essa é a lógica Todas as coisas relacionadas
aos danos causados por um
projétil devem ser armazenadas no projétil e essas informações devem
ser repassadas O inimigo só deve considerar e
ser responsável por coisas relacionadas ao
inimigo. E neste caso, isso é se mover e bater em paredes, uma entidade
muito simples Então, apenas outra rápida
olhada no que seria classificado como código
limpo é
o encapsulamento de garantir que sua classe,
em geral, a regra seja, como eu disse, fazer uma
coisa e fazer uma coisa bem Com isso configurado
e pronto, porém, agora
temos uma turma completa
pronta para ser reestruturada Então, a seguir, vamos
examinar o tópico da herança. Essa será a melhor
maneira de lidar com muitos códigos e
recursos
compartilhados que estamos vendo
atualmente no
inimigo e no jogador. Estamos duplicando
muito trabalho, então será
hora de corrigir isso
13. 12 — Base Class de herança herança: É hora de consertar a bagunça
que fizemos. Duplicamos a configuração da malha. Estamos lidando com
o movimento de forma diferente, mas seguindo a
mesma lógica estrutural duas vezes. Isso parece
pequeno no momento. Mas quando adicionarmos
saúde, destruição e
efeitos, tudo isso
começará a se agravar. Cada recurso compartilhado significa o
dobro do trabalho para nós, mas também
significa potencialmente o dobro dos bugs. Também na
classe de peões, atualmente
estamos usando
toda a malha como um colisor, que realmente não é ideal
para esse tipo de jogo A maioria dos
jogos de ação ICD como esse, na verdade, usa um truque para fazer
o jogador se sentir um pouco mais inteligente do
que realmente é Quando você pensa que se
esquivou de algo com habilidade, mas na verdade acabou de
sobreviver, é bom,
mas isso porque seu
colisor provavelmente é
um pouco menor do
que um pouco menor do Vamos querer
implementar algo
assim para que comece a
parecer realmente interessante
interagir com
nosso jogo . Apenas uma pequena forma de manipulação
psicológica, mas faz com que o jogo pareça justo, mesmo quando a matemática
diria o contrário A maneira de resolvermos
isso é usando um
colisor de esferas como a nova rota
em vez da malha A malha funcionará apenas como decoração
totalmente
livre de colisões Ambas as classes precisarão disso, então podemos muito bem construir
isso apenas uma vez e compartilhar componentes e recursos como esses em
todas as classes. A maneira de fazer isso é com algo
chamado herança Já mencionei anteriormente que
o UnrelEngine é um software altamente
baseado em herança,
então seguiremos o
mesmo tipo de então seguiremos o
mesmo Basicamente, significa que
podemos codificar algo uma vez no que é chamado de classe
principal ou base. Podemos então criar
classes secundárias disso, que herdarão todos os
componentes,
os recursos e os
sistemas que inserimos Por exemplo, vimos os
atores fornecerem uma transformação,
uma escala de rotação de localização no mundo,
e então os peões
pegam essas informações e constroem sobre elas
, recebendo a mecânica a ser
possuída e muitas outras e constroem sobre elas
, recebendo
a mecânica a ser
possuída e muitas outras
coisas.
Chega de falar. Vamos ver isso em ação.
Então, vamos começar a criar nossa nova classe base que nos
ajudará a ver o
sistema na prática. Se voltarmos às
plantas e à pasta principal, criaremos
algo completamente novo Clique com o botão direito do mouse na
janela e voltaremos para a classe
Blueprint e
criaremos um novo peão Vou mudar isso de
ser chamado de sublinhado de peão para base
plana de
sublinhado da BP em vez Todos eles serão
aviões, então podemos deixar claro nossa convenção de
nomenclatura aqui Dentro de nossa nova classe,
abordaremos os componentes e adicionaremos o componente
esférico que mencionei. Não estamos procurando
esse aqui. Esta é uma esfera visual sólida em três D. Só queremos uma ligação em colisão. Se pesquisarmos
a palavra colisão, podemos ver aqui que temos
algumas opções diferentes Queremos nosso colisor de esferas, que aplicará isso aqui, e podemos fazer a mesma
coisa que fizemos antes Podemos arrastar isso para
a raiz padrão da cena para torná-lo nosso
novo componente raiz. Em seguida, podemos voltar
ao botão Adicionar. Ainda queremos nossa malha estática. Isso simplesmente não vai
mais
lidar com colisões . Faremos a
mesma coisa novamente. Vamos até nossa
malha estática aqui e
selecionaremos nosso herói do plano de
sublinhado SM Com a malha estática
ainda selecionada, podemos ir até a seção de
colisão aqui
e, na verdade, podemos simplesmente
usar essa lista suspensa e pedir que ela não faça nenhuma
detecção de colisão Também podemos desativar a
sobreposição de eventos gerados. Isso apenas garante que
nada esteja sendo verificado relação à
malha estática em nenhum ponto. Perfeito porque queremos que
isso seja visual. Isso significa que ele não precisa ser
adicionado à pilha de colisões Está meio que sentado
lá sendo renderizado. Se também selecionarmos nosso colisor
de
esferas , podemos fazer
algumas alterações aqui Se colocarmos isso
no lado direito na seção de colisão novamente, queremos mudar isso
de sobreposição ou dinâmico, e podemos realmente tornar isso
mais distinto do que isso,
e diremos que isso seja
classificado como uma Então, veremos que
isso muda a predefinição de colisão para O tipo de objeto agora é
rastreado como um peão e é feito algumas
coisas aqui Não vou deixar por isso mesmo se quisermos flexibilidade total. Vamos considerar isso como
a predefinição padrão, mas podemos
personalizá-la
soltando-a novamente e
selecionando Então, ainda temos
esse conjunto como peão. Ainda temos as configurações de colisão
ativadas conforme desejamos e temos tudo
isso definido por padrão podemos achar que queremos No entanto, podemos achar que queremos
voltar
e fazer com que isso não se sobreponha a outros peões
ou bloqueie outros peões, faça algo diferente
com a estática mundial, e agora temos a
opção de
alterá-la se quisermos.
Não faremos isso agora. Faremos isso com
base em testes e vendo como o projeto se desenrola Com isso feito, isso está
nos colocando em uma
posição muito boa, no entanto. Cada classe secundária
agora herdará esse conjunto. Então, isso significa que
configuramos isso uma vez e nunca mais
precisamos pensar nisso novamente. Então, agora podemos começar a analisar nossa funcionalidade compartilhada, bem
como na captura de eventos, o tipo de coisas
que queremos
compartilhar entre as duas classes. Como sempre, vamos pegar
o evento para começar a sobrepor
e excluir este E para o movimento,
há algumas coisas a considerar. Mais uma vez, apenas com base na recriação
do projeto de exemplo estamos tentando atingir algum nível de paridade: há
um pequeno recurso se você realmente
observar o que está acontecendo quando os aviões e
o jogador não se movem ou alinham o movimento no
início Eles reproduzem uma pequena
animação. Eles animam a tela por
talvez um ou dois segundos
e, em seguida, permitem que o
movimento vá para os lados Então, vamos fazer
algo muito parecido. Vamos congelar ou pausar qualquer entrada de movimento até que a
animação seja lançada. Veremos as animações
na seção de aprimoramento, mas precisamos
pensar novamente no que
precisaremos
considerar e podemos
programar isso agora Então, vamos começar com
isso. Vamos querer fazer uma verificação muito simples e
lógica. Então, se retirarmos
nosso pino de execução, vamos
procurar uma ramificação. E da filial, podemos
medir a condição aqui. Vamos promover isso para uma
variável imediatamente. Chame isso de B,
movimento ativado. Vamos clicar em Compilar e
garantir que o
padrão seja verdadeiro. Então, se o movimento estiver ativado, que
queremos fazer enquanto estamos apenas depurando antes de configurarmos a animação,
se o movimento estiver ativado,
permitiremos que movimento estiver ativado,
permitiremos o inimigo voe de um lado para o outro e desça pela tela,
e permitiremos que o jogador
voe de um
lado para
o outro com base na Caso contrário, isso significa que
provavelmente estamos na animação e chamaremos a
função false aqui e impediremos qualquer movimento aconteça.
Então, isso só nos configura. Mais tarde, quando chegarmos
a esses recursos, pensando no futuro, não
precisamos refatorar completamente
o código novamente. próximo passo é que as duas classes precisarão de algum tipo de movimento. Mas, como mencionei,
estamos programando o movimento de
forma um pouco diferente, então não podemos compartilhar o código de movimento
real porque não há o mesmo
tipo de movimento sendo usado. Mas o que podemos fazer é compartilhar o fluxo lógico e os conceitos da
funcionalidade que precisaremos. Podemos fazer isso dando
uma olhada nas funções agora. Então, no lado esquerdo,
temos essa
categoria de função aqui. Assim como os eventos,
podemos criar nossas próprias funções personalizadas
e, em seguida, chamaremos a lógica quando essa função for
chamada da mesma forma que fizemos
com eventos no passado. Então, se pressionarmos mais aqui,
e eu vou chamar essa nova função,
criamos o movimento da alça. E você pode ver uma
das diferenças aqui Na verdade, um
dos principais benefícios de usar funções em vez de eventos é que elas fazem
praticamente a mesma coisa. Eles respondem ao serem chamados, mas aqui temos nosso
próprio gráfico de funções. Então, está meio
escondido e, novamente, mantendo as coisas bem arrumadas Agora, não vamos realmente
lidar com nenhuma das
funções de movimento aqui. A forma como isso será
usado é que
substituiremos essa função em
nossas classes filhas posteriormente, mas precisamos que ela exista
para ter algo para chamar O que queremos fazer é voltar ao gráfico
de eventos. Queremos usar nossa função de
movimentação de alças. E vamos
colocar isso no pino verdadeiro. Então, se um movimento estiver ativado, chamaremos a função de movimento da
alça. Então, novamente, ele se torna
agradável e legível. E quando
realmente implementamos isso, podemos ter uma ideia do que
exatamente vai
acontecer. Então, isso é meio
simples por enquanto. Você verá isso se desenrolar
e fazer muito mais sentido quando realmente começarmos a
implementar as coisas Essa é uma daquelas coisas
em que eu poderia tentar passar cinco a 10 minutos descrevendo
o que faremos mais tarde, mas acho que
fará muito mais sentido simplesmente implementá-la à medida que avançamos. Outra coisa é que
ambas
as classes simples precisarão do inimigo do jogador e dos chefes
ou
do que você quiser começar a herdar dessa classe Todas precisarão ser destruídas ou
mortas em algum momento Então, enquanto estamos aqui, podemos muito bem
adicionar outra função, e vou chamá-la
de handle death. Novamente, não vamos colocar
nada aqui agora, mas uma coisa que podemos
fazer com essa função, coisas genéricas, como tudo,
precisarão reproduzir um efeito sonoro ou um efeito de partícula
quando eles morrerem Podemos fazer isso
nesta classe aqui porque essa é uma função
universal. Isso é algo que, independentemente
do tipo de avião, todos
precisam mostrar algum tipo de feedback
quando isso acontece. Portanto, podemos fazer a
funcionalidade universal aqui. E então, se houver
algo exclusivo no plano individual, podemos substituir novamente a funcionalidade que
está acontecendo aqui e ,
em seguida, fazer algo além disso Então, apenas uma
ideia aproximada de como a herança
funciona e como podemos
usar esse código reutilizável,
economizando tempo e
esforço à medida que avançamos Agora, a última coisa que
eu posso imaginar que ambas as classes de aviões precisarão é a velocidade de movimento. E nós
meio que já sabemos disso. Se analisarmos nosso próprio código, uma das poucas coisas
que os dois têm é abrirmos os
gráficos de eventos,
pan base, ou seja, o player tem muito mais funcionalidades Há muito mais
variáveis aqui, mas tem velocidade de movimento. E então a panela é um pouco
diferente, simplificada. Embora não estejamos
fazendo a
verificação de movimento para a esquerda na versão para jogadores, ainda
estamos usando a velocidade de
movimento. Então, coisas assim
são o que estamos
procurando em nossas classes básicas. Coisas que tivemos que
implementar mais de uma vez são algo que
poderíamos simplesmente colocar diretamente na classe base Então, aqui, o que eu vou
fazer é criar uma nova variável chamada
essa velocidade de movimento. E trocamos este
por um flutuador, empilhamos e salvamos E sempre que
precisarmos usá-los
entre as aulas, estarão disponíveis
e prontos para uso. Novamente, ainda não
precisamos usá-lo,
mas isso está apenas estabelecendo
as bases para que tenhamos uma transição mais suave e
agradável E, na verdade, essa
é
a nossa classe base desenvolvida tanto
quanto precisamos agora Podemos voltar e
adicionar coisas mais tarde, mas temos os
componentes compartilhados de que precisamos: a colisão unificada, o movimento pronto para ser implementado em cada turma infantil mesmo vale para a morte
e, em seguida, para a
variável de velocidade pronta para uso. Então, só para dar uma
olhada
rápida em como podemos usar
essa classe base, adicionaremos a funcionalidade completa
um pouco mais tarde, mas com uma demonstração muito rápida. Se voltarmos ao
nosso sorteio de conteúdo, podemos clicar com o botão direito do mouse
na Base simples. E aqui em cima,
temos a opção de
criar uma classe secundária de Blueprint Se clicarmos neste, isso criará um novo
modelo para nós Isso herdará
tudo do Base simples. Vou chamar isso de jogador de avião BP
underscore. E então, se
clicarmos duas vezes para abrir este, podemos ver que
agora vem pré-construído com nossa esfera e
nossa malha estática. Também temos algumas outras
coisas aqui. Se clicarmos na opção de substituição,
podemos ver, na verdade,
as funções que criamos manualmente, lidar com a morte e
lidar com o movimento, especificamente em
nossa classe base Se clicarmos neles, isso nos dará uma
função para que possamos começar a usar a
versão principal da função , como mencionei, fazer
nossas próprias coisas
além e, como mencionei, fazer
nossas próprias coisas
além disso. Nossos controles de pressão para
se livrar desse por nove. Ainda não queremos fazer nenhuma
substituição e não precisamos
mudar nada ainda, mas eu também
gostaria de mostrar outra maneira adicionar classes com
base nas que temos Se você voltar ao
sorteio de conteúdo mais uma vez, clique com o botão
direito aqui
e, desta vez, vamos
assistir a uma aula de diagramação, algo que pode
não ser muito óbvio Mas muitas pessoas pensam
que isso se restringe às classes de mecanismos
irreais e às criadas por desenvolvedores
não relengin Mas, na verdade, assim que
criamos uma classe, podemos realmente encontrá-las aqui. Então, se eu procurar uma base simples, podemos ver aqui que a
base simples é filha de um peão e um peão, como eu
disse, é filho de um ator E nosso jogador simples está
em uma criança de base simples. Então, agora podemos selecionar nossas próprias classes da nossa
lista de classes aqui no editor. Então, selecionaremos a base simples
novamente. Selecione este. E, claro,
vamos chamar esse avião
BP Underscore Então, ambos estão prontos para começar quando começarmos a
desenvolver as coisas. Só queria
mencionar, também, que existem várias
maneiras de
usar suas classes básicas quando você as tiver
prontas e configuradas. Feito isso, a
classe base está pronta, no entanto. Como eu disse, temos
os componentes compartilhados, a funcionalidade compartilhada e a configuração unificada de colisão Em seguida, vamos
refatorar o player primeiro. Pegaremos o grande
, examinaremos o código fragmentado que
vamos percorrer
e depois nos concentraremos
no inimigo
14. 13 — RefactoringPlayer: A aula está pronta para começar.
Então, agora vamos precisar converter nosso player
para fazer uso disso. Isso é conhecido
como refatoração,
essencialmente reestruturando o código
existente sem alterar Nosso objetivo é
o mesmo comportamento mas uma melhor organização e redução da sobrecarga ou da reutilização de
variáveis, componentes e coisas do tipo, sempre que
possível Percebi que, no tópico anterior que
acabamos de abordar, dei instruções para
criar duas novas classes de aviões. Há uma outra coisa que eu percebi no meio
que poderia ser útil conhecer
e, na verdade nos
pouparia um
pouco mais de tempo. Então, o que eu vou
recomendar é que, na verdade,
excluamos o inimigo simples
e o jogador comum. Assim, podemos pegar esses Shift
Select e pressionar Delete. , não fizemos
nada nisso, então não estamos perdendo
nada e, pelo menos você sabe que essas
opções estão disponíveis. Em vez disso, o que eu sugeriria é ,
se formos para nossa base aérea e eu as fechasse
para não confundir as coisas, queremos clicar duas vezes e abrir a classe base do avião na
qual estamos
trabalhando para
garantir que você não excluiu a classe base do avião Então, com a base do avião ainda aqui, não
queríamos nos
livrar dessa. O que queremos fazer é
realmente usar
as classes existentes e simplesmente
mover as coisas para onde precisamos. Então, a primeira coisa é
focar em nossa nomenclatura. Se focarmos no
jogador em primeiro lugar, vou
renomeá-lo para BP, sublinhando E é por isso que
precisávamos excluir essas outras classes para
não termos conflitos de nomenclatura O nome da classe estava bom, mas podemos fazer
algo bem inteligente aqui para usar o que já
temos nessa classe. E faremos o
mesmo com nosso inimigo. Então, vamos pegar esse e chamá-lo BP underscore
plain enemy E então, se clicarmos
duas vezes para abrir o player do plano de sublinhado da BP, podemos começar a fazer
nossas alterações Então, o que achei que
seria útil
saber é que, na verdade, existe
uma maneira muito legal mudarmos o que essa classe
está classificando como pai Então, no momento, podemos ver
a classe principal como peão. Se voltarmos aqui
para as configurações da classe e depois voltarmos
ao painel de detalhes, podemos ver que temos a classe
principal aqui. O menu suspenso está configurado para peão. Se procurarmos por avião,
podemos mudar isso agora herdar da base do plano de
sublinhado da BP E essa é, na verdade, uma
ótima maneira de refatorar as coisas. Um dos motivos é que ele nos
fornecerá erros e avisos sobre códigos
que podem estar duplicados E nós meio que
já podemos ver isso. Então, se olharmos para
o lado esquerdo, podemos ver que temos
duas malhas estáticas Qualquer coisa aqui que diga Editar em Blueprint ou Editar
em C plus, se você estiver trabalhando em um projeto
C plus, é uma indicação de que isso é
herdado de uma classe base Então, quando você vê isso, não
podemos entrar. Não podemos pegar os herdados e excluí-los, então
eles estão presos aqui Então, o que queremos
fazer é pegar nosso
sublinhado zero da malha estática Não precisamos de duas
malhas diferentes para nosso avião e podemos excluir essa, então vamos excluí-la aqui A outra coisa que podemos ver aqui é que temos algo chamado velocidade de
movimento com sublinhado
zero nas variáveis Se escrevermos, clique aqui,
podemos acessar as referências e encontrar todos os membros
atuais da classe. Se clicarmos duas vezes
neste, isso nos
levará diretamente
para onde está. Então, como mencionei,
é uma boa maneira
rápida arrumar
as coisas, porque podemos simplesmente usar esses atalhos
para pular e encontrar as coisas restantes das
quais talvez
precisemos nos livrar E, novamente, a razão pela qual
isso recebeu um sublinhado zero é
porque sabemos que
temos algo chamado velocidade de
movimento
na classe base e não podemos
ter a mesma variável, mesmo que esteja em uma
versão secundária dessa classe Então, faremos a mesma coisa
novamente. Vamos deletar esse. Vamos simplesmente deletar a velocidade de
movimento. Isso está apenas nos dizendo que
estamos usando isso no momento, mas está tudo bem
porque sabemos onde está. E então o que queremos
fazer aqui é partir
daqui e
procurar a velocidade de movimento. E podemos ver aqui que
queremos obter
a variável de velocidade de movimento, e essa é a da nossa classe
base, a classe de emparelhamento E lá vamos nós. Então
é basicamente isso. Essa é a aula meio
arrumada e pronta para começar. Então, definitivamente poderíamos
deixá-lo aqui, mas há mais algumas
coisas que podemos usar da classe principal. Portanto, a primeira coisa que sempre
queremos considerar é
o início do jogo, e precisamos fazer essencialmente em todas as
nossas funções. Mas para começar nosso jogo inicial, vamos
clicar com o botão direito do mouse no nó e queremos encontrar
essa opção aqui para adicionar uma chamada à função principal. E queremos conectar
isso entre nossa execução atual e a funcionalidade
que já estamos chamando. Isso apenas garante que
a lógica do início do
jogo dos pais também seja chamada
quando começarmos a jogar, que
significa que, se
tivéssemos novamente alguma lógica
universal que quiséssemos fazer
na classe principal, ela também será chamada. Caso contrário, isso só
será chamado sozinho e ignoraremos a versão dos
pais. Queremos fazer a mesma
coisa com o evento. Vamos escrever,
clicar nisso, adicionar chamada à função
principal e, em seguida, conectar
tudo. Incluindo os segundos Delta, talvez
precisemos mover
algumas coisas por aqui. E então podemos simplesmente
conectar isso aqui. E, novamente, arrume as
coisas se quiser. Tente ajudar a visualizar
isso para você, a funcionalidade principal
será chamada primeiro Então, por exemplo, quando nosso
jogador for criado pela primeira vez, ele automaticamente fará com
que seu evento início de jogo seja chamado uma vez
e, em seguida,
enviaremos
imediatamente uma mensagem para realmente dar uma olhada
na versão principal e ver se algo está
acontecendo para começar a jogar. Navegue até aqui. Podemos abrir o blueprint principal
com esse atalho aqui, e podemos
começar a jogar aqui, e podemos ver que não há código
real no momento se fôssemos fazer
algo como tirar No entanto, se fôssemos fazer
algo como tirar
uma corda impressa daqui, diríamos que os pais
começassem e a manteríamos na
tela por um momento. O que aconteceria agora
é quando pressionamos Play. Veremos que o
início dos pais está impresso na parte superior. Assim, podemos confirmar que
nossa lógica original, a lógica universal, está,
de fato, sendo chamada. Agora, o problema, é
claro, é se adicionarmos isso aos inimigos,
então, se entrarmos na classe de inimigos
simples, entraremos no início do jogo. Nós vamos querer
fazer a mesma coisa. Vamos clicar com o botão direito do mouse, adicionar uma chamada para
os pais e conectá-la aqui. Agora, como temos três
inimigos e um jogador, veremos essa
mensagem quatro vezes porque todos estão chamando
a mesma função. Obviamente, precisamos
fazer a mesma alteração nas configurações da
classe inimiga. Mude isso de
peão para base simples. OK. Então, estamos fazendo a
mesma coisa. Estamos apenas reparando o que essa
classe está herdando Clique em compilar. Então, todos os quatro estão seguindo
o mesmo processo. Agora, tudo bem, nesse caso, mas é aqui que você deve ter cuidado e começar
a se
certificar de que está considerando o que
está implementando. Então, isso e não faria sentido se essa mensagem
dissesse algo como, se fosse específico
do que o jogador deveria estar fazendo, como gritar, eu sou o jogador Se clicarmos em compilar, isso
significa o player do avião, chamaremos isso, o que
é perfeitamente normal Mas então, todos os inimigos. Então, todos os três inimigos também
estão dizendo: “Eu sou o jogador”, o que é
um pouco confuso Portanto, é aqui que você precisa ter
cuidado com a herança. E é por isso que
continuo dizendo que
queremos nossa
lógica universal aqui. Qualquer coisa que esteja relacionada
apenas a ser um plano geral
está perfeitamente bem. Então, se todo avião tivesse que se anunciar e dizer: “
Eu sou um avião”, tudo bem porque todos os quatro são, de
fato, aviões. Como podemos ver, não
gostaríamos de nenhum código
na classe base relacionado especificamente
ao jogador. Então, espero que isso faça sentido, e possamos
começar a ver como podemos usar a herança e como
podemos compartilhar nossos recursos, componentes e lógica
entre E é assim que vamos lidar com coisas
como destruição. Podemos fazer com que os efeitos de
partículas, todos os efeitos
sonoros sejam reproduzidos na classe principal,
porque isso não é específico de nenhum plano Todos eles precisam ser
destruídos de alguma forma. Mas coisas como o movimento,
que são um pouco únicas, vamos lidar com isso
nas aulas para crianças. De volta ao player normal. Primeiro de tudo, vamos terminar essa
. Uma maneira muito rápida
de pegar o código, que sabemos que
já está funcionando. Como mencionei, tudo o que realmente
queremos fazer é garantir que não
tenhamos isso espalhado e que possamos usar
essa função que criamos há pouco tempo Então, se pegarmos tudo
relacionado ao movimento, então esses serão esses
nós aqui, o cálculo aqui, eu estou apenas segurando a tecla Shift e
arrastando e , em seguida, a localização do
ator aqui Isso está relacionado apenas
à rotação, então vamos deixar
essa por enquanto. O que queremos fazer é
pressionar Control e X para cortar e clicar aqui para
substituir a função de
movimento da alça Então, queremos a função que
criamos anteriormente, esse espaço vazio. E então vamos
pressionar o controle V aqui e vamos
conectar tudo de volta. Assim, podemos garantir que nossa função de
movimento sempre
seja chamada porque
estamos chamando nosso evento. E se o movimento estiver
ativado, o
movimento da alça também será
chamado a partir desse evento. Então, novamente, só precisamos
chamar essa função uma vez aqui, e podemos fazer uso dessa
chamada
de função em nossas classes filhas. Mudamos isso e
vou voltar
ao gráfico de eventos. Vamos mover isso para trás, por enquanto, a rotação, e vamos
conectar isso de volta. E apenas testando à medida que
avançamos, como mencionei, isso é mais para mostrar como
você pode refatorar o código
sozinho, se necessário E esse é um processo muito
comum. Só queremos testar esses
pequenos passos à medida que avançamos, e ainda devemos ter
o movimento ativado. Então, se algo está quebrado,
deixe-me verificar
o que pode ser. Se o movimento estiver ativado, se isso for verdade, chamaremos nossos eventos Temos nosso movimento de alavanca
aqui, velocidade de movimento. Acabei de perceber que temos nossa nova
variável de velocidade de movimento na classe base, mas não
atribuímos um valor a ela. Então, se pegarmos nossas
configurações de classe aqui, isso realmente
nos dará acesso às
configurações da classe quando
selecionarmos esse elemento superior
aqui ou o padrão da classe Podemos ver que os padrões da classe
têm as variáveis aqui, e podemos ver nossa velocidade de
movimento, e acho que estava
configurando isso para 1.000 no player. Então,
vamos atrasar isso. E então devemos
ser capazes apertar play e nos movimentar. Então, obtemos o mesmo movimento,
obtemos a mesma rotação. Tudo parece o mesmo. Não alteramos
a funcionalidade. Acabamos de arrumar nosso gráfico e onde
as coisas são tratadas Então, estamos garantindo que isso
seja chamado se e quando
quisermos , e outro benefício
muito interessante agora é que podemos entrar Poderíamos desativar o
movimento ativado, para que o movimento não seja
mais ativado. Podemos apertar play e agora não
podemos mover o avião. Mas é claro que isso interrompe
a rotação porque
agora estamos multiplicando por um valor que realmente não faz nada Mas você pode ver que a
lógica é que estamos lidando com as coisas
da maneira que
queremos que elas funcionem. E tudo isso agora é tratado
na classe base em relação
aos estados de movimento ativado
e desativado, e estamos apenas aproveitando
isso
na versão para jogadores
dessa Portanto, certifique-se de clicar aqui. Vamos garantir que movimento esteja ativado
no momento. Vamos alternar isso
no código um pouco mais tarde, quando
chegarmos à animação Lembre-se de que eu disse que não
adicionaremos coisas como rotação ou
física falsa e coisas
da classe inimiga, é por isso
que não estamos reutilizando exatamente o código de movimento Outra coisa que os
inimigos não terão é a lógica de rotação real que
temos aqui por esse motivo. Algo que poderíamos
fazer, no entanto, para manter as convenções de nomenclatura e
o estilo geral iguais Tem outra dica
que eu queria mostrar. Podemos pegar todos
esses nós pressionando Shift Select
para capturar esses nós. E então, se clicarmos com o botão direito do mouse em qualquer um dos
nós que
selecionamos aqui, podemos optar por reduzir isso
para uma função própria. E vamos chamar isso
de “um”. Você provavelmente pode adivinhar. Vamos chamar isso de rotação de
uma alça. Bom e óbvio. Se precisarmos nos aprofundar nisso e começar a
ler nosso código, nisso e começar a
ler nosso código,
viremos do festival da base de
aviões
e podemos ver que, se
o evento continuar,
se tivermos o movimento ativado, manipule o movimento e isso sairá da classe base Então, uma vez feito
isso, isso
nos levará de volta à nossa classe infantil. Então, isso já foi
resolvido. O pino de execução será chamado e, em seguida,
começaremos a chamá-lo. Então, estamos lidando com o movimento
se o movimento estiver ativado, e então estamos
lidando com a rotação, novamente, se o movimento estiver ativado. Exatamente os mesmos resultados se pressionarmos play,
nada mudou. Estamos apenas tornando isso muito mais legível e sustentável Estamos nos livrando
desse código de espaguete ou até mesmo do potencial
de isso acontecer aqui porque temos controle total de
nossa base de código e de como
queríamos que Estamos fazendo uso da herança, então estamos economizando muito tempo ao
adicionar novos recursos No momento,
isso pode parecer um trabalho árduo, mas
definitivamente economizaria muito tempo a longo prazo, entendendo o que isso está fazendo e como usá-lo. Quando estivermos aqui, se você estiver
dentro da base do avião, se estiver
acompanhando exatamente, podemos nos livrar
dessa mensagem descrevendo
o que é a classe Vamos nos livrar
desse. Ele compila em O inimigo partirá por enquanto
e verifique se tudo está salvo
na classe do jogador, e essa é a refatoração do
jogador concluída Então você pode ver que não foi
realmente tão doloroso. Demorei um pouco mais
só porque queria explicar esses conceitos e
torná-los claros à medida que avançávamos. Se eu estivesse fazendo isso
sozinho, provavelmente teria
sido uma tarefa de 1 minuto. Portanto, mesmo refatorar e reconsiderar
completamente como a estrutura das classes é tratada realmente não
precisa demorar muito,
especialmente se você está pensando no
início do desenvolvimento, especialmente se você está pensando no
início do desenvolvimento, é por isso
que estou tentando
enfatizar isso à Tente fazer essas
escolhas com antecedência, e é a
diferença de ter
uma refatoração de 1 minuto
para uma refatoração de 1 hora Se você estiver testando seu código e algo estiver quebrado
ou não estiver
funcionando, verifique se todas as chamadas dos seus pais estão conectadas. Então, esses pais ligam aqui, os nós laranja são
conectados e chamados no início do jogo, na marcação
do evento e assim por diante. Da mesma forma, verifique
se o movimento está
ativado aqui na classe base
e,
o mais importante, por meio desse valor aqui em cima,
como acabei de mostrar, apenas algumas
pegadinhas, nas quais
imagino que algumas pessoas
possam cair Então, basta verificar as coisas
que estamos mudando. Para o próximo tópico, é claro, vamos abordar
a mesma coisa, mas para o inimigo
, isso deve levar um pouco menos de tempo. Agora
vimos como fazer isso aqui.
15. 14 — Refatoração do inimigo: Refatorando o inimigo.
Já fizemos isso uma vez. Deve ir um pouco mais rápido. Obviamente, se você
ainda não tem isso aberto, vamos nos certificar de
abrir a classe inimiga simples. Verifique aqui, se você ainda não fez a alteração
, se
redefinimos a classe principal aqui
para a base do plano de sublinhado da BP Lembre-se de que podemos fazer
isso por meio das
configurações da classe e do
menu suspenso aqui. Novamente
, as mesmas coisas que com o jogador. Vamos excluir
a malha estática, o que nos causará um
pequeno problema aqui. Vamos apenas dizer:
Tudo bem, então clicaremos em sim. Isso me levou direto ao
ponto em que está o problema, ou seja, vinculamos função de
impacto
do componente anterior, aquela verificação de colisão,
à malha estática original Na verdade, isso não é um problema porque queríamos
corrigir isso de qualquer maneira. Não queremos usar a
malha como colisor em vez disso, vamos pegar
o componente esférico aqui, então vamos pegar este e queremos fazer a
mesma coisa novamente Então,
no lado direito do painel de detalhes, simplesmente
soltamos isso. Vamos encontrar a função do quadril
no componente on e criar uma ligação para ela. E isso é tudo que isso está fazendo. É apenas vincular
sempre que ocorre uma ação
, está vinculando essa função
para ser chamada. Então, podemos excluir este,
conectar as mesmas coisas, então pino de execução e pino de ator, e essa é a parte inicial
do problema resolvido. Então, vou
entrar na janela de exibição rapidamente. Vamos pegar
a malha estática e queremos ter certeza de que estamos atualizando o material. Então, novamente, no elemento zero aqui, esse é o que controla
o corpo do avião. Vamos anotar isso
e agora podemos encontrar outro material que você
pode ter feito para seu inimigo, que para mim é apenas MI
underscore plane enemy Selecione esse e estamos praticamente de volta onde estávamos. A mesma coisa com a velocidade de
movimento também. Queremos
clicar com o botão direito do mouse sobre isso, encontrar as referências
do aluno apenas para ter certeza de nos
livrarmos de todas elas. Podemos clicar duas vezes em um
deles e ver onde
eles estão sendo usados. Podemos ver que temos alguns deles para garantir que não
percamos nenhum quando estamos tentando conectar
as coisas novamente. Vou
clicar com o botão direito do mouse no
gráfico de eventos aqui embaixo,
pesquisar a velocidade de movimento e obteremos a variável de velocidade de
movimento aqui, aquela que foi criada
em nossa classe principal. Encaixe isso aqui, duplique
isso, coloque isso aqui embaixo, remova isso só para arrumar
as coisas um pouco, e clique duas vezes no final
, que está aqui E, novamente,
vamos clicar com o botão direito do mouse e pesquisar a velocidade de movimento. Vamos definir
a velocidade de movimento aqui e, em
seguida, conectá-la. Livre-se disso e voltaremos
para onde estamos. Agora, há uma opção que eu não
queria mencionar porque
achei um
pouco complicada. Na verdade, na versão atual, isso simplesmente não parece funcionar. Mas algo que
pode ser útil se eles corrigirem isso no futuro
é que, no passado,
pudemos clicar com o botão
direito do mouse na variável. Podemos selecionar aqui para
substituir as referências. O que estou perdendo
no momento é
que não
sei para onde foram esses recursos. Normalmente, você pode soltar isso e poderíamos ter encontrado a variável de velocidade de
movimento criada na classe principal. Por qualquer motivo,
eu só posso acessar diretamente
as variáveis do ator
e do peão, não a base real de reivindicações do
sublinhado da BP, embora eu devesse ser Mas só para dizer que,
por esses motivos, talvez
precisemos fazer isso
da maneira um pouco mais manual que
acabamos de remover, lembre-se de se livrar
do
sublinhado de velocidade de movimento zero Não devemos mais usar
isso
e, em seguida, basta clicar em compilar para garantir que
tudo tenha sido concluído O mesmo com o jogador. Agora
que os temos na
classe inimiga,
só queríamos verificar novamente. Eu já segui
esse caminho enquanto
fazíamos o conteúdo do jogador. Se você decidiu não
entrar na classe inimiga estou focado apenas na classe de jogador
simples. Em seguida, verifique se
você também tem o início do jogo, chamada
dos pais e a substituição
eventI da chamada dos pais Então, vamos clicar em
R aqui. Vamos fazer a
chamada de adição à função principal
e, novamente, apenas
garantir que as
conectemos à medida que avançamos Para a lógica do movimento, faremos a
mesma coisa novamente. Então, na verdade, queremos que a mesma lógica de
movimento aconteça. Nós podemos pegar tudo isso. Nada realmente
vai mudar. Podemos pegá-los, então basta selecionar
Shift para pegá-los. Queremos pressionar o controle em X para cortar todos os
nós daqui. Vamos substituir e
substituir a função movimento da alça Depois de fazermos qualquer coisa
que precise acontecer na função principal, vamos
colá-las aqui e depois garantir que nosso
movimento seja chamado. Feito isso, isso
me lembrou que também
poderíamos melhorar
outra coisa aqui Então, queremos ter certeza de que com a sobreposição
que estávamos fazendo, anteriormente
estávamos apenas ligando para destroy actor e
deixando uma mensagem aqui Podemos trazer nossa função de
lidar com a morte, colocá-la aqui e substituí-la pela função de destruição. Então, vamos nos livrar de Destroy.
Nós temos tudo sob controle. O que talvez queiramos fazer é
realmente entrar aqui. Vamos deixar um
comentário para nós mesmos. Então, isso foi tirado. Se clicarmos duas vezes sobre isso, isso nos
levará para
a base do avião. Então, agora estamos na classe
dos pais. Podemos partir daqui, e algo que
sempre vamos querer
fazer no final é chamado de ator
de destruição. Uma coisa que talvez queiramos
fazer é usar os
comentários para facilitar o rastreamento das coisas. Então, se pressionarmos C para
colocar um comentário aqui, eu gosto de deixar para
mim esse tipo de anotações posticas, quase Podemos dizer algo como
implementar o efeito pré-morte. Então, o que acontece
antes de destruirmos nosso ator? Nós vamos
fazer isso aqui mesmo. Isso torna tudo muito
fácil porque você pode pressionar Control em F em qualquer classe e pesquisar por Do. Clique duas vezes sobre isso. E onde quer que
você esteja em sua classe, se ainda tiver muitos comentários
para fazer, você pode ir rapidamente até eles e ver no que
pode trabalhar. Também podemos ir para
o lado direito. Podemos dar
uma cor
diferente para que se
destaque um pouco. Depende totalmente de você como
você gostaria de lidar com isso. Mas, como mencionei, é
uma ótima maneira encontrar rapidamente os recursos que talvez ainda não estejam totalmente
prontos para serem implementados porque não estamos tocando
nessas partes do sistema, mas sei que
precisarei
voltar aqui e fazer
isso em algum momento Então, quando voltarmos para
atualizar isso mais tarde, é
assim que você realmente deve se concentrar em seu fluxo de trabalho. Isso realmente não fez
nada por nós agora. O que isso significa é que,
quando voltarmos para adicionar efeitos e
coisas do tipo mais tarde, não
precisamos voltar
e alterar nosso código inimigo. Agora está pronto para ser usado. continuar desenvolvendo todo
o projeto, e isso será
contabilizado
automaticamente quando
atualizarmos os recursos aqui O resto da colisão ainda
é o mesmo. Isso ainda vai ser basicamente o que
precisamos fazer aqui. Você pode substituir
isso por um comentário, outro para fazer um comentário, se
quiser, mas, novamente, não
temos acesso
ao sistema de saúde, então precisamos de algo
para nos lembrar voltar aqui, e essa string de
impressão está boa. Só queremos verificar se tudo
isso está funcionando, então voltaremos ao modo de
jogo, garantindo que os inimigos e
o jogador ainda
estejam se movendo. Pretendido, e
tudo isso é muito bom. Eles ainda estão
pulando nas paredes. Eles ainda estão seguindo
sua direção aleatória, velocidade
aleatória, ricocheteando um no outro, e podemos
voltar e mudar isso, dependendo de como achamos que
o jogo deveria Mas acho que com
isso feito, agora
temos a paridade de comportamento Tudo funciona
como antes, mas fazendo uso da herança
adequada É só uma rápida recapitulação, agora que terminamos nossa refatoração, passando a
usar a herança descobrir o que isso O principal será que
compartilhamos a configuração de colisão Podemos configurar
essa esfera uma vez e ela funcionará nas duas classes
que fazem uso dela. Temos o tratamento compartilhado
da morte. Então, novamente, quando
adicionarmos coisas como explosivos e
sons, ambas as classes
poderão usar Podemos substituir o
efeito, se necessário, mas não precisamos
fazer nenhuma alteração nosso código base agora Temos a opção de ativar a lógica de
movimento compartilhada,
então, quando
adicionarmos as animações, esse movimento ativado
será válido para cenas cortadas tanto para
o jogador quanto para o inimigo Temos variáveis compartilhadas,
como a velocidade de movimento. Ela existe quando
não temos duplicações ou várias versões
delas em toda a classe Talvez eu veja meu exagero
no momento apenas nessas duas classes
diferentes, mas estamos prestes a adicionar
coisas como saúde,
projéteis, efeitos esportivos e tudo mais Agora teremos um
pool de recursos compartilhado para extrair de onde as coisas são relevantes
para usar a mesma coisa em
vez de duplicá-la Uma coisa que acabou de
vir à mente é que
poderíamos fazer essas atualizações de
esfera agora. Como mencionei, o tipo
geral de abordagem que as pessoas adotam com esse tipo
de jogo é para o jogador. Queremos que a esfera talvez seja um pouco menor do
que o esperado. Então, isso pode realmente
estar bem. Poderíamos potencialmente aumentar um pouco o raio da
esfera No momento, podemos ver que está realmente dentro do corpo. É tão pequeno que não
conseguiríamos vê-lo. Então, o projétil vai
voar completamente por toda a envergadura
e pela maior parte do corpo Isso, como mencionei,
é apenas para fazer o jogador se sinta um pouco melhor
do que é. Se eles pensarem em
seus olhos que uma bala quase os errou, mas na verdade, ela os atingiu. Eles vão se sentir
como se esquivassem disso. E o que não queremos é que aconteça
de outra forma, onde eles sintam que
deveriam ter se esquivado de alguma coisa, mesmo que claramente
não o tivessem feito, e se sintam enganados ao sentirem esse dano extra em suas mentes Com a esfera
selecionada, porém, queremos encontrar o raio da
esfera aqui, e podemos definir isso
para algo como 50, e você verá onde
isso entra em jogo Então, agora, essa é a área que o jogador
estaria sofrendo dano. Então, talvez eu reduza
isso um pouco, então é puramente o corpo, algo como 45, e acho que provavelmente é a margem
de manobra que queremos dar a eles Se clicarmos em compilar e depois
voltarmos para a
classe inimiga, a mesma coisa Vamos entrar no
mirante, pegar a esfera, mas acho que desta vez,
o que eu poderia fazer é
torná-la algo como
64 ou dobrá-la E, na verdade, talvez
até seja um
pouco pequeno demais, então vamos fazer algo como 70. Então, novamente,
vai parecer o jogador
sentirá que está atirando muito melhor que, toda vez
que atira, na verdade está
atingindo o inimigo exatamente como planejou, quando, na verdade, perderá o corpo, mas vamos
pegar isso para eles e fazer com que pegar isso para eles e fazer sintam que estão fazendo melhores no jogo
do que poderiam ser. Obviamente, queremos
equilibrar isso. Não queremos
facilitar demais, mas você pode ver que é bom e fácil ajustar essas
coisas de qualquer maneira Então é assim que a herança é configurada. Ambas as classes estão funcionando, ambas herdam da base
do avião Em seguida, podemos passar a
adicionar a saúde e os danos. E será aí
que você realmente começará a
ver os benefícios de aproveitar esse tempo antes
da implementação
para configurar a herança.
16. 15 — Sistema de saúde: É hora de adicionar saúde e danos. Já temos nossa classe base configurada para compartilhar os dados
importantes, então vamos direto para a base do plano de sublinhado da
BP Aqui, precisaremos de
duas variáveis diferentes. Queremos monitorar
nossa saúde atual, a saúde que temos
atualmente e nossa saúde máxima. Podemos fazer isso com
o uso de flutuadores, então vou pegar a
velocidade de movimento, pressionar o controle, na
verdade, duplicá-la uma vez e chamá-la de saúde
atual Duplique-o uma segunda vez e chamaremos esse de Max Health. Se clicarmos em compilar, obterei
o máximo de saúde e definirei isso para
um padrão de 100 Podemos deixar a
saúde atual vazia. Em vez disso, o que estamos fazendo
é, no início do jogo, colocar nossa saúde atual
no pino de execução aqui, e queremos pegar nossa saúde
atual e
defini-la como nossa
saúde máxima. Sem erros humanos. Toda vez que começarmos a
jogar, sempre nos certificaremos de
começar com saúde total. Portanto, uma maneira
simples e agradável de garantir que
não tenhamos nada de errado
com nosso sistema de saúde. Mais uma vez, só um lembrete. É por isso que é
realmente importante. Quando clicarmos em compilar e salvar, volte para o player normal e
verifique se você tem o controle para
começar a jogar, e o
mesmo para o inimigo Então é aqui que isso
se torna importante, porque queremos garantir
que ambas as classes inicializem sua saúde com qualquer que seja sua
saúde máxima Com isso confirmado, também
podemos implementar nosso manipulador de danos.
Isso é muito simples. O RL Engine possui um
sistema de mensagens
integrado especificamente
para lidar com danos Se clicarmos
no gráfico de eventos, precisaremos pesquisar um
evento chamado qualquer dano. Então é esse aqui,
o evento, qualquer dano. E isso será chamado
sempre que enviarmos uma mensagem de outro ator, seja um projétil, um explosivo impactando o
avião ou a classe inimiga, podemos enviar uma mensagem dizendo:
Ei, você foi danificado Quando essa mensagem for enviada
e recebida aqui, essa
chamada de evento ou função será feita. E quando isso acontece,
tudo o que queremos
fazer é definir
nossa saúde atual, então vamos arrastar isso
para o pentágono de execução Faremos disso
nosso inferno atual, então pegaremos a
saúde atual pela segunda vez, controlaremos e arrastaremos isso para o
gráfico para ler o valor,
e isso resultará em nosso dano
negativo. Então, o inferno atual
menos um valor aqui, que será o dano
que estamos transmitindo, então isso será algo que
colocaremos na chamada
da outra classe O resultado desse cálculo
será nosso valor de saúde. Uma coisa que normalmente é recomendada para esse
tipo de cálculo é evitar que as coisas fiquem um pouco complicadas ou estranhas Não queremos permitir danos ou, se também implementamos a
cura, não
queremos permitir que
esses valores nos levem além do nosso limite máximo ou
mínimo Então, podemos usar algo
chamado grampo. Vamos puxar esse pino aqui
e procuraremos a braçadeira. Queremos a opção de fixação flutuante, que está um
pouco aqui em cima. Então, a braçadeira flutua E vamos inserir
o resultado dessa fixação em nosso pino aqui Então, podemos ver o que
isso nos permite fazer. Podemos pegar nosso valor mínimo. Portanto, a quantidade mínima de
saúde que devemos ter é zero. E a quantidade máxima de
saúde que podemos ter
será nosso valor máximo de saúde.
Tão bonito e simples. Isso significa que, se adicionarmos
algo como kits de saúde, quando você pega um
desses, não poderá
ultrapassar a saúde máxima com
a qual começou. Portanto, ele sempre
manterá os resultados desse cálculo
dentro desse intervalo. Depois de confirmarmos que a
configuração da saúde foi feita corretamente e não
conseguirmos errar, faremos
nossa verificação para ver se o dano que acabamos de sofrer
é suficiente para nos destruir. Então, vamos retirar nosso pino de
execução aqui. Vamos
procurar uma filial. Nosso verdadeiro falso controle
de fluxo aqui. E tudo o que queremos
fazer é recuperar nosso valor
de
saúde atual novamente, então controle e arraste isso para dentro.
Veja se isso é menor que. Então, vamos procurar
o operador menor que aqui. E o que vou fazer é
realmente verificar se isso é menor ou igual
a um determinado número. Insira isso na ramificação
aqui, a booleana, e agora temos uma
verificação dizendo que, se nossa saúde atual for
menor ou igual a zero, podemos lidar com
nossa chamada da função de morte ou da
função de tratamento de morte Pergunte por que estamos usando
menos down em igual a, especialmente porque
acabamos de restringir isso para garantir que
nunca fique abaixo de zero E isso é apenas uma espécie
de hábito de segurança. Se algo causar mais
danos do que o inferno restante, ou se tivermos alguma estranheza de
ponto flutuante, ou mesmo se
refatorarmos o código novamente mais tarde e decidirmos
não corrigir isso, quero ter certeza de
que essa verificação
sempre será relevante para
garantir Então, por exemplo,
se pegarmos essa pinça, se tivermos cinco pontos de vida e sofrermos mais dez de
dano, obviamente, teremos
menos cinco, o que
significa que, se
verificarmos apenas zero
, algo que tenha sofrido mais dano do que deveria evitaria ser morto Com isso feito, porém,
de nossa filial aqui, podemos lidar com a morte. E se isso for verdade,
podemos simplesmente conectar isso.
É isso que agora
começará a lidar com todas as funcionalidades
de
morte qualquer um dos aviões que
você possa se sentir tentado a fabricar
e, é claro, dos dois
que já temos Handle Death já tem
a função
destruída e, como mencionei, voltaremos aqui mais tarde para adicionar coisas como explosões, efeitos
sonoros e todas as coisas divertidas e suculentas que
queremos colocar em nosso jogo Então, para realmente começar a
usar o sistema de danos, já
temos algo
pronto para testar pelo
menos parte de
como essa estrutura funcionará
dentro do nosso inimigo. Então, se voltarmos para a classe
inimiga, essa parte aqui, que está
imprimindo nossa sequência de caracteres há muito tempo, podemos
finalmente removê-la Em vez disso, o que
queremos é pegar nosso ator de sucesso, então controlaremos o
arrasto para o gráfico. Vamos usar o outro ator e estamos procurando
aquela mensagem
global que mencionei um pouco
antes, a de aplicar dano. Então, podemos ver aqui que
aplicamos danos. Isso apenas faz uma ligação para qualquer ator com
quem possa se comunicar. Nesse caso, será aquele em
que acabamos de
entrar . Vamos conectar
isso aqui mesmo, então pegaremos nossos pinos de
execução, verificaremos se estão todos conectados
, tiraremos isso do caminho e queremos aplicar
uma certa quantidade de dano ao jogador Acho que, para os inimigos,
vou dar saúde a
essa metade dos jogadores. Eu sei que o jogador
terá 100 curas. Vamos definir isso para 50, e isso
significa que o jogador pode receber dois golpes de um inimigo para não querer pular
nele com muita frequência. Não será uma maneira
rápida e limpa de ganhar pontos
extras simplesmente voando todos os inimigos. Agora,
isso me lembra. Outra coisa que podemos fazer
com nossas variáveis herdadas é selecionar
o inimigo, por exemplo, e obter os detalhes
da classe aqui, no lado
direito, queremos ter certeza de
que a saúde
do inimigo provavelmente será diferente
da saúde do jogador Assim, poderíamos definir a saúde do
inimigo para 50
e, no jogador,
verificaremos se o
padrão deve ser 100 Certifique-se de que a
saúde do jogador esteja definida como 100. Então, novamente, uma boa maneira
fácil de definir o valor da saúde apenas
uma vez e lidar com isso
na classe principal,
tanto para o dano sofrido
quanto para a saúde fornecida aqui, porque eles são
baseados em variáveis que existirão em
todas as classes. E então, nas classes secundárias, tudo o que precisamos fazer é
ajustar essas variáveis
no editor se quisermos
mudar o tipo geral
de marcação do nosso jogo E, como mencionei,
porque
já configuramos isso de uma certa forma, agora significa que
temos o nome de morte. Não precisamos
voltar e tocar nisso. Precisávamos fazer uma
pequena mudança:
o lado da classe inimiga
não precisava ser contabilizado e tudo
continuará funcionando como estava Uma coisa que quero mostrar
rapidamente, só porque esse
é outro
daqueles lugares realmente claros você pode ter
se sentido
tentado a adotar
uma abordagem diferente
para lidar com a morte do inimigo, é que poderíamos
desligá-lo por enquanto Outra coisa que você
pode fazer é duplicar nossa função de aplicar
dano Poderíamos inserir isso
aqui porque o principal é que, quando
atingimos o avião do jogador, sabemos que a classe inimiga precisa
se danificar, essencialmente. O que poderíamos fazer é
pegar nosso valor máximo de saúde. Então, podemos pesquisar por MAXel
e inserir isso aqui. E então, o
ator danificado, poderíamos basicamente aplicar
dano a nós mesmos. Então, se retirarmos
do ator
danificado aqui e procurarmos por uma célula, obteremos essa opção integrada na funcionalidade que eu
queria apresentar, obtendo uma referência a si mesmo. Então, basicamente
, é um pouco estranho. Isso basicamente
encontrará uma referência a si mesmo, que é encontrada aqui. Ele chamará por si só a mensagem de aplicar
dano, que obviamente
será captada
na classe base, pois é aí
que
temos o caso de algum
dano ser causado. E porque estamos transmitindo
o máximo de saúde, e isso é apenas uma questão de segurança. Mais tarde, decidi
que, na verdade, a saúde do inimigo
aos 50 estava muito baixa, e entrei e
mudei para 75. Obviamente, o que não
queremos fazer é ter esse 50
codificado, porque
qualquer alteração que
fizermos em uma base mais ampla do que apenas esse nó aqui
seria meio esquecida e perdida Outra forma, novamente,
é tentar pensar em como você
estrutura seu código, no uso de variáveis,
principalmente no tipo de preparação para
o futuro , para
que você não precise trabalhar mais no futuro A principal coisa com os programadores
é que somos muito preguiçosos. Quanto menos trabalho
tivermos que fazer, melhor, evitando voltar ao nosso código e alterar
variáveis em todos os lugares. Se pudermos
configurar algo assim, posso alterar a
saúde máxima para qualquer coisa. Eu poderia diminuí-lo, eu
poderia aumentá-lo. Essa função
sempre funcionará. Como mencionei, porém, ele simplesmente não é
lido de forma muito clara. Demora um pouco
mais para descobrir por que temos um dano
aplicado, outro aqui e quais são
esses diferentes atores. Acho que faz mais sentido
se vamos criar
um tipo completo de inimigo ao estilo
kamikaze, podemos simplesmente conectá-los
e isso torna tudo muito mais claro Então, vamos aplicar
dano ao que fizemos, apenas depois de fazer isso, vamos aplicar
dano a nós mesmos. E lembre-se, isso é realmente seguro porque estamos
olhando aqui embaixo, verificando se
o ator de sucesso é o que o jogador humano
está controlando no momento, e somente se isso for verdade,
faremos isso. Portanto, isso não causará
danos às paredes, aos projéteis ou
a outros inimigos Tudo isso será
contabilizado aqui embaixo. Portanto, essa é uma
maneira agradável, fácil e segura de estruturar danos por impacto. Algo que eu
realmente não mencionei, mas também tenha em mente que a ordem de operação
é muito importante. Assim que você pensa sobre isso, se você nunca
pensou nisso antes, fica realmente óbvio. É algo
que as pessoas sentem falta. Se lidarmos com a morte primeiro, então poderíamos jogar isso para
o outro lado também. Se conectarmos isso aqui,
solte-os e mova isso. Apenas um exemplo muito rápido,
conecte-o novamente. E isso é só porque eu já
vi isso acontecer antes. Os alunos não sabiam ao certo por que certas funções não estavam sendo convocadas quando
esperavam. Às vezes, também pode estar
no sistema. Alguns sistemas podem funcionar, outros podem
não, dependendo da
rapidez com que a iteração do ticket e coisas assim
acontecerão Mas, basicamente, se você
pensar no que está acontecendo aqui, se atingirmos o player e
chamarmos handle death primeiro, isso será entrar
na função principal, chamando destroy e,
potencialmente, se isso for imediatamente adicionado à coleta de
lixo e
apagado da memória, essa classe não Isso significa que não vai
sair daqui,
voltar para essa função e causar
danos ao jogador Portanto, você pode acabar com um jogo em que o
jogador simplesmente nunca receba danos de impacto. Portanto, tenha cuidado com
esse tipo de coisa. E, novamente, é muito
comum que as pessoas
já tenham lidado com o
lado mortal das funcionalidades e depois
voltem e adicionem os efeitos de partículas e
o
som e depois
não saibam imediatamente
por que as partículas e os efeitos
sonoros não estão sendo os efeitos
sonoros não estão É porque sua
aula provavelmente está sendo apagada da
memória e não existe. Essa função está sendo
chamada. Portanto, a ordem de operação também é importante. Controle de fluxo é
outra palavra para isso. Esse foi um tipo de exemplo muito
simples, mas é uma armadilha fácil de
cair se você não estiver
prestando atenção suficiente Mesmo que você
entenda o conceito, é um erro simples de cometer. Então, com isso, se apenas
clicarmos em compilar e salvar, podemos voltar e
testar ou clicar em reproduzir O que estamos
procurando aqui é garantir que eles ainda se destruam
ao atingirem o jogador. E o mais importante, depois de
dois golpes como os que vimos lá, eles também estão
destruindo o jogador Portanto, nem o jogador nem o
inimigo têm um sistema de saúde, tendo em mente que não
estamos implementando esse sistema de saúde
em cada classe. Estamos fazendo isso apenas
uma vez na classe base, e toda essa funcionalidade
para calcular a saúde, verificar se a classe está morta
e, em seguida, chamar a função
está sendo tratada lá Ao analisar isso, acabei de perceber que
provavelmente cometi uma pequena de codificação. Isso na verdade nos
causará
um pequeno problema porque chamamos
handle death quando calculamos
que a morte
seria apropriada, e
estamos chamando isso Há uma boa chance de
conseguirmos que dois conjuntos de partículas
funcionem. Vamos receber uma
da chamada de disfunção
e, em seguida, uma da chamada de
disfunção, que está acontecendo
com base na saúde Então, agora que estou
analisando meu próprio código, o que acho que deveríamos
fazer é, na verdade, a maneira que eu estava tentando usar
apenas como um exemplo de aprendizado. Mas se duplicarmos isso novamente, acho que teremos que
fazer de outra maneira Então, vamos
causar danos a nós mesmos. Então, novamente, vamos
retirar o agente de dano. Vamos dizer vender, e
vamos colocar isso aqui. Isso só garante que
é muito fácil ignorar
coisas como essa Sorte que voltamos e
demos uma olhada rápida no código. Isso apenas garante que o dano
seja aplicado a nós mesmos. Vamos usar o
mesmo truque que mencionei há
pouco, então Maxel E, novamente, percebo que poderia
editar isso do vídeo. Mas como criei todo
esse projeto com a intenção de tentar ensinar
como pensar em programação, acho que esse é um
ótimo exemplo
de aprendizado do tipo de coisa que
você pode ignorar e como pode facilmente se meter em uma pequena situação que precisa
voltar e corrigir Então, isso garantirá que
definitivamente nos matemos. Estamos sempre
transmitindo a
quantidade máxima de saúde que
poderíamos ter. fará com que
isso seja chamado, que garante que nosso identificador morte seja chamado apenas uma vez, que
significa que, quando chegarmos
aos efeitos de partículas, aos efeitos sonoros, o
chamaremos uma vez aqui e depois
tocaremos uma vez aqui Então, essa é a principal
coisa que queremos evitar, que eu
possa excluí-la.
Não lê muito bem. É aqui que você
pode querer fazer um comentário apenas para deixar
claro. Isso é para o jogador. Isso é para você mesmo
garantir que sempre
saiamos do jogo
depois de bater no jogador Coisa muito simples, coisa
muito pequena. Transformei isso em um tópico maior
só porque é mais
um momento de aprendizado que surgiu acidentalmente Última pequena coisa
que podemos fazer enquanto ainda
estamos na classe inimiga. Podemos remover o uso
de números mágicos. Então, no momento, estamos apenas aplicando 50 de
dano ao jogador. Podemos transformar isso
em uma variável e chamaremos isso de dano
de impacto. Basta verificar se há outros que
possamos ter perdido. Acho que foi só essa.
Na verdade, nós os temos se você quiser
criar uma
velocidade de movimento mínima e máxima, porque o inimigo tem a chance
dessa randomização Ele compila, salva,
volta para o player,
confira aqui Acho que não
temos tantas variáveis que
criamos recentemente, então tudo bem na classe
do jogador e também na classe
base. Outra coisa que
talvez você queira fazer se estiver realmente
tentando manter todas essas variáveis organizadas à medida que começa a obter muito
mais variáveis, pode ficar um
pouco mais difícil descobrir
a que elas estão relacionadas Assim, você pode fornecer
categorias de variáveis, o que pode ajudar. Então, por exemplo,
temos aqui a velocidade atual, a velocidade
alvo, a velocidade de interação. Então, esses três estão todos
relacionados ao movimento
e, em seguida, esses dois estão
relacionados à rotação. Então, o que podemos fazer
é selecionar uma delas
no painel de detalhes, obtemos essa opção
aqui para uma categoria e podemos configurá-la para
algo como movimento. E então podemos
simplesmente arrastar e soltar os outros movimentos
na categoria de movimento. Podemos pegar a rotação
e talvez possamos dar a ela uma categoria
de rotação. mesmo de novo, coloque-os aqui, e então podemos
derrubá-los. Facilita um pouco
, especialmente quando você tem uma longa lista de variáveis que começam a aparecer
em classes maiores Isso significa que você pode
navegar muito rapidamente para encontrar todas as
coisas relacionadas ao movimento se estiver procurando por
um valor muito específico para ajustar e o
mesmo para rotação Você pode lutar. Você pode
ter uma categoria de booleanos, vetores, o que
quiser configurar aqui Exatamente como seu processo
de trabalho se adequará melhor ao seu
projeto, mas apenas uma ideia rápida. Se você quiser fazer
algo entre os tópicos, fique à vontade para fazer uma pausa, fazer uma pequena
pausa no
acompanhamento e talvez voltar
às outras classes e ver como você pode
categorizar as coisas na classe base e talvez
até na classe inimiga Não vou fazer isso na tela,
mas é apenas uma ideia para colocar esses conceitos em prática e
informar que esses
recursos existem. Com isso feito, porém, nosso
sistema de saúde está completo. Já implementamos isso uma vez
e está funcionando em todos os lugares. Isso significa que podemos passar para
os projéteis. E, novamente,
agora podemos simplesmente construir sobre a base que já
criamos. Será aí que
o combate ficará mais interessante e quando
poderemos realmente revidar.
17. 16 — Movimento Melhorado: Lembre-se daquele bug
de taxa de quadros que
reconhecemos e
acabamos de superar É hora de voltar
a isso e consertá-lo. Substituiremos o código
de movimentação
problemático algo pronto para produção Independência adequada da taxa de quadros, estrutura
mais limpa
e melhor preenchimento. Percebo que antes de
começarmos a adicionar coisas
sofisticadas, como geradores de
atores, projéteis e
aprimorar o sistema
de danos, enquanto estamos fazendo esse fator enquanto estamos fazendo esse fator
e aprimorando o código base, provavelmente
deveríamos voltar
e garantir que não
esqueçamos o movimento e
o bug que já conhecemos esqueçamos o movimento e
o bug O código ofensivo
que precisamos corrigir está em nossa classe de jogador Então, se você ainda não
tem isso aberto, vá em frente e abra o BP
Underscore plain player No meu caso, vou
pressionar o botão do meio do mouse fechar as guias que não
usaremos Então, a classe base e
a classe inimiga e navegue até a função de
movimento da alça logo aqui. Então esse é o código que
queremos substituir e melhorar. Agora, a primeira coisa é que, após
o movimento da alça principal, queremos clicar e
desconectar esse código Algumas pessoas têm opiniões
diferentes sobre esse tipo de coisa. Novamente, quero manter o
foco na estrutura do código, nas
boas práticas e em
coisas assim. O que você pode ver, especialmente
no código C plus plus, é alguns desenvolvedores podem manter o código antigo que estamos
tentando substituir. Talvez coloque isso em um comentário
, caso queira vê-lo mais tarde, caso ache que talvez precise
recorrer a isso. Isso acaba com um espaço de trabalho
desordenado. Talvez você tenha muito mais código em seu C plus
do que precisa. Em Blueprints
, obviamente, podemos ter muito mais coisas apenas no gráfico
do que precisamos E, idealmente,
estaríamos usando algo como o Github para
controle de origem de qualquer maneira Então, se precisássemos
examinar um código antigo, o ideal seria reverter
nosso repositório e visualizá-lo por meio do Git
ou Perforce ou algo assim Agora, neste caso,
vou manter isso apenas por um momento,
porque acho que há algumas coisas que podemos simplesmente
copiar e colar rapidamente, mas vamos nos livrar totalmente
desse código Então, vamos
começar este do zero. A primeira coisa
que queremos fazer é extrair nosso
pino de execução aqui e
criar algo
chamado sequência. Queremos essa opção aqui mesmo. E se você nunca
viu isso antes, as sequências são muito
subutilizadas Eles fazem com que nosso projeto seja
lido como um código tradicional, ou
seja, de cima para
baixo, da esquerda para a direita Cada um dos pinos lida com
uma tarefa específica, ou pelo menos é assim que devemos
pensar em usá-los É muito mais limpo do que a lógica que se estende pelos
três monitores, só porque você tem
essa longa linha de lógica Só para ressaltar, não
estou me exibindo. Isso foi um exagero. Na verdade, eu não
tenho três monitores. Existem outros
benefícios e motivos pelos quais você pode querer usar
isso, mas o principal,
voltando às sequências, é que elas são uma
maneira muito boa de ajudar a estruturar
nosso código e nos ajudar a pensar logicamente, dividindo as coisas
essencialmente em etapas Você está dizendo, faça isso,
depois faça isso, então faça isso, e você tenta manter tudo um pouco exclusivo para uma determinada tarefa. Então, a primeira coisa
que realmente queremos em nossa tarefa é calcular nossa velocidade de movimento
alvo. Já estamos fazendo
isso aqui, então essa é uma das coisas
que podemos pegar. Se pegarmos o código até o nó de velocidade de movimento
alvo, pressione Control em X e, em
seguida, cole novamente. Portanto, essa será a
primeira tarefa que daremos a nós mesmos
em nossa sequência. Outra coisa que pode
nos ajudar a manter o código um
pouco legível é que, se clicarmos
duas vezes em um fio, isso nos dará um nó de reinicialização. Podemos mover isso até
aqui porque queremos ter certeza de que teremos
espaço suficiente, essencialmente para o caminho diferente
que estamos seguindo. Agora, uma coisa
que vamos mudar é que
vamos criar
nossa própria interpolação Não usaremos F interp two. Por esse motivo,
vamos mudar um pouco dos segundos do Get
World Delta. Cara, livre-se desse nodo
aqui, da multiplicação. Conecte isso diretamente
à velocidade alvo definida e
tornaremos essa taxa de quadros independente um pouco
mais tarde. Vamos manter isso por perto. Precisaremos disso
em apenas um momento. Eles obtêm segundos Delta mundiais. Mas é basicamente isso.
Esse é o nosso primeiro passo. Nossa primeira coisa que precisamos fazer
é ter uma meta a ser alcançada. Isso então nos alia.
Podemos ir até então um. E o que vamos
fazer aqui é calcular nossa própria
interpelação personalizada Alpha Então, isso vai ficar um
pouco matemático, mas será a chave para a independência adequada da taxa de câmbio Vamos continuar,
vamos adicionar isso
e, em seguida, vou voltar atrás
e tentar explicar por que acabamos com
um cálculo que temos. Então, a primeira
coisa que queremos é nossa velocidade de interação de movimento aqui, então vamos
controlar o arrasto para dentro e obter a velocidade de interação de
movimento Multiplicaremos isso
por nossos segundos Delta, é por isso
que ele está disponível há
pouco, então teremos nossos segundos
Delta do Get world para começar a
fazer com
que segundos
Delta do Get world para começar a nossa
taxa de quadros de cálculo seja independente novamente Em seguida, queremos negar ou inverter o cálculo que criamos, então vamos multiplicar aqui Vamos multiplicar o nó e multiplicar isso por menos A partir do nosso cálculo aqui,
vamos puxar novamente. Vou pesquisar
algo chamado EXP. Este é o
valor exponencial, então diz aqui, isso retornará o E
exponencial à potência
do valor.
Então, vamos usar isso. E, finalmente, depois do
nosso nó exponencial, vamos puxar a partir daqui
e vamos subtrair, então basta pressionar a tecla menos, encontrar, subtrair e subtrair
um do cálculo encontrar, subtrair e subtrair um do O importante,
antes de
esquecermos , é que obviamente não queremos
nenhum número mágico, vamos usar
o pino final. Vamos promover
isso para uma variável e chamaremos
isso de MV Alpha Se você estiver
criando categorias, talvez
queira movê-las
para a categoria de movimento. Como, é claro, esse será
um movimento específico. Vamos conectar isso
ao nosso pino de execução, depois ao primeiro, e agora temos
nosso código Alpha pronto para uso. Portanto, essa é nossa
interpolação suave que usaremos de uma
forma mais manual e
intencional em Então, só para focar novamente
, o que isso está fazendo é nos dar um menos E a
velocidade negativa vezes Delta Essencialmente, isso está fornecendo
uma curva de decaimento suave. Essa é a principal razão pela qual
precisamos usar a subtração de
um no final, pois queremos que
ela decaia com o tempo E a razão pela qual
precisamos usar uma fórmula como essa é voltar à principal fonte do
problema que estamos tendo entre diferentes taxas de quadros e mantendo
as
taxas de quadros independentes. A função F interp está na verdade, fornecendo uma aproximação
linear, e é isso que está quebrando
em baixas taxas de Em comparação, se
criarmos uma função como essa que podemos usar com
uma função larp padrão, essa
abordagem exponencial nos fornece interpolação
matematicamente correta Então esse era o
objetivo principal aqui: na verdade, queremos parar
completamente de usar isso. Por fim, lembre-se de
que queremos tentar fazer
coisas específicas muito exclusivas por linha. Vamos adicionar outro pino
e queremos os
dois pinos aqui. Vamos partir daqui
e queremos fazer a última coisa, que é, na verdade, usar
a velocidade atual, fornecendo interpolação a Ainda queremos
usar a interpolação, mas apenas a versão básica mais
rudimentar com nosso Assim, podemos puxar
do pino de execução. Podemos encontrar a velocidade atual
definida. Então, definindo o valor que
estamos rastreando, é aqui que queremos
extrair desse pino aqui, e vamos
pesquisar o loop. E desta vez, queremos
apenas usar o loop flutuante padrão Então você pode ver que é
um pouco mais simplificado. Em vez de ter a
corrente no alvo no tempo Delta e
uma velocidade de interp, se quisermos alterar
a velocidade de interp, precisamos adicionar algum
tipo de deslocamento aqui Tudo o que estamos fazendo é fornecer
essa curva exponencial, que será nosso Alfa Então, se fizermos o movimento Alpha, podemos colocar isso aqui. Mas, além disso,
basicamente ainda estamos fazendo a mesma coisa. Vamos
passar de A para B. E eu mencionei
isso quando
olhamos pela primeira vez para o F nos dois primeiros, temos meio que 0,1 em 0,2 ou ponto A e o ponto B. Então,
ainda estamos fazendo a mesma coisa. Vamos de A, que
é a velocidade atual, para B, que é nossa velocidade alvo
em um período de tempo, e agora estamos baseando
isso em nosso próprio Alpha móvel personalizado Então, essa é a principal mudança
aqui: a forma como estamos definindo a
velocidade atual está sendo atualizada. Então, se continuarmos, podemos
realmente excluir isso agora. Então, podemos ver que estamos
na maior parte do tempo
atualizando nossa base de código. Vou
clicar duas vezes aqui novamente para criar outro nó de reenraizamento apenas para
manter isso um pouco arrumado, tirar as coisas do caminho nos
dar
espaço suficiente Então, a última coisa é que
queremos definir nossa localização novamente. Também vamos fazer algo um pouco diferente aqui. Então, depois de definir
a velocidade atual, uma vez que estamos
rastreando a velocidade, queremos extrair
nosso pino de execução e
pesquisar algo chamado add actor world offset Então, podemos ver a
opção logo aqui na parte superior, no Actor world offset Portanto, para nosso caso de uso, essa é,
na verdade, a melhor solução em comparação com definir a
localização do ator para movimentos
conscientes da física. A única coisa que realmente
precisamos mudar é clicar com o botão
direito do mouse no vetor de
localização Delta aqui, dividir o pino da estrutura para
que tenhamos os mesmos resultados de antes. Queremos medir
nossa velocidade atual, que
possamos conectá-la se você quiser, mas neste caso,
vou apenas
Controlar a velocidade atual de arrasto Vamos multiplicar
isso por segundos Delta. Então, obteremos mais segundos Delta do mundo
G e conectaremos isso
ao nosso resultado aqui. E então, é claro,
vamos fazer disso o Y porque estamos nos
movendo de um lado para o outro. Então, queremos isso no
eixo Y. É basicamente isso. Então, agora atualizamos. Também podemos nos
livrar disso. Agora atualizamos
nosso código de movimento. Estamos rastreando a
velocidade alvo de forma um pouco diferente. Temos nosso alfa de movimento totalmente
personalizado baseado em uma curva de decaimento e mudamos um pouco a maneira
como lidamos com a velocidade atual e como a
conectamos à localização mundial Agora, uma coisa que
poderíamos fazer aqui, só para melhorar um pouco as coisas, é
voltar a comentar coisas Então, novamente, esse é um bom uso de comentários quando temos
essas grandes divisões de lógica específica em nossa ,
então o que poderíamos fazer é
pegar esses nós aqui pressionar C. E se eu quisesse
fazer um comentário, talvez
eu diria algo como definir velocidade para o avião alcançar E para que eu não precisasse me
aprofundar no código mais tarde, eu poderia simplesmente especificar
que essa é especificamente a
velocidade alvo que estamos analisando. Novamente, eu poderia dar esse tipo de
cores mais exclusivas apenas para que os comentários se
destaquem de outras coisas como fazer, que
criamos anteriormente. Não precisamos fazer isso e deixar tudo muito
bonito. Você definitivamente pode se
deixar levar por isso. Mas quando
mudo a cor das coisas, é mais que, à primeira vista,
sei que uso um
cinza específico para comentários Eu uso um vermelho específico para códigos
potencialmente quebrados ou algo que
precisa ser movido todos juntos. Eu normalmente uso, tipo,
um verde para fazer. Então, novamente, em
um piscar de olhos, eu posso ver como estou
lendo meu código Esses são apenas comentários
em que preciso me atualizar Isso é algo que eu realmente
preciso eliminar mais tarde, e coisas assim
podem se tornar úteis Então eu dou a eles
uma cor muito azul acinzentada só
para me lembrar Basta pressionar
Control C e Control V para obter outro
comentário aqui, meio que duplicar este, e vamos colocá-lo aproximadamente no lugar para que eu
não precise definir
a cor novamente. E essa
é uma dessas coisas. Depois de se acostumar com atalhos
e coisas assim, o pouco de
tempo extra necessário para personalizar a
cor e o tipo de tema não adiciona muita sobrecarga ao
seu tempo de desenvolvimento Então, isso, se eu estivesse deixando
um comentário para mais tarde, está nos ajudando a rastrear o Alpha para uso em nossa função de
interpolação Mais uma vez, apenas
me lembrando de que, especificamente, isso está atualizando a função
move Alpha E então queremos talvez mais
um comentário. Eu mencionei que não farei
isso para todas as linhas de código e não farei isso para o
resto do projeto e vídeos, pois os vídeos
ficariam muito longos. Mas só para mostrar o
conceito, à medida que
analisamos alguns desses maiores
refatores e mudanças, que podem ser um
pouco mais confusos, acho que é definitivamente
valioso ver isso Então, vamos apenas
colocá-los em seu lugar. E o que eu poderia chamar isso
é que estamos atualizando nossa velocidade atual e , em seguida, definindo a
localização do nosso avião. E, ao dizer
isso, na verdade outra coisa muito útil é que agora estou questionando meu próprio código porque estamos
fazendo duas coisas por linha E se você se lembra, eu disse, a regra geral é
que,
com uma sequência, nós as tratamos
um pouco como funções em que as funções deveriam fazer uma coisa específica
e outra muito bem. Então, no momento, estamos
principalmente seguindo isso. Isso está definindo especificamente
a velocidade alvo. Isso é calcular e definir especificamente o movimento Alpha, mas agora isso
está fazendo duas coisas Está definindo a velocidade atual
e, em seguida, movendo o avião. Então, o que eu poderia ficar
tentada a fazer é adicionar outra e depois fixar aqui, controle
mamário em X,
controle em V. Conecte isso E, mais do que tudo,
eu poderia ter deixado isso, mas só para mostrar como é
fácil manter seu código limpo e seguir regras
e estruturas específicas. Então, agora estamos realmente seguindo
as regras que estabelecemos a nós mesmos,
e eu só preciso
mudar as coisas um
pouco e talvez
adicionar outro nó de reinicialização aqui. Arrume um pouco as coisas. Novamente, não estamos tentando
fazer essa obra de arte, mas quanto mais fácil
for trabalhar com ela, nosso eu futuro
ficará grato O que estamos fazendo agora é pensar no código. Podemos vir e
fazer seu comentário final. Então, isso é definir a velocidade
atual com base em uma interpolação simples, ou
seja, Então essa é a única coisa que essa linha está fazendo especificamente. E então, novamente,
precisamos de um comentário final, então o controle C controle
V colocou isso em prática. Quer dizer, eu tenho um tijolo lógico muito
bom, então agora isso é simplesmente
atualizar a localização do avião. Então, se
fôssemos ler isso,
podemos ver especificamente
o que está acontecendo. Estamos definindo a velocidade alvo. Estamos atualizando o movimento Alpha, que será usado posteriormente para a função de
interpretação. Estamos usando essa função de
interpretação e definindo a
velocidade atual com base nela. E então estamos pegando
essas variáveis e atualizando a localização final do
avião. Então, isso agora é provavelmente melhor do que o que eu tinha há
pouco. É apenas uma pequena
mudança, mas, novamente, seguindo essas regras, pensamos como pequenas funções, essencialmente, e todas elas estão
fazendo esse trabalho muito específica e o
estão fazendo bem Mantenha as coisas arrumadas, mantenha
as coisas fáceis de ler. E se precisarmos
voltar e remover algo, adicionar algo
, será muito mais fácil atualizar e corrigir nosso
código no futuro. Então é como uma tangente lateral lá. Eu não esperava
me aprofundar muito na limpeza do código, mas vi a
oportunidade novamente porque meio que fui contra o que
mencionei no
início do tópico Feito isso. Esse é o
movimento agora pronto para começar. O que precisamos ver a seguir
é o sistema de rotação. Vai ser o mesmo
problema porque estamos usando o
mesmo tipo de coisa. Se formos lidar com a rotação. Temos uma
função muito simples, que é,
novamente, a coisa muito boa
que o Unreal faz por nós Ele fornece muitas
dessas funções auxiliares, este R integrado intercala dois, simples e
simples, um nó, alguns nós próximos a ele
para o cálculo
e, em seguida, define a rotação
ativa, e estamos
prontos para testar Mas algo que
as pessoas precisam saber é que, geralmente, isso só
serve para testes. Provavelmente queremos começar
a criar
nosso próprio código quando ficarmos mais sérios e, na
verdade, com as coisas. Antes de
fixar a rotação, basta
verificar algumas coisas no movimento da alça. Como vamos
dirigir a velocidade atual um pouco mais
manualmente dessa forma, provavelmente
queremos ter certeza de que, ao clicar nela anteriormente, percebi velocidade
atual tem
um valor padrão O valor padrão aqui era
essencialmente quando essa era originalmente nossa velocidade geral de
movimento. Então, vamos
querer redefinir isso e garantir que a velocidade atual, a velocidade
alvo, a velocidade de
interposição do movimento tenham um valor,
mas a velocidade alvo da multidão e a velocidade atual estão todas
definidas como zero por padrão, e só serão
calculadas em tempo A outra coisa, o mesmo problema,
muito fácil de fazer novamente, é que quase esqueci de
marcar a função de varredura, então ela tem a mesma função
da função de definir localização
real que usamos anteriormente, então precisamos ter certeza de
que a varredura Isso deve ser
muito bom para começar. Isso não funcionará
totalmente no momento. E acabei de perceber que fizemos
isso da maneira errada. Acho que estava dizendo
para você subtrair a coisa
certa anteriormente, mas durante a implementação, eu
conectei isso da maneira errada Então, se clicarmos com a tecla Alt
após o exponencial, é
muito importante
aqui, queremos subtrair nosso
cálculo de Então, estamos trabalhando de volta a partir de
um. Estamos criando essa curva de decaimento a partir de uma com base
nessa atualização ao longo do tempo Então, sim, está apenas testando rapidamente para
garantir que isso ainda funcione. Como mencionei, a rotação vai
ser um pouco trabalhada, mas ainda temos
o mesmo movimento, então temos um bom movimento
suave,
a rotação, porque é baseada na velocidade que
temos , está completamente quebrada, mas isso é algo com o qual
podemos trabalhar, e meio que
melhoramos isso à medida que
avançamos e
refatoramos a rotação Então, apenas algumas recapitulações
finais. Certifique-se de que estamos
fazendo nosso cálculo para nosso valor exponencial
e, em seguida, retirando
isso de um. Portanto, é um menos nosso cálculo
exponencial aqui, e esse é o resultado que
queremos para nosso movimento Velocidade atual, velocidade alvo, ideal é que
você seja definido como zero. Estamos calculando isso aqui, multiplicando-os novamente, e obtemos um bom movimento
independente da taxa de quadros Então, isso ainda é
meio que uma sensação e funcionamento muito parecidos com os
que tínhamos anteriormente. Você pode achar que
precisa ajustar um
pouco a velocidade agora, mas estamos
muito perto do que tínhamos As rotações foram interrompidas, o
que, como mencionei, é esperado porque estamos usando um cálculo muito simples aqui com base na velocidade alvo e apenas multiplicando isso
pelo fator de inclinação, e agora a
velocidade alvo ou velocidade atual,
desculpe, está sendo tratada de uma
maneira Com isso feito, porém,
melhoramos o movimento. É uma
base muito boa para começar, e então podemos pular
direto para a rotação Agradeço esses tópicos
bastante pesados à
medida que analisamos isso,
mas espero que, passando algum tempo
entre os tópicos, faça uma pausa novamente sempre
que achar necessário e realmente tente entender o que
estamos fazendo e por que essas mudanças
funcionarão Eu tentei explicar a matemática
e outras coisas por trás delas. Algumas coisas são
muito difíceis de transmitir sem realmente ter experiência prática com
o código-fonte. Outra coisa
é que você pode acessar código-fonte do Unreal Engine encontrar a função Ler
em C plus plus E, novamente, mesmo
que você não
entenda totalmente o C
plus, tudo bem. A maior parte é
muito legível por humanos. Os comentários estão todos lá. Está explicando o que está
acontecendo na
função F interp passo a passo E, às vezes, basta mergulhar
no código-fonte dessa forma, já que tudo está
prontamente disponível Seja muito útil e você
começará a entender algumas
das limitações de
usar apenas a funcionalidade reconstruída e
predefinida
fornecida pelo Unreal Engine Não quer dizer que seja ruim, como mencionei, ele
tem seus casos de uso, mas encontramos esses casos marginais em
que simplesmente não funciona e precisamos criar
nosso próprio código
18. 17 — Rotação melhorada: Movimento configurado. Agora precisamos fazer a mesma coisa
para nossa rotação. Ainda queremos estar dentro
do avião, player. Vamos entrar na função de rotação da
alça. Vou fazer uma atualização muito
parecida aqui. Outra coisa
boa é que
podemos começar a tornar
o código um
pouco mais uniforme, porque a lógica por trás dele
será muito semelhante. Então, na verdade, podemos dar
nossos passos iniciais aqui. Vamos reduzir isso. Vamos
soltar isso
e guardar qualquer coisa que possamos usar um pouco mais tarde,
mas, como você disse,
anteriormente, vamos nos livrar
completamente disso até o final Agora, a primeira coisa é
que queremos obter nossa sequência. Podemos fazer a mesma coisa novamente. Então,
pegaremos um nó de sequência e começaremos a mantê-lo
organizado porque precisaremos fazer muitos
cálculos para isso Então, vamos nos certificar de que mantemos nosso código alinhado de
forma clara e organizada Agora, precisamos fazer um pouco
mais para a rotação porque,
como eu disse, anteriormente, era um valor meio
arbitrário apenas sendo multiplicado
pela velocidade atual sem
nada mais contabilizado Então, vamos fazer um
pouco de fixação e arrumação para tornar isso um
pouco mais refinado também O que queremos é que
usemos nossa velocidade atual. Chegaremos à
velocidade atual que temos, então ainda vamos
baseá-la aproximadamente na mesma coisa, mas com algumas modificações. A maneira como vamos fazer
isso é a partir da velocidade atual. Queremos fazer uso
de algo chamado intervalo
de mapas fixado Isso mapeará uma
faixa de valores para outra, perfeita para converter
a velocidade em um ângulo de inclinação específico No alcance A,
nossa velocidade de movimento será negada. Então, clicaremos com o botão direito do mouse,
pesquisaremos a velocidade
de movimento porque ela está sendo acessada pela nossa classe principal, a velocidade-alvo real ,
a velocidade máxima
que podemos mover, então obteremos
a velocidade de movimento. Vamos multiplicar
isso por menos um. Sinta-se à vontade para se dar
espaço à medida que avança. Então essa
será nossa faixa A.
Na faixa B simplesmente estará
a velocidade de movimento,
então inalterada E, novamente, estou me dando
um pouco mais de espaço, pois precisaremos de mais
coisas aqui embaixo. Então,
precisaremos de um novo valor para nossa
inclinação máxima e mínima que queremos alcançar Então é aqui que, na verdade,
não temos um
pouco de controle. Então, podemos dizer que queremos que ele
seja capaz de
inclinar no máximo 15 graus a qualquer
momento ou
25 ou o que você quiser
na categoria de rotação E, novamente, se você tiver
categorias, tudo bem. Caso contrário, basta pegar qualquer
flutuador que você tenha. Vou pegar
meu fator de inclinação, duplicá-lo e
chamá-lo de inclinação máxima. Clique em compilar e
acho que, por padrão, darei a isso um valor
máximo de 15, então isso reduzirá a
rotação de 15 graus Você poderia criar uma inclinação mínima, que seria menos 15, mas semelhante ao que
fizemos aqui, em vez disso, vamos
pegar nossa inclinação máxima e
multiplicá-la por E essa será a
nossa faixa A, e você começará a ver
como tudo isso funciona. Espero que, como você vê,
eles se juntem. E eu vou
pegar nossa inclinação máxima e então essa
será nossa faixa de saída B. Então, vamos pegar
nossa velocidade atual, qualquer que seja nossa velocidade atual,
conforme calculada, conforme calculada, se estiver em algum lugar
entre zero e menos nossa velocidade máxima de
movimento Acho que foram 1.000. Então, nossa inclinação
máxima variará
de zero a menos 15 com
base em uma espécie de porcentagem,
um valor uniforme que
corresponderia aproximadamente à velocidade E vice-versa,
se estivermos nos movendo para a direita
, levaremos
nossa velocidade máxima de movimento, zero a 1.000 positivos, e eu escolherei um valor de
inclinação de 0 a 15 graus Então é assim que podemos realmente
fixar, em vez de apenas
ter uma rotação completamente arbitrária de qualquer Na verdade, estamos baseando isso
especificamente entre qualquer que seja nossa velocidade
atual e, em seguida, mapeado entre as
velocidades reais que podemos Isso
facilita muito a atualização. Se quiséssemos dizer
que temos mais inclinação, mas mantemos a mesma velocidade
, podemos simplesmente aumentá-la Eu poderia dizer que agora você
pode inclinar até 25 graus em vez de apenas 15 Para testar, acho que
vou mantê-lo em 15, mas podemos contornar isso
com muita facilidade. Não queremos promover
isso para uma variável. Então, o que quer que isso
calcule, vamos promover
para outra variável Vou chamar isso de inclinação de alvo. É muito semelhante à forma como
a primeira coisa que fizemos em movimento foi calcular
nossa velocidade alvo. E conecte isso ao
zero, mova isso para cima. E provavelmente teremos
que fazer uma boa quantidade
de ajustes aqui para manter isso mais legível, só porque há muito mais tipos de matemática
acontecendo nessa função A rotação é
sempre um pouco
mais complexa e complicada do que
calcular o movimento
ou o tipo geral de localização ou até mesmo mais complexa e complicada do que calcular o movimento
ou o tipo geral de localização ou deslocamentos de escala Agora, o alvo
Alpha é na verdade tão parecido que vou
ficar um pouco preguiçoso Vou voltar
ao movimento das alças. Vou pegar todo
o código aqui, pressionar o controle C, então vou pegar todos esses nós aqui. A única coisa que não
queremos é a mudança Alpha. Vou voltar
aqui para a rotação, e vamos conectar isso
a um valor em um momento. A única coisa que talvez
queiramos fazer é
mover nossa inclinação alvo para a categoria de rotação Na verdade, vou renomear
isso porque temos algumas convenções de
nomenclatura ligeiramente diferentes em Então, vou pegar a velocidade de
interposição de rotação e alterá-la para inclinação, porque decidimos
que todo o resto está sendo classificado como
inclinado em vez de inclinado em vez Vou controlar o arrasto e a velocidade de intercalação
da inclinação. E conecte isso aí. Assim, podemos nos livrar da velocidade de interação do movimento
no início Mas, além disso, estamos
fazendo exatamente a mesma coisa. Estamos calculando nossa velocidade de interposição de
inclinação multiplicada pelos segundos do Delta
mundial G,
multiplicada por menos um, obtendo o retorno exponencial
e, em seguida, estamos
criando isso novamente, em seguida, estamos
criando isso novamente, nossa Então, estamos retirando todos
esses valores de um. Então, os resultados disso serão outra nova variável,
então vamos promovê-la
para outra variável, e vamos chamá-la de Tilt Alpha. Porque vamos querer fazer
a mesma coisa novamente. Conectaremos isso
ao nosso próprio nó de interpolação ou loop, do qual teremos controle
total Então, vamos adiantar isso novamente tentando manter as coisas
um pouco arrumadas Acho que só por questões de limpeza e espaço, vou
deletar isso agora Não precisamos passar passo a passo, como
fizemos anteriormente. Simplesmente não usaremos nada
do código antigo aqui. Então, vamos criar
outro pino de sequência. Queremos fazer nossa
próxima etapa da lógica. Esse é muito
simples. Então, muito semelhante novamente ao terceiro estágio
em nosso código anterior. Vamos definir
nossa inclinação atual. E acho que só de
olhar para isso agora, provavelmente
vamos
começar a misturar valores aqui. Então, até que queiramos
e atualmente estamos usando o fator Tilt, acho que
vamos perder Então, vou
renomear esse
fator de inclinação para inclinação atual E essa palavra está lentamente
perdendo todo o significado. Eu já disse
isso muitas vezes. Vamos arrastar isso para dentro
e conectar o pino de execução. E, novamente, o valor que
queremos preencher aqui,
garantindo que, se clicarmos em compilar,
isso não tenha mais
um valor padrão,
então vamos defini-lo como zero Esse valor será calculado
com base em outro loop. Então, a mesma coisa novamente,
um loop flutuante. E a mesma coisa novamente.
Então, vamos pegar nossa inclinação atual,
nossa inclinação alvo e nosso
Alpha. Tão bonito e simples. Praticamente, como mencionei,
gosto do movimento, mas agora tudo está relacionado à rotação
ou inclinação. Então você pode ver o
padrão. Na verdade, conseguimos usar
basicamente o mesmo código. Então você não
entendeu isso uma vez? Muito fácil de reutilizar
e refazer. Precisávamos ficar um
pouco mais complexos com parte inicial
da rotação aqui em cima,
mas, por outro lado, era muito semelhante Então, podemos fazer a
mesma coisa novamente. Queremos mais um pino,
e isso vai realmente usar esses valores
e definir a rotação. Então, a mesma coisa novamente.
Desta vez, queremos usar
a chamada da função set actor
rotation. Então, vamos colocar isso aqui, e voltaremos e faremos
uma pequena limpeza com
alguns reenraizamentos um pouco mais tarde Vamos dividir o
pino da estrutura como fizemos anteriormente. Vamos pegar nosso valor de inclinação
atual e conectá-lo
ao que estamos fazendo
isso no rolo E é basicamente isso, mas temos os
mesmos passos novamente. Portanto, defina o alvo, defina o Alfa, defina o atual e use o
atual como valor. Agora, vou
entrar, como mencionei, vamos
arrumar um pouco porque está ficando um pouco apertado
e difícil Acho que tudo bem se
eu não vou gastar muito tempo
imprimindo os nós, mas isso é suficiente apenas para
manter as coisas separadas E, como
mencionei, não quero
gastar muito tempo apenas
comentando Não é a coisa mais útil de se
ver na transmissão ou em um vídeo. Mas se você quiser
fazer algo semelhante, apenas uma pequena coisa entre os tópicos, talvez novamente, pause o conteúdo e
diga que está fora de
uma tarefa para garantir que você
entenda o que está acontecendo Leia o código e a rotação
e veja se você pode fazer alguns bons comentários para descrever exatamente
o que está acontecendo aqui, por que estamos usando o
grampo de alcance e coisas assim E o principal é que, se
você precisasse voltar e examinar o código em um
ou dois meses, de relance, é muito mais fácil ver
o que está acontecendo do que isso, atualmente, pois eu precisaria
voltar e ler em profundidade Mas vamos verificar se tudo está funcionando. Acho que a principal coisa que temos nossa inclinação máxima está definida como 15, então devemos ver apenas uma inclinação de 15
graus de qualquer E, obviamente, estamos apenas negando isso com base na velocidade
do movimento A velocidade de movimento ainda é 1.000, o que eu acho que está perfeitamente correto. Se parecer um
pouco mais lento, podemos voltar e
aumentar isso Quanto à velocidade de interação, acho que
queremos diminuir
um pouco a velocidade. Acho que vamos reduzir
isso para três em vez dez porque nossa
curva de decaimento funcionará um pouco
diferente do que estamos fazendo com F interp dois e, em seguida, a corrente
alvo e o Alpha devem ser
definidos em tempo de execução, então eles devem começar em
zero, o que é perfeito E então estamos apenas usando
isso aqui. Então, acho que isso deve funcionar agora. Então, se voltarmos, aperte
play. Sim, lá vamos nós. Parece que
parece diferente, mas podemos ver que é
praticamente o mesmo. Acho que meio que prefiro
a aparência. É muito mais simples,
só que parece um pouco mais refinado.
Então, isso é muito bom. E, como mencionei,
agora é aqui que entra a
flexibilidade. Se você quisesse alterar
a velocidade, talvez a intercalação fosse muito lenta. Nós podemos aumentar
isso. Então, voltaremos ao modo de jogo aqui. Então, estamos
voltando a esclarecer você um pouco
mais rápido. Então, tudo bem. E então, se você quiser,
como mencionei antes, se não tiver certeza do
que algo está fazendo ou para que lado
um valor deve seguir, se você o torna realmente drástico, fazer uma mudança realmente grande E você pode ver
que é quase
como contra-atacar
quando nos soltamos Então, a decadência está acontecendo muito mais rápido e estamos
contra-atacando Então, isso pode parecer um
pouco melhor, na verdade. Então, talvez eu estivesse errado, talvez ir para um
valor mais alto em vez menor teria sido
melhor para isso, agradável e fácil de testar, mas
isso é o principal. Tente incorporar a maneira como você pensa
sobre sua própria base de código Facilitar a atualização e o ajuste posterior aumentará a
probabilidade de
você refinar o jogo
e melhorá-lo você refinar o jogo
e melhorá-lo Se for realmente
difícil trabalhar com seu projeto, é muito menos provável que
você
queira refiná-lo Passe esse tempo para
melhorar o jogo. Então, é mais uma questão
de design , na qual é sempre
divertido pensar. A última coisa é a inclinação máxima. Então, se pegarmos a inclinação máxima, se eu fizer algo muito maior, como 45 graus só para mostrar a diferença que podemos
obter, se flutuarmos, você pode ver que quando começamos a velocidade máxima,
estamos
atingindo aquele ângulo de inclinação
máximo mais alto Então é assim que isso
entra em jogo. Provavelmente não quero que ele
gire muito, mas talvez você queira
aumentar algo mais como 25 para torná-lo
mais visível visualmente Mas a principal coisa que
temos sobre a
implementação anterior é, como você viu. Na verdade, não estava fazendo nenhum cálculo
específico para atingir um determinado ângulo de rotação com base na
velocidade ou qualquer coisa. Estava indo o mais longe
possível dentro de um
determinado período de tempo. Já agora,
temos um pouco de controle. Dependendo da nossa velocidade atual, podemos controlar exatamente o
quanto giramos E então, a coisa
mais importante a verificar é que vou usar alguns comandos do console
para me livrar dos inimigos. Nós não precisamos deles.
Continue voando até nós. Vou entrar no
modo de jogo. Vou dar a mim mesmo o comando stat FPS do
console, para que possamos ver que estou
rodando a 120 Eu me coloquei
diretamente em 30. E, novamente, devemos
ver que estamos obtendo uma
estrutura muito menos agradável de se ver, mas ainda estamos obtendo
apenas 25 graus de rotação e estamos atingindo o que
esperamos ver em um momento,
aproximadamente na mesma Então, se eu agora aumentar isso para 60, estamos alcançando apenas
a mesma rotação, o mesmo tipo de inclinação de inclinação ou
inclinação de rotação, desculpe Estou fazendo isso aproximadamente
na mesma quantidade de tempo. E então, se subirmos para 120 ou, na verdade, vamos
simplesmente abrir o limite Eu vou dizer cerca de 600, então eu posso
obter cerca de 300 FPS. Parece mais suave, mas os movimentos acontecem
na mesma velocidade e a rotação está
levando o mesmo número de quadros ou segundos
para chegar lá Então, agora corrigimos completamente o
problema de independência da taxa de quadros que tínhamos anteriormente. Então, lembre-se de que o movimento não
era realmente um
grande problema, mas a rotação tinha
um problema em que,
embora estivéssemos
multiplicando por segundos por causa disso,
exatamente o tipo de lógica que as funções F
inter estão usando, lembre-se de que basicamente conseguimos girar a asa
até o chão
porque a rotação
não estava bloqueada porque a rotação As diferentes taxas de quadros o estavam
afetando de forma diferente. Então, agora
resolvemos completamente esse problema. Tivemos que nos aprofundar um
pouco
mais na matemática, usando a função
de espreita
simplificada, mais rudimentar simplificada Mas, ao aguentar um
pouco a chuva com nosso próprio código, agora
resolvemos vários problemas que
foram lançados. Você
provavelmente encontrará muitos jogos
porque muitos
jogos são lançados
com base em exemplos de conteúdo, código de
produto e
coisas assim Esse é o teste completo.
Mesma velocidade de movimento. Temos os mesmos limites
de rotação. Não há nenhuma asa
atravessando o chão. A fórmula exponencial
é o que nos dá a interpretação matematicamente
correta em qualquer taxa de quadros Espero que um
conteúdo mais aprofundado como esse não tenha congelado
completamente seu cérebro e impedido você de acompanhar. Esse foi realmente o
objetivo dos tópicos
quando eu os criei: tentar fazer com que as pessoas pensem mais
sobre sua base de código e o que está acontecendo nos bastidores e não apenas acompanhem. Então, espero agora você possa ver os benefícios
do que somos. Eu mencionei desde o início Isso está demorando muito
mais do que poderia ter acontecido, e eu poderia ter simplesmente
editado muitas informações triviais ou
o que pode ter parecido informações
triviais, mas acho que você
teria perdido muitas que
agora você possa ver os benefícios
do que somos. Eu mencionei
desde o início.
Isso está demorando muito
mais do que poderia ter acontecido,
e eu poderia ter simplesmente
editado muitas informações triviais ou
o
que pode ter parecido informações
triviais,
mas acho que você
teria perdido muitas das
potencial de aprendizado e realmente entender
o que você está fazendo. O objetivo aqui é que, com sorte, você possa assistir algo assim, evitar
assistir a mais duas ou três outras séries de tutoriais ou cursos ou qualquer que seja o
caso, porque
na verdade você está aprendendo muito mais sobre os sistemas e consertando coisas que até existem no conteúdo oficial de aprendizagem
da Epic Então, espero que haja
valor nisso. Então, se você realmente quiser começar a refinar seu projeto agora, é
aqui
que você provavelmente tem o tipo geral de compreensão do que
vamos fazer Organizamos nosso projeto em um local bastante rígido
e sólido Então, se você quiser começar a
experimentar entre os tópicos, é
aqui que você pode
querer frear um pouco . Novamente,
isso não é uma corrida. Não pretendemos
concluir o projeto o mais rápido possível Nosso objetivo é fazer com que você saia, entenda o que
está fazendo e como expandir o
que já aprendeu Então, talvez faça algo simples, mesmo que seja apenas
entrar em seu próprio código, ver se agora você pode comentar e descrever o que seu
código está fazendo
para si mesmo usando
alguns bons comentários
ou categorizando para si mesmo usando
alguns bons comentários as variáveis Se você percebeu que tem
essa longa lista de variáveis
e pode ver uma maneira
de melhorá-la, comece a adicionar categorias
às suas variáveis, coisas
simples para manter
seu projeto estruturado, organizado e fácil de trabalhar Lembre-se de que o objetivo principal é que as sequências sejam seu controle de fluxo, tornando-as mais legíveis, como código de script normal ou
código Bons comentários,
explique a intenção em vez de apenas
descrever a variável Coisas como você poderia
simplesmente fazer um comentário dizendo interpolação alfa,
mas um bom comentário seria calcular os valores de
independência da taxa de quadros com base na interpolação alfa, coisas assim para fornecer um descritor,
de uma forma rápida do que
você está fazendo e por quê Com isso feito, porém, o sistema de movimentação
está pronto para produção. Temos movimentos e
rotação suaves e
controlados com taxa de quadros independente para o jogador, que é a classe mais pesada
e complexa que teremos
no projeto seguir, veremos como gerar inimigos dinamicamente
durante o jogo, em vez de apenas
colocá-los manualmente, o que obviamente
será um
pouco restritivo para um pouco restritivo para
19. 18 — EnemySpawner: É hora de automatizar a geração de
nossos inimigos. Estaremos construindo isso de forma
flexível desde o início. começar, isso funcionará para
os inimigos, mas vamos prepará-lo um pouco para o
futuro, então isso funcionará com coisas
como objetos de fundo ou qualquer outra coisa que
precise aparecer com o tempo. Chega de
colocar inimigos manualmente, o que será o
primeiro passo importante. Então, para começar,
vamos até nossa
pasta Blueprint e vamos
criá-la dentro de uma nova estrutura de pastas Então, vou pressionar
Control Shift e N para uma nova pasta, chamada
de spawners Clique com o botão direito do mouse, iremos
para a aula Blueprint e queremos criar nossa classe de ator padrão do
blog Como mencionei, isso
é apenas um contêiner. Tem uma transformação, um
lugar no mundo, e então podemos colocar
nossa lógica aqui. Vamos dar a esta o nome de BP Underscore Spawner Então, como mencionei,
planeje um pouco para frente. Não vamos especificar que isso será apenas para inimigos, e talvez tenhamos outros
geradores que serão filhos dessa classe
com herança Dentro disso, queremos
apenas ir
direto ao nosso gráfico de eventos. Não há nada que precisemos adicionar visualmente para representar isso. Acho que, nesse
caso, podemos nos livrar do fato de o ator ser uma sobreposição, e a maioria das coisas aqui
deve ser responsiva, então não devemos
fazer verificações e atualizações constantes
nos eventos,
para que possamos nos livrar dessas duas chamadas de
função Podemos orientar nossa lógica central a partir de uma função personalizada.
Acabei de mudar isso. Vamos criar uma nova
função aqui, e eu vou chamá-la de ator
de spawn Então, novamente, tudo o que
estamos fazendo à medida que avançamos e planejamos é tentar
manter isso muito genérico. Não estamos dizendo gerar peça de
fundo, captador de
geração, geração de inimigo Tudo o que precisamos transmitir
é um argumento sobre o tipo de ator
que queremos gerar, e provavelmente precisaremos
talvez de alguma rotação aleatória, um deslocamento, localização
e coisas assim Podemos tornar isso
agradável e genérico
e tornar tudo
muito reutilizável Então, sempre tentando planejar com antecedência. Lembre-se, pense com preguiça,
planeje o programa uma vez e use quantas
vezes for possível Dentro dessa função, vamos extrair do pino de execução
e, na verdade, temos uma
função embutida dentro do Unreal, chamada spawn actor from class Quando estamos usando essa função, a principal coisa que queremos, como mencionei,
é uma transformação, então onde queremos que
isso apareça e especificamente, em que tipo de
classe queremos gerar Então, no momento, isso poderia
ser algo como nosso inimigo, mas, novamente, isso
seria muito específico. Então, se destacarmos e passarmos o mouse
sobre o pino roxo aqui, podemos ver que isso
se
refere especificamente ao tipo de ator Portanto, esses pinos roxos são as
referências reais da classe em si, não uma instância no mundo Quando temos esses pinos azuis, essa é uma instância real
que existe no mundo Podemos pensar nos pinos
roxos como uma referência à localização dentro da nossa estrutura
de pastas Então, vamos fazer uso
dessa digitação genérica. Vamos
partir daqui e,
na verdade, promoveremos isso para uma variável. Vamos dar a este o
nome do tipo de ator. Use isso agora
que podemos preencher isso com qualquer tipo de
ator em nosso projeto,
seja um
inimigo, uma picape, uma peça de fundo quando os
adicionamos, o que quisermos, agora
podemos fazer com que essa função gere peça de fundo quando os
adicionamos, o que quisermos, agora
podemos fazer com que essa função gere isso em um determinado ponto As principais coisas que
vamos querer expor
são os detalhes da transformação de spawn Então, se escrevermos,
clique aqui,
dividiremos a estrutura pi. Vamos deixar a escala de
transformação de spawn para 11 e um Geralmente, tentamos não
substituí-los. Se tudo foi
configurado corretamente, como neste projeto, todos
os ativos devem estar na escala
correta para começar. Então, vamos manter isso
e assumir que os ativos são importados
e funcionam conforme o esperado. Você tem a opção de
randomizar ou deslocar
a rotação, mas vou manter isso
limpo por enquanto, e sempre podemos voltar
e refazer Em vez disso,
vou clicar com o botão direito do mouse e pesquisar por Obter rotação de
atores. A razão para isso é que isso significa que podemos conectá-lo
diretamente. E onde quer que
giremos nosso gerador, temos controle total
no editor, então agora essa é mais
uma ferramenta de edição, onde se eu quiser que isso gere coisas para
os lados, só preciso
me lembrar de
girar o gerador real para girar alternativa seria
expor isso a uma variável e
conectar manualmente a rotação, mas acho que essa pode ser
uma ótima maneira de trabalhar É um pouco
mais intuitivo para mim, desde que não seja
muito restritivo, o que acho que, neste
caso, devemos ficar bem Para a localização, vamos
retirar daqui e
adicionar um pino positivo. Este pode precisar de um
pouco de randomização, alguma variação e
compensação fornecida Se clicarmos com o botão direito do mouse, podemos
pesquisar a localização do ator G. Então, a mesma coisa novamente,
vamos usar as propriedades gerais de
onde quer que o gerador esteja, então esse será nosso ponto de partida
básico Agora, para esse tipo de jogo
, como sabemos que estamos indo apenas de uma perspectiva de
cima para baixo, não
precisamos de nenhuma
randomização no Z e provavelmente queremos fazer toda a nossa geração fora
da tela, que significa que
também não precisaremos nenhuma randomização no Então, o que poderíamos fazer é
clicar com o botão direito mouse nesse segundo pino vetorial
e dividir a estrutura. Vamos usar nosso pino
Y aqui e queremos usar esse
nó de seleção que vimos anteriormente. Não queremos selecionar float. Queremos este aqui
com o ícone exclusivo. Isso nos dá o curinga
que usamos anteriormente. Vamos mudar isso para um booleano, então vamos
randomizar ou não, e eu vou promover o índice
aqui para uma nova variável, e vamos chamá-la de adicionar deslocamento aleatório Novamente, lembrando de
dar a isso um B. Se decidirmos adicionar
um deslocamento aleatório, queremos fornecer algum tipo valor
flutuante dentro
de E, novamente,
vimos como fazer isso, então agora estamos apenas analisando
as funcionalidades
e abordagens que já
adotamos no passado Então, se isso for verdade, se estivermos
adicionando um deslocamento aleatório, extrairemos daqui
e usaremos aquela função aleatória flutuante no intervalo que
vimos antes E a partir disso,
queremos apenas uma distância lateral, ou
seja, uma distância lateral mínima e máxima
que possamos aplicar Então, se obtivermos nossa flutuação
máxima aqui, vamos apenas
promovê-la a uma variável, e daremos a essa
o nome de distância de deslocamento O mínimo é que, como
vimos antes, com velocidades e
coisas assim, será o
inverso negativo, então podemos controlar o arrasto
na distância de deslocamento, multiplicar isso por menos um e inserir o
resultado Então, se definirmos uma distância
de, digamos, 100 unidades, e
quisermos que isso aconteça em qualquer lado do centro
da tela, colocaríamos esse
ator de desova no centro
da tela inseriríamos o valor 100
na distância de deslocamento Isso significa que ele
pode gerar -100, 100 positivos ou algum
valor intermediário Se decidirmos não expor a variável e não tivermos
o deslocamento aleatório ativado
, vamos apenas adicionar false Então, vamos adicionar zero
à nossa transformação geral, que significa que o ator aparecerá exatamente onde o colocamos É relativamente simples, mas
ainda é uma espécie de ferramenta para desenvolvedores, algo que podemos usar
se for necessária mais complexidade, mas que nos dá alguma flexibilidade e variação em nosso projeto, geralmente faz com
que as coisas pareçam mais interessantes
e divertidas de jogar. Algo que eu ainda não mostrei,
e quero apresentar aqui porque estamos criando
um desenvolvedor muito rudimentar Isso é algo muito útil dentro do Unreal Outros mecanismos fazem coisas semelhantes, permitindo que
as pessoas vejam as variáveis fora
da classe. No momento, por
exemplo, se pegarmos uma de nossas classes geradoras e a
colocarmos no mundo, certificando-nos de que
compilamos e salvamos tudo, podemos ver aqui que
os objetos selecionados, nenhuma das
variáveis que
acabamos de criar, está
realmente Não seria possível
entrar manualmente por instância. Então, se tivéssemos três
ou quatro desses, não
poderíamos
escolher que este tinha alguma randomização e
uma distância única, e este não tinha
randomização, por exemplo Atualmente, temos apenas um
lugar em que podemos mudar isso, e isso está
aqui no gráfico. Então, ele pegaria esse
booleano e o desativaria, e então isso seria ativado ou
desativado para todos eles. E da mesma forma, pela distância. A maneira mais útil de substituirmos
isso são esses ícones aqui Você pode não ter
tocado neles ainda, mas se clicarmos neles, ele
fornecerá um pequeno ícone de olho. Por padrão, eles começam fechados
e podemos abrir o olho. Em outros idiomas,
isso é chamado de tornar algo público. Ele é exposto a
outras classes e pode ser lido e gravado
fora dessa partir de um modelo irreal,
isso é apenas tornar a variável
editável essencialmente fora da classe Então, se entrarmos em nosso ponto de vista novamente com os mesmos
objetos selecionados, você pode ver que,
no menu suspenso padrão, temos acesso ao tipo de ator que
queremos que isso Então é aqui que
podemos começar a fazer coisas como essa:
criar inimigos. Não vamos fazer isso, mas isso pode
gerar jogadores. Portanto, já temos
alguma flexibilidade no que eles
vão gerar E então, como os inimigos podem querer ser mais aleatórios, podemos ativar essa
opção como verdadeira para adicionar um deslocamento aleatório
em qualquer direção, e podemos
definir que seja, como eu disse, talvez 100 unidades
à esquerda e à
direita do gerador. Muito bom e simples,
como você viu, não
é uma configuração muito complexa, mas já temos
uma quantidade relativa de flexibilidade e liberdade
na forma como a usamos. Então, no momento, se
adicionássemos isso ao início do jogo e fizéssemos com que fosse chamado
uma vez, um inimigo não seria um grande
desafio para nosso jogador. Então, o que queremos fazer é adicionar
alguma desova contínua. Vamos evitar
usar coisas como atrasos e loops, pois isso se torna
confuso e Então, você já deve ter visto
algo assim antes, onde, ao começar a jogar, novamente, eu só quero visualizar algumas
das coisas que vi
em muitos projetos Então você pode ter algo como entraremos pela primeira vez e geraremos um ator uma vez.
Em seguida, adicionaremos um atraso. Portanto, um atraso é apenas um
tipo de processo de espera cronometrado. Vamos esperar,
digamos, 3 segundos. Antes de fazermos a próxima coisa, e depois geraremos o ator novamente. E você pode ficar tentado
a vir aqui
e, talvez, depois de cada
vez que isso for feito, tente encontrar uma maneira de se
lembrar de si mesmo Vai ficar confuso. Você acaba vendo
pessoas fazendo coisas assim, vamos
repetir o plano de fundo, e você acaba com
esse loop infinito em que as pessoas dizem que
depois de
gerarmos isso, vamos esperar
mais 3 segundos e chamar o ator de spawn Então, vamos evitar
esse código de estilo iniciante. O que queremos usar em vez disso
é algo chamado temporizadores. Eles são muito mais limpos
e nos dão muito mais controle sobre se
e quando eles são chamados. Então, a partir de nossa jogada inicial, o pino de execução, queremos encontrar uma função chamada I valid. Queremos essa opção com o ponto de
interrogação na parte inferior. Isso é verificar
se outro objeto ou ator é
válido atualmente, ou seja, ele existe e não está
sendo enviado para a coleta de
lixo para limpeza se estiver sendo destruído
ou algo parecido Do objeto de entrada, então o que queremos
verificar se ele existe, vamos extrair daqui e usar essa função embutida, o peão get player Então, isso é, novamente, apenas uma
dessas coisas a considerar. Isso acontece em muitos
jogos para novos desenvolvedores em que você
criou um jogo como esse e os inimigos
destruíram o jogador. Mas mesmo quando você está
na tela de fim de jogo ou está apenas
esperando pelos créditos ou o que quer que esteja acontecendo depois, você pode ver o
inimigo ainda aparecendo ou atirando no jogador, espécie de cachorro empilhado
em um cadáver Parece um
pouco intenso, e geralmente é porque não
há nenhuma verificação no meio do jogo para
ver se os jogadores realmente
estão ver se os jogadores realmente classificados como mortos ou
não estão mais disponíveis O que vamos fazer é que, se o jogador for
removido do jogo, não
haverá mais necessidade de os inimigos aparecerem, então
vamos parar Se isso for verdade, então se o
player ainda for válido, vamos chamar
uma função aqui, que é o cronômetro definido
pelo nome da função Queremos essa opção aqui, e a primeira coisa que podemos
preencher é a hora aqui. Então, esse é o tempo que
vamos esperar até essa função que
criaremos em um momento seja chamada. Então, por enquanto,
podemos partir daqui e procurar outro flutuador
aleatório no alcance E um pequeno
truque, que pode ser muito útil quando
você não quer apenas ter o mínimo e o máximo ou algo que seja
o inverso um do outro Podemos fazer uso de
algo chamado vetor dois D. Então, se criarmos
uma nova variável, chamaremos essa variável de intervalos de
geração E vamos
descer isso, e vamos pesquisar
aqui, em vez de um vetor, que é um valor flutuante de três
pontos, também
vamos
procurar um vetor. Queremos este
aqui embaixo, o vetor dois D. E se clicarmos em Compilar, podemos ver que tudo isso são apenas dois
valores de ponto flutuante, onde o valor X será nosso mínimo e o
valor Y será o máximo Então, podemos definir isso para
algo como um mínimo de 3 segundos antes
que algo apareça e um máximo de seis E podemos voltar
e ajustar isso mais tarde. Podemos arrastar
isso para o gráfico, clicar com o botão
direito do mouse no pino da estrutura, dividir o
pino da estrutura aqui e
podemos dizer mínimo, máximo. Portanto, uma boa
maneira limpa e organizada de configurar a função de
temporização Para o nome da função, temos
nosso ator de spawn aqui. Uma coisa que eu sempre
costumo fazer, novamente, em parte porque sou preguiçosa e não
quero digitar coisas, mas também para evitar cometer erros de
ortografia ou digitação Vou pressionar F
dois para renomear isso, pressionar Control N C para
copiar e,
em seguida, controlar NV aqui para colar isso NV aqui para colar isso, garantindo que
tenhamos a mesma grafia, a mesma capitalização, evitando erros no nome porque isso diferencia maiúsculas de
minúsculas e precisa ser
escrito Não vamos
definir isso como loop, mas se você tivesse
uma função em que
quisesse que ela
continuasse constantemente,
você poderia configurá-la como loop, e ela
continuaria girando
e girando e, basicamente,
chamando-a chamando-a Querer um pouco
mais de controle manual. Vou me certificar de que
isso não esteja marcado. E o que podemos fazer
é pegar todo esse código, incluindo
o que é válido, porque se você pensar sobre isso, quando começamos a jogar, não
há razão para
que o peão do jogador não
seja realmente um objeto válido Sempre
existirá quando pressionarmos play. Então, o que vamos
fazer em vez disso é clicar com o botão
direito
do mouse em qualquer um desses nós e reduzir
isso em uma função. Vamos dar a isso o nome
de call spawn Aca timer. Então, estamos meio
que ofuscando um pouco
a lógica Então, novamente, as etapas são
um pouco mais claras e fáceis de entender à medida
que analisamos nosso código. E a maneira como
realmente queremos
lidar com isso é que provavelmente vamos querer criar
alguns inimigos imediatamente Então, em vez de desovar
com base em um cronômetro, podemos ignorar Então, começaremos criando
um ator diretamente. Vamos colocar isso em
nosso pino de execução. E, novamente,
pensando na ordem da lógica em nosso código. Assim, sempre podemos
refazer coisas como. Vamos começar a
jogar e vamos
criar um ator imediatamente O que isso vai fazer,
vai cair aqui. Em seguida, escolheremos nosso tipo de ator se
tivermos um conjunto, escolheremos um local e um deslocamento, se houver um deslocamento
a ser aplicado, e selecionaremos a rotação e
geraremos isso em um ponto E depois disso,
é aqui que podemos começar a fazer um loop quase
automático Então, se quiséssemos que
isso continuasse, poderíamos pegar nosso cronômetro principal de
spawn actor colocá-lo aqui E o que isso
fará agora é entrar, e isso é mais importante
aqui porque, em tempo de execução, é aqui que, após
a primeira ou a segunda aparição, podemos ter destruído o
jogador Então, este que eu faço
é um cheque válido, um cheque muito simples e
barato para
garantir que o jogador ainda
esteja no jogo. E se estiverem,
vamos permitir que
ele gere outro ator,
usando a função spawn actor, basicamente, chamando essa
função novamente após um determinado período ou
intervalo de tempo Agora, é algo que
eu gosto muito de fazer, e isso é totalmente opcional. Mas como quando usamos a função set time by function
name, não
podemos clicar duas vezes e descobrir o que ela está
realmente chamando, precisamos examinar
nossa lista de funções e encontrar o nome correspondente. O que eu gosto muito de fazer é
colocar a função aqui e colocá-la abaixo do cronômetro
definido pelo nome da função Então, isso significa que se eu estiver examinando meu
código no futuro, se eu chegar a esse ponto
e perceber que devo
corrigir ou alterar algo
nessa função aqui, posso simplesmente
clicar duas vezes nesse nó e isso me levará ao
que essa função está chamando Então, só uma
pequena dica, mas acho que pode
ser muito útil, especialmente quando
você volta para ajustar as coisas. Se isso
não for flexível o suficiente, precisávamos remover
alguma coisa, apenas uma boa maneira de navegar Mas isso é praticamente
tudo o que precisávamos. Esse é um bom tipo
de gerador autoencapsulado e
autocontrolado, com alguma flexibilidade
nos diferentes tipos de atores em
que podemos gerar, onde eles vão
aparecer e se alguma flexibilidade
nos diferentes tipos de atores em
que podemos gerar,
onde eles vão
aparecer e se
há alguma randomização aplicada. Também poderíamos descer e expor os
intervalos de desova Assim, poderíamos ter cada ator
diferente, cada criador diferente, com intervalos de tempo
diferentes sobre
quando as coisas deveriam gerá-lo intervalos de tempo
diferentes sobre quando as coisas Portanto, certifique-se de
compilar e salvar. Uma coisa que eu quero
acrescentar antes de realmente
testarmos isso é que, se
formos para a seção de componentes, adicionaremos algo
aqui, vou
pesquisar o componente de seta. Então, na verdade, há
um componente aqui que
podemos usar que é
apenas uma seta visual. Podemos mudar a
cor se você quiser mudar a cor
por diferentes motivos. Mas o principal é que,
novamente, de relance, isso só nos permitirá
saber qual caminho seguir,
então o padrão é sempre apontar
para frente então o padrão é sempre apontar
para Então, se clicarmos em
compilar e salvar, voltarmos
ao nível principal, podemos ver que, de fato,
aqui, os inimigos estarão voltados para o lado errado Então, vou me
livrar de alguns
deles , vamos testar um
de cada vez. Certifique-se de que isso não se
sobreponha ao chão,
caso contrário, os inimigos
não conseguirão se mover E então podemos girar
isso 180 graus no Z.
E você pode ver que agora está
apontando para o início do nosso jogador, o
que significa
que, se definirmos
isso para a classe inimiga, poderíamos atribuir a ela uma
distância aleatória de cada lado,
e um intervalo
de desova ocorrerá Podemos pressionar play, e isso gerará
um imediatamente Então,
dentro de três a 6 segundos , veremos outro
aparecer e pronto Portanto, temos nosso
ator de desova aleatório funcionando corretamente. Ao fornecer a rotação
que mencionei, podemos ver exatamente onde isso
vai aparecer e em qual
direção você estará voltado O principal problema que
temos agora é, obviamente, que podemos vê-los aparecendo, então queremos recuar um
pouco para que eles
apareçam fora da tela Eles farão essa animação e, em
seguida, aparecerão
com esse determinado intervalo Se você quiser colocar uma posição
ligeiramente diferente, ou se quiser mais delas,
você poderia escaloná-la dessa forma, para que pudéssemos ter
vários geradores Você pode fornecer distâncias de
deslocamento
diferentes, intervalos de desova diferentes e
pode escaloná-los um pouco
dessa forma Novamente, para tornar a jogabilidade e a interação
muito mais interessantes. Acho que, no momento, provavelmente
poderíamos escapar impunes com apenas um gerador
para nossos inimigos Então, se descobrirmos
ou decidirmos que
não há o suficiente sendo
gerado em tempo de execução, podemos voltar e
adicionar mais ou
brincar com esses intervalos de
geração Então, outro pouco
de experimentação ou lição de casa que você
pode fazer Você pode fazer algumas
coisas simples aqui, como duplicar o spawner e experimentar configurações
diferentes, como acabei Experimente diferentes intervalos de desova, diferentes distâncias de deslocamento, ative ou
desative E, idealmente, se você
saiu
do conteúdo até agora e criou seus próprios tipos
diferentes de inimigos, você pode ter inimigos que
só se movem para frente, para
trás ou de um lado para o outro,
seja qual for o caso Talvez tente adicionar alguns geradores
diferentes para
inimigos diferentes só para ver como você pode usar
facilmente esse sistema um tanto
flexível E isso é o principal aqui. Estamos analisando e
pensando em como
projetamos nosso sistema. Poderia ter criado
uma classe de ator especificamente para
gerar apenas inimigos Poderíamos ter entrado
na classe e
codificado a lógica aqui para gerar
inimigos especificamente Então, precisaríamos
ter feito a mesma coisa com
um tipo de inimigo
ou com um plano de fundo diferente quando chegássemos lá Essencialmente, muitas
duplicatas funcionam novamente, mais coisas para dar errado
e mais bugs para corrigir Já com essa
abordagem, podemos reutilizá-la posteriormente para os planos de
fundo, diferentes tipos de inimigos, chefes, qualquer coisa para a qual você queira
usá-la
20. 19 — ProjectileBase: Entrando em uma
das partes divertidas agora, é hora de adicionar um
pouco de poder de fogo. Novamente, essa será uma classe de
projéteis que funcionará para os
jogadores e inimigos Como antes, vamos pensar no futuro,
tornando isso personalizável de
acordo com as cores e
os danos, focando nesse
design inteligente desde o
início, economizando na duplicação posterior Então, podemos deixar o
sublinhado da BP Sponerbse se você ainda
estiver aqui Vamos entrar em
nossa pasta de plantas. Vou voltar para a pasta principal
do blueprints aqui Vamos criar uma nova pasta,
então controle a mudança em N, e vamos chamá-la de projéteis Agora, no momento, há uma boa chance de
que esse projeto acabe com apenas
um tipo de projétil Como mencionei,
vamos tentar tornar isso o mais flexível
possível. Mas, novamente, em
versões mais avançadas ou com luz intermitente deste projeto, você pode querer coisas
como mísseis domésticos,
lasers, estilo espingarda, projéteis Portanto, talvez
nem sempre
consigamos reutilizar o
projétil que temos Então, ainda vamos
supor que talvez
queiramos
desenvolver isso mais tarde, mesmo que não o façamos para
esse projeto menor. Então, vamos clicar com
o botão direito aqui novamente dentro da nova pasta. Criaremos uma nova classe de
blueprint. Mais uma vez, esse
será um ator simples, e daremos a ele o nome de
projétil BP Underscore Vamos colocar a palavra
base no final mais uma vez, caso
queiramos expandi-la um pouco mais tarde com versões infantis
semelhantes, mas um pouco
exclusivas. Dentro da nossa nova
classe de atores, queremos apenas, antes de tudo, criar
uma nova malha estática. Então, vamos
adicionar um novo componente, malha
estática, e podemos arrastá-lo diretamente para a raiz da cena
padrão. Então, novamente, fazendo disso
o novo componente raiz. Com a malha estática selecionada, vamos para
o lado direito. Eu forneci aqui o projétil SM
underscore, então vamos selecionar este E esse será nosso
visual do projétil. No lado esquerdo,
voltamos aos componentes. Podemos soltar essa linha
novamente, e podemos ver aqui se pesquisarmos a
palavra movimento do projétil Temos nosso componente de
movimento de projéteis. Unreal tem um sistema integrado para simplificar
parte da configuração Agora, não vamos realmente
usar isso porque, novamente, é bom ter
controle total de nossa própria lógica. Deixe-me
mostrar como isso funciona. Então, se clicarmos em
compilar e salvar com esse conjunto ativado, queremos ir para o lado
direito aqui no painel Detalhes com
o movimento do
projétil selecionado Queremos transformar a escala de
gravidade em zero. Caso contrário, teremos
alguma queda com o tempo. E daremos a isso a velocidade de movimento
inicial de 300. Se entrarmos,
clicarmos em compilar, entraremos em nosso visor e colocaremos
isso no nível Agora, eu não vou apertar play porque queremos realmente
ver isso se movendo. Mas a maneira como isso
funciona basicamente é que podemos clicar em simular, e veremos que isso
dispara em aproximadamente 300 unidades Então, funciona. É agradável
e simples de configurar. Mas, como mencionei, há uma razão pela qual
não usaremos isso. E isso
ocorre principalmente porque o componente inclui replicação de rede, coisas que
realmente não precisamos Muitos
cálculos físicos, novamente, não são necessários para o que
vamos fazer, manejo da gravidade, que desativamos explicitamente,
mas ainda está lá Também é um
pouco inflexível. Queríamos adicionar coisas como
aceleração, ao longo do tempo, localização, tudo isso está meio que
bloqueado na implementação do Epix Por muito tempo, acho que o homing não
funcionou Existem algumas soluções alternativas que
você pode forçar, e a aceleração
definitivamente não funciona. É muito difícil
enfatizar
a velocidade e
fazer com que algo pareça um pouco caricatural, passar
de 100 unidades de velocidade e depois subir para 600 com o tempo
e depois descer novamente É muito difícil controlar
a velocidade desses
componentes em tempo de execução. Essencialmente, se você gerar
isso ao mover 100 unidades, essa será a aceleração,
o valor
da velocidade
desse projétil até você
reiniciá-lo ou destruí-lo Então, por esse motivo,
vamos nos livrar
desse ator e somente por
esse motivo. Em vez disso, mostre como
podemos implementar uma lógica muito semelhante e muito
mais simplista para nosso próprio movimento de projéteis Então, só para
que você saiba que estou ciente de que isso existe, vamos
excluí-lo. Vamos nos livrar
desse componente
e, basicamente, lançaremos nossa própria versão personalizada especificamente para fazer o que precisamos em nosso projeto. Então, se pularmos
para o gráfico de eventos, vamos fazer
o padrão aqui. Vamos nos livrar de
nossa Lei para começar a se sobrepor. E lembre-se do que eu disse
antes, podemos usar venti, e esse é um
daqueles casos novamente, queremos que isso
se mova suavemente ao longo tempo com uma lógica de
movimento simples Então, é no eventk
que queremos que isso ocorra. Fiquei interessado e
queria dar uma olhada no código-fonte do Unreal
Engine, que é até mesmo assim que o componente de
movimento de projéteis está funcionando Isso está sendo executado no Venti para manter as coisas atualizadas constantemente, estrutura independente, agradável
e suave A lógica que precisamos para
isso é muito simples. Portanto, se retirarmos do
nosso pino de execução, procuraremos o deslocamento local
do ator de adição Isso garante que
a localização
do projétil
avance em relação à
sua própria rotação Então, outra
coisa muito boa é que só precisamos nos conectar
para a frente
quando começarmos a gerá-la. E ao usar essa funcionalidade, ele garante que ele sempre estará se movendo na direção correta. Vamos dividir a
estrutura aqui, simplesmente porque sabemos
que só queremos que ela
se mova no eixo X, para frente e para trás Mas você definitivamente poderia
voltar e fazer
algum movimento lateral
se quisesse transformá-lo em algum movimento lateral
se quisesse transformá-lo um projétil teleguiado ou
algo parecido Tudo do Delta X. Vamos transformar isso em uma
variável para obter um flutuador, e chamaremos isso
de velocidade de movimento Clique em compilar e daremos a
isso um valor padrão de algo como 2.000
unidades, ou talvez 2.500 Podemos voltar e
mudar isso mais tarde se for muito rápido. Então, é claro, só
precisamos entrar aqui. Vamos medir nossa velocidade de movimento. Multiplicaremos isso
por nossos segundos Delta,
fazendo com que, como no movimento do
avião, tudo seja independente da
taxa de quadros, e então inseriremos esse resultado aqui. E é mais ou menos isso. Temos um movimento de
projétil independente da taxa de quadros, que se moverá na
direção em que é gerado, tornando-o agradável e
fácil de usar
tanto para o jogador quanto para o inimigo, independentemente da
forma como o
avião inicial esteja enfrentando uma implementação simples e
rápida, mas é
personalizável se
precisarmos estender isso personalizável se
precisarmos estender Então, nos tópicos anteriores
sobre Observando inimigos, mencionei que o
projétil estaria lidando com seu próprio sistema de colisão
e dano, e é exatamente isso que
implementaremos Então, com a
malha estática selecionada, vamos entrar nas predefinições
de colisão E queremos alterar a
predefinição aqui de bloquear tudo para sobreposição ou dinâmica.
Então, vamos detalhar isso. Encontraremos a
sobreposição ou dinâmica e veremos o que isso faz com as predefinições
de colisão O principal motivo é
que o projétil não
deve
empurrar fisicamente as coisas Isso pode acabar em
situações em que as coisas parecem problemáticas,
em tudo o que realmente
precisamos fazer é estar cientes de que elas
tocaram E se você começar a
ser empurrado para trás ou os inimigos
começarem a ser movidos com projéteis, isso pode parecer um pouco
estranho para o jogador Se quisermos adicionar o
knock back como um recurso, tudo bem, mas faremos isso por meio de código para
que tenhamos controle total Geralmente, quando duas
coisas
se sobrepõem fisicamente à função de
bloqueio, não
parece uma
retração Parece que duas coisas estão lutando para habitar
o mesmo espaço, e simplesmente não é
agradável olhar para Tudo o que precisamos que o projétil faça é detectar e atingir algo
e, quando isso acontecer, causar
dano Sem simulação de física
ou coisas assim. Faremos a
mesma coisa que fizemos antes. Vamos rolar para
baixo até o final. Encontraremos a seção de eventos e queremos adicionar
o componente on para iniciar
a chamada da
função de sobreposição aqui Então, quando isso se sobrepõe a
outra coisa , como fizemos antes, precisamos descobrir
algumas informações e ver se o dano
será aplicado Vamos pegar o ator aqui,
então o outro ator, novamente, mesma forma que antes, vamos
promover isso para uma variável, e vamos chamar essa
sobreposição de ator E isso porque é o mesmo
motivo que acontece com os inimigos. Vamos querer
comparar algumas informações
com base nisso. Não queremos continuar
puxando esse pino aqui, então usaremos uma variável que
armazenamos como referência Então, a primeira coisa
que acho que queremos considerar é se a coisa que
sobrepomos é referenciada como a coisa que é esponda
, ou seja,
o Então, por exemplo, se
o inimigo disparar, e isso for classificado como
um projétil inimigo, não
queremos que ele
cause dano ao avião do inimigo Da mesma forma, se o
jogador disparar um projétil, isso é classificado como projétil de
camadas Obviamente, não queremos causar
danos a nós mesmos. Então, a primeira coisa que
podemos fazer é obter nosso ator sobreposto e verificaremos se isso é igual a um
tipo específico de ator Então, se isso for igual a, e pudermos pesquisar
outra variável
rastreada incorporada fornecida e rastreada
pelo mecanismo Unreal por padrão, então também podemos
usá-la Vamos
procurar o dono do G. Então, sempre que algo é
gerado no mundo, é imediatamente dado o
conceito do que o possui, que o gerou.
Então, podemos usar isso. Portanto, podemos dizer que, se
a coisa que
sobrepomos também for o proprietário, vamos simplesmente
pular a aplicação A principal razão para isso é
que talvez queiramos escolher nosso ponto de desova, talvez diretamente no
meio do avião Então, haverá
um breve momento o projétil
que o jogador gera ficará, na verdade, dentro
do avião por apenas um Se for esse o caso,
vamos simplesmente
ignorar a primeira sobreposição
aqui, não faremos nada Então, vamos puxar uma ramificação aqui, que é nosso fluxo condicional, então vamos verificar se devemos fazer algo com
base nesse resultado E se isso for verdade, podemos basicamente pular,
não faremos absolutamente nada Agora, a maneira
como geralmente gosto de lê-los, porém, é que gosto de fazer coisas fora da tropa sempre que possível Essa é uma preferência pessoal. Novamente, programadores diferentes sempre
terão preferências
diferentes
sobre como abordam as coisas Mas eu prefiro que meu código finalizado
real, o que faz
a funcionalidade principal,
se torne realidade Então, o que vou
fazer é, na verdade fazer um checkout um pouco diferente Eu só queria mostrar de uma forma mais
legível antes de tudo, mas com uma pequena alteração, podemos realmente
pesquisar que não é igual a. Portanto, um ponto de
exclamação igual
nos dará uma verificação diferente do fator
de sobreposição Vamos conectar isso
aqui, e
agora isso faz a verificação invertida Então, isso é verificar se
a coisa é o dono, e agora é verificar
se a coisa não é então. Então, se conectarmos isso em vez disso, obteremos esse resultado aqui. Então, estamos dizendo que se o
fator de sobreposição não é o proprietário, e é assim que eu
gosto de executar meu código, é que, se esse não
for
o objeto proprietário, podemos fazer nossa Então, mais uma vez, parte
disso é apenas para mostrar a maneira
diferente de pensar sobre seu código e a
maneira diferente de ter
várias abordagens para
resolver o mesmo problema,
mesmo que várias abordagens para
resolver o mesmo problema, se trate apenas de como o código é lido. E isso é bom e simples agora. Podemos pegar nosso ator de
sobreposição novamente, arrastá-lo com
controle,
puxá-lo desse pino, e já
fizemos isso antes Vamos chamar a aplicação de dano
a essa função universal global. Aquele que pode ser aplicado
a qualquer tipo de ator. Então, podemos colocar isso
no verdadeiro pino. Se a coisa que
atingimos não for nosso dono, podemos causar danos a ela. Acho que, por padrão,
darei a isso um valor padrão de 20, então
vamos inserir 20 aqui. Vamos promover isso
para uma variável. Novamente, lembre-se de que, se você colocar um valor aqui antes de
promovê-lo a uma variável, essa variável
já o terá armazenado. E o principal é que não
queremos números mágicos. Vou renomear este para causar dano
de projétil. Clique em compilar e
verifique se
devemos ter o número
20 preenchido aqui Agora, idealmente, depois
de fazer isso, talvez
queiramos começar a
reproduzir alguns efeitos sonoros
e efeitos de partículas
específicos do projétil Eu forneci um tipo
muito pequeno de faísca em vez de
uma explosão total, apenas para indicar que
algo atingiu uma superfície em vez de realmente
causar uma explosão Então, para fazer isso, vou usar o mesmo conceito que
mencionei anteriormente. Vou pressionar C dentro do gráfico de eventos
sem nada selecionado. Vou pressionar C
para criar um novo comentário, e vou dar
um grande sinal de que fazer aqui, e então diremos algo
como implementar efeitos. Isso será algo
que faremos em nosso passe polonês um pouco mais tarde. Isso é bom. Não, isso só vai
nos lembrar de voltar aqui. Como mencionei,
normalmente atribuo a isso uma espécie de cor verde amarela apenas para me lembrar e realmente posicionar contra outras coisas que possam aparecer no gráfico Mas o que
definitivamente queremos fazer é que, depois de
tocarmos nossos efeitos, queremos ter certeza de que o projétil seja
removido do jogo Então, vamos sair
do pino de execução, procuraremos o
ator destruidor e nos
livraremos de nós mesmos. O projétil fez seu trabalho para poder ir embora. E
é mais ou menos isso. Então, vamos verificar
o que sobrepomos. Se não for o proprietário, vamos
causar danos. Agora, essa é uma ligação muito segura. Você pode estar se perguntando e
se eu bater nos limites laterais ou algo parecido com um piso onde eu
possa colocar ou uma picape
ou algo parecido Agora, se isso acontecer
e eles não tiverem a função de ativação de nenhum dano
que vimos anteriormente, podemos ver aqui
o evento de qualquer dano. Eles não têm isso implementado dentro de sua base de código,
então está tudo bem. Eles receberão
essas informações, mas não têm um sistema de saúde nem
nada com que lidar. Então, é como uma mensagem descartável
muito, muito barata Não teremos problemas de
desempenho a menos que façamos algo muito
ruim com isso, e isso não fará
nada Eu não vou destruir o chão ou as paredes
ou qualquer coisa assim Portanto, é uma boa função segura. Não precisamos saber nada
sobre o outro ator. Desde que
toquemos em algo,
podemos descobrir algumas
informações genéricas sobre isso. E se
acharmos que talvez queiramos tentar aplicar danos,
tudo bem. Podemos simplesmente enviar esta mensagem. Então, a última coisa é
tornar isso reutilizável. Esse é o dano
implementado de uma forma bastante universal. Queremos garantir
que nossos projéteis correspondam à cor do atirador, para que o jogador dispare
projéteis azuis e os inimigos disparem projéteis verdes ou o que você
quiser personalizar Então, vamos voltar à
nossa função de começar a jogar aqui. Só queremos fazer isso uma vez quando o projétil for gerado Queremos realmente
pegar nosso componente. Podemos fazer alguns códigos
nos componentes que já
temos, então vamos arrastar isso
para o gráfico de eventos e vamos extrair
daqui e
pesquisar a instância de criação de
material dinâmico. Então, só temos
essa opção aqui. E esse é um
dos benefícios de usar instâncias de material em vez de
nosso material mestre O código básico do sombreador está
com a instância do material, podemos transformá-las em
uma versão dinâmica
e, na verdade, podemos atualizar
suas propriedades em tempo de execução Queremos pegar o valor de
retorno aqui, então essa versão dinâmica
que é criada, queremos promover
isso para uma variável, e vamos chamá-lo de material R. Então é apenas uma referência
ao nosso material. A partir disso, podemos fazer nosso código para alterar algumas
das propriedades principais. A principal coisa, se você quiser
fazer mais sobre isso, é
só saber os nomes das
variáveis com as quais você pode trabalhar. E
isso é muito simples. Se pegarmos a malha estática, mostraremos rapidamente
algumas das outras coisas que você pode fazer depois de aprender
uma que estou prestes a
analisar com você. Se clicarmos duas vezes no projétil
MI underscore, sabemos que esta é
nossa instância material Isso abrirá o ativo para nós. E, basicamente, qualquer coisa que eu tenha exposto para você
aqui, lembre-se, eu disse que
criei esse material grande e
um tanto personalizável Qualquer coisa nomeada em nossa seção aqui pode
ser acessada em código. Assim, você pode alterar a
especularidade em tempo de execução, se quiser fazer com que
as coisas pareçam mais brilhantes e potencialmente Você pode alterar a textura
em tempo de execução, as cores,
as cores de substituição e a propriedade
emissiva, se quiser fazê-la
brilhar. Você queria fazer. Contanto que você saiba o nome
e a grafia específica, você pode alterar e
afetar qualquer um deles Então, a maneira de
fazermos algo realmente simples para mostrar esse tipo de inação é obtermos
nossa referência material E, novamente, por preferência pessoal, sempre
consigo um novo nó
para extrair daqui, mas você pode simplesmente encontrar
as informações
dessa
referência de material que acabou promover para uma variável. Vou pegar nossa
referência de variável aqui e, a partir disso, quero encontrar o valor
do parâmetro vetorial definido. Então, é essa opção aqui. Vemos que isso está
na categoria de material, então estamos procurando
a coisa certa. Isso nos permitirá definir a cor
de um vetor, nesse caso. Então, vamos conectar isso
ao pino de execução. O vetor que queremos alterar será
a cor,
então a cor emissiva E, novamente, podemos sempre
verificar aqui. Isso é chamado de cor emissiva, então é o que
eu estou procurando E a nova cor que eu
quero que seja será
baseada em qualquer
ator que tenha gerado isso baseada em qualquer
ator que tenha gerado Então, se for um inimigo verde, eu
poderia transformar isso em verde. Se for nosso jogador, eu o
transformo em azul. Se você tem um inimigo vermelho, talvez queira
transformá-lo em vermelho. Então, vamos verificar se
isso está funcionando. Se mudarmos isso para
algo bastante óbvio, vamos deixar isso amarelo
por enquanto, clicar em compilar e salvar Não vamos ver isso
acontecer até começarmos a jogar. Então, podemos colocar isso
no gráfico e
clicar em simular aqui Devemos ver isso
começar a brilhar. Outro problema que
acho que tenho aqui é com o projétil MI
underscore Quero ter certeza de
que isso está marcado. Mas também preciso ter certeza
de que isso tem alguma propriedade emissiva Então, vou entrar
e me certificar de que o valor padrão para a propriedade
emissiva aqui é dez Porque, novamente, estamos
multiplicando isso no momento, qualquer cor por zero
fará com que ela não Então, se pressionarmos Play
novamente ou simularmos, na verdade, podemos ver que agora
ficou amarelo Então, se eu me aproximar um pouco mais,
clicarei
em simular para que possamos ver tudo e teremos
um projétil amarelo brilhante Portanto, a única alteração
que você deseja fazer é abrir o material e garantir que ele
brilhe o
quanto quiser Você pode fazer com que seja muito
mais exagerado, então podemos fazer disso
um projétil muito brilhante e
brilhante, dependendo
totalmente Então, vou definir isso para 100 para que fique muito, muito visível. E isso é
basicamente o que fazemos aqui. Então, estamos pegando essa
propriedade pelo nome e definindo-a com um
novo valor, simples e simples Agora, outra coisa
que você pode querer fazer é ter um pouco de brilho
mais do que outros. Então, eu só precisei
entrar e
editar manualmente a intensidade emissiva aqui Então, o que poderíamos fazer
em vez disso é mostrar como
podemos usar esse sistema. Podemos duplicar a referência do
material
e, desta vez, vou
definir um valor escalar Portanto, os valores com os quais
estamos trabalhando, embora sejam
conhecidos como flutuantes, quando trabalhamos
com materiais,
infelizmente, são
chamados de escalares Isso ocorre porque eles são
feitos de um flutuador escalável. Podemos alterá-los em tempo de execução. Então, tente se lembrar disso. É uma terminologia um pouco nova, mas que você
precisa aprender para trabalhar com materiais
especificamente Então, vamos pegar
nosso valor escalar. Essa eu chamei de força
emissiva. Então, vamos conectar
isso. encontrar nossa força emissora E então você pode mudar isso para qualquer valor que você
queria que fosse. Então, poderíamos transformar isso
em algo realmente tolo por padrão, como 1.000 Então, 1.000 pode ter sido
um pouco extremo, mas mostrou o conceito
geral. Vou reduzir
isso para 100. Acho que parece
muito legal, pois propriedade
um tanto emissiva um projétil que
se move bem rápido Talvez precisemos enfatizar isso
para torná-lo mais visível. Como em tudo, não
queremos que essas sejam variáveis mágicas novamente. Só poderíamos mudar isso aqui diretamente no código. Então, vamos
promover nossa cor para uma variável que
podemos rastrear e usar posteriormente. Estamos nomeando essa cor de
projétil pelo nosso valor. Então, o valor do
ponto flutuante aqui. Vamos transformar isso em
uma variável e chamá-la emissiva de um projétil Então, isso nos dará
alguma flexibilidade quando
começarmos a gerá-los
em nossas classes principais, inimigo ou
no jogador Agora, alguns de vocês podem
ter percebido que há outro problema que
ainda não abordamos. E isso é que os
projéteis podem potencialmente voar no espaço para sempre se
não atingirem absolutamente nada Pensei que, se as coisas
atingirem o chão e as paredes, eu disse que elas simplesmente se
limpariam sozinhas. Acione uma função
descartável muito barata, que é perfeitamente adequada para
causar danos na parede, que basicamente
será ignorada, mas não consideramos o que acontece se ela não
atingir absolutamente nada O que eles farão no momento
é voar para a eternidade, devorando a memória Portanto, há duas coisas
que poderíamos fazer. A primeira é que, se conquistarmos
nossa propriedade principal aqui, podemos realmente dar a qualquer ator com quem trabalhamos uma vida inteira. Então, vou encontrar
isso no painel de detalhes. Podemos pesquisar aqui por toda a vida, e podemos dar a isso
uma expectativa de vida inicial. Se soubermos que isso definitivamente não ficará na tela
por mais de, digamos, 10 segundos, então podemos dar a isso
uma vida útil de dez segundos E depois desse tempo, se
não tocar em nada, se não chamarmos a função de
destruição aqui, ela será
destruída automaticamente. O problema aqui é
que podemos acabar com alguns projéteis que se movem
um pouco mais devagar do que outros, ou vamos usá-los
e talvez reciclá-los mais tarde, que significa que podemos simplesmente
escondê-los e trazê-los de
volta ao jogo E, obviamente, não queremos que
nossos projéteis simplesmente saiam
da tela
aleatoriamente em 10 segundos Então, na verdade, não vou
usar essa abordagem. Outra coisa que você pode
ver é no evento, uma verificação constante para ver se ele
está fora da
câmera ou fora da zona E vamos fazer
algo um pouco semelhante, mas eu queria me concentrar novamente nas boas práticas de programação. Como eu disse, algumas
coisas definitivamente podem e devem estar no Tick, mas isso não é uma das coisas que
vamos fazer é criar uma nova função
chamada out of bounds check E isso vai ser
uma matemática muito, muito simples. Então, vamos clicar com o botão
direito do mouse e
pesquisar a localização do ator G, a localização do projétil
em seu ponto atual Vamos
extrair desse nó e retirar outro vetor. Então, vamos
subtrair um nó aqui e podemos usar algo chamado gerenciador de câmera
do player Portanto, se obtivermos o gerenciador de
câmeras do player, podemos encontrar o premade sempre meio que referenciado e
na memória Unreal de qualquer maneira, então também podemos fazer
uso desses valores que já existem E a partir do
gerenciador de jogadores, o que
atualmente está rastreando a câmera ativa
atual, podemos obter a localização da câmera. Então, essa será a localização
atual da câmera que
estamos vendo. Então, podemos retirar esses dois, e isso fornece um novo
vetor, uma distância para nós. A partir disso, podemos puxar
o pino vetorial aqui e queremos obter
o comprimento do vetor. Então, se procurarmos o comprimento,
podemos obter o comprimento vetorial. Isso converterá isso em um valor de ponto flutuante para nós, essencialmente nos dando uma distância em linha
reta. Portanto, sabemos exatamente quantas
unidades em linha reta nosso projétil atual
está longe de nossa câmera Isso funciona independentemente
da direção, o que é outra coisa
muito útil desse tipo
de abordagem, que
significa que
funcionará para projéteis voando em qualquer
direção, em qualquer ângulo E então o que queremos fazer
é,
a partir do nosso pino de execução , retirarmos daqui e obteremos uma ramificação. Você tem espaço suficiente
para trabalhar com isso. E basicamente
vamos dizer que, se esse comprimento vetorial for
maior ou igual a
um determinado valor, então vamos
destruir esse ator. Então eu digo mais do que ou
igual a para contabilizar, novamente, se
ultrapassar esse valor. Se isso for verdade, vamos
conectar isso aqui, secar um pouco as coisas aqui. E vou dar
isso, acho que um valor de 3.500 unidades funciona Então, isso está aproximadamente fora
das zonas da câmera. Podemos ser um pouco mais científicos
e tentar testar isso mais tarde. Se você achar que as coisas estão
saindo da tela muito cedo, basta
aumentar esse valor
e, se as coisas estiverem demorando
muito, você poderá diminuí-lo. Mas acho que
isso definitivamente funcionará. Não importa
se eles existem por alguns segundos a
mais do que deveriam. O principal é que não
queremos vê-los simplesmente tela e desaparecendo
magicamente E não queremos que
centenas e centenas de projéteis existam
por minutos a fio Esse é mais um problema
que estamos tentando resolver. Se isso for verdade, então
vou partir daqui, vou dizer destruir o
ator só para que
possamos limpar aquele projétil
da memória Tão bonito e simples. Como sempre, não há números mágicos,
então vou descer e promover
isso como variável. Vamos chamar isso de algo
como distância fora dos limites. E, novamente, isso
torna
simples e agradável que sempre possamos
voltar direto para cá. E se estamos tendo problemas em que
precisávamos mudar isso, aumentá-lo ou
diminuí-lo, agora temos um bom lugar fácil de encontrar um lugar
para fazer essa mudança. No momento, não
chamamos essa função, então um
problema muito simples de resolver ou
fácil de ignorar
é que não podemos simplesmente
criar a função Precisamos ligar para isso também. Não queremos ligar para isso
apenas uma vez. Obviamente, não gostaríamos de
fazer isso no início do jogo. E, como mencionei, não
queremos fazer
isso constantemente em eventos Então, em vez disso, o que
vamos fazer é a partir do pino de execução, depois de definir nosso
parâmetro escalar aqui,
vamos, mais uma vez,
fazer uso de temporizadores Isso é muito, muito flexível. Então, procuraremos a mesma função,
que é definida como temporizador
pelo nome da função A função
que queremos obviamente será nossa verificação fora dos limites Então, novamente,
vou renomear isso, na verdade, renomeá-lo,
mas pressione Control C, Control V para colocar isso, e poderíamos configurá-lo para repetir
talvez uma vez a cada segundo Portanto, lembre-se de que, se
fizéssemos isso no Tick, isso seria verificado
potencialmente 120 vezes por segundo com
base na minha taxa de quadros atual. Então, isso é um pouco
exagerado. Não precisamos que seja tão preciso. Fazer isso uma vez a cada
segundo não vai sobrecarregar o desempenho
do jogo, e isso significa que
ainda estamos verificando, em uma iteração ou
intervalo relativamente rápido , os projéteis que não precisam estar Como mencionei,
ter um projétil por mais alguns
segundos não será potencialmente ter centenas de projéteis sendo verificados
120 vezes por segundo;
se eles ainda existissem, seria mais problemático Queremos ter certeza de que
isso seja chamado continuamente, mais de uma vez, então
definiremos isso como loop Então, uma vez a cada segundo,
isso agora será chamado. Temos uma
iteração em loop desse cronômetro, que verificará localização
do projétil
contra a câmera e se
ele está tecnicamente fora de vista Então, podemos ir e testar isso.
Se conectarmos um desses, criaremos talvez
alguns deles
e clicaremos em simular
para que possamos ver
o disparo E você pode ver que
um deles realmente atingiu o avião inimigo, que foi
destruído ao atingir o avião Mas o outro
dispara e, depois de estar uma certa distância,
não o vemos mais. Então, se eu pressionar o
avião
a partir daqui, o principal é que não os
vimos simplesmente desaparecerem pela câmera, é
isso que queremos evitar. Mas sabemos pelos
testes anteriores que eles estão sendo eliminados quando testamos
isso no modo de simulação Claro, eles estão
voando e
saindo da visão da câmera Então, essa é uma boa maneira
limpa de fazer isso. Isso não vai
fornecer uma grande sobrecarga. Isso definitivamente não
causaria problemas de desempenho. É um
cálculo relativamente simples e leve aqui. Acho que é muito mais seguro do que usar a vida útil,
porque não sabemos por quanto tempo ou com que velocidade
todos os projéteis se moverão e
por quanto tempo eles podem ficar na tela E isso é barato o suficiente para executar esse cálculo e não
causará problemas de desempenho. E eu queria demonstrar apenas uma
comparação simples de onde
podemos usar o tick e onde
evitamos usar o Tick. Lembre-se de que, quando estivermos
brincando com essas coisas, sempre volte e
exclua os atores que você talvez
não esteja mais usando. Não queremos
mantê-los por perto. Vamos criá-los a partir de alguma funcionalidade
de disparo
um pouco mais tarde Então, mais uma vez, se você ainda
estiver
brincando com essas coisas, sinta-se à vontade para experimentar velocidades
diferentes, cores diferentes,
ver se você deseja afetar alguma das
outras propriedades na instância do material. Veja se você consegue descobrir
como alterar alguns
dos outros valores escalares
ou parâmetros vetoriais Novamente, o principal é que você
só precisa do nome e da grafia exata, e
você ficará perfeitamente bem Você pode alterar os valores conforme achar melhor. Outro desafio
interessante. Não, espero que você esteja se sentindo mais confortável com um
pouco do programa Para adicionar aceleração ao longo do tempo com talvez algum tipo
de interpolação Você pode ver essas abordagens no outro
código que temos. E é uma das coisas
boas que
mencionei sobre a criação
de nosso próprio código. É algo quase impossível de fazer com
o componente de
movimento do projétil Então, se você quisesse que ele passasse de uma velocidade mais lenta e acelerasse com o
tempo ou ao contrário, você poderia começar a
voar muito rápido e depois desacelerar,
perdendo impulso Você também pode
ver coisas como
direcionar projéteis usando técnicas
semelhantes,
intercalando em direção a uma
meta específica ao longo do tempo direcionar projéteis usando técnicas
semelhantes,
intercalando em direção a uma
meta específica ao longo Eu mencionei que eu
recomendaria manter a classe atual como está. Se você estiver fazendo esses testes e tentando alguns
desses experimentos. Eu sempre recomendo
duplicar o que você tem e tentar criar
sua própria versão a partir disso No entanto, é uma ótima
maneira de aprender. Não quero impedir que você experimente coisas novas,
mas, é claro, nos tópicos futuros,
usaremos esses projéteis
exatamente como estão Portanto, eu
também recomendo
ter essa versão para que possamos concluir
o projeto juntos.
21. 20 — Projeto: fogo do inimigo: Para fazer com que as coisas realmente
disparem seus projéteis. Vamos fazer isso de
novo, bem arrumado. Uma função de
disparo na classe base personalizada
pelas crianças, se necessário. mesmo padrão
que usamos antes, então vamos acabar com a mesma funcionalidade
do nosso projeto de exemplo, que estamos trabalhando para recriar um pouco, mas estamos adotando uma abordagem um pouco
diferente Então, primeiro, apenas um lembrete, se você tivesse algum
dos projéteis espalhados, eu
recomendaria excluí-los Antes de começarmos,
geraremos tudo
isso dinamicamente em tempo de execução, quando necessário Vamos começar
em nossa classe de avião base. Então, se formos para a base do
plano central e
fizermos nossa
implementação inicial aqui, criaremos uma função
aqui chamada fire. Faremos
algo muito parecido com o que fizemos com nossa classe geradora inimiga Vamos retirar o pino
de execução e procurar o ator de
desova da classe Podemos, mais uma vez, partir daqui e promover
isso para uma variável. E caso queiramos
mudar isso mais tarde no momento, acho que teremos apenas
uma única classe de projéteis Mas caso queiramos projéteis
diferentes, vamos promovê-los para
torná-los reutilizáveis Vamos renomear esta
para classe de projéteis. Deixe isso como o tipo de
ator padrão, clique em compilar e pronto. Agora, quando clicamos em compilar, recebemos esse erro
dizendo que precisamos fornecer algumas informações
extras Precisamos do TransponPin. Podemos fazer duas coisas. Podemos
dividir o pino da estrutura. E se você quiser deixar
isso completamente vazio, podemos clicar em compilar e isso
fará com que o erro desapareça. Agora, vou
pressionar Control in Dead. Há outra coisa
que podemos fazer aqui. Para o local do spawn,
precisamos saber exatamente onde queremos nossos projéteis
venham a existir E uma maneira de fazer
isso e tornar isso um pouco visual é
adicionar um novo componente. Eu vou
entrar no mirante. Vou adicionar
um novo componente e selecionar o
componente de cena aqui mesmo. Uma coisa que eu deveria ter
feito era que isso já estivesse selecionando a malha, mas
está tudo bem. Quero que esses componentes da cena sempre acompanhem o que está
acontecendo com a malha. Então, vou
pegar isso e
soltar isso novamente, focando na hierarquia, para que o
novo componente da cena seja filho da malha estática Para deixar isso claro, se
você realmente quisesse, poderíamos renomear
isso, e eu chamarei esse projeto de
nosso local de desova Então, quando analisamos nossa
hierarquia, temos uma ideia geral sobre
o que esses diferentes componentes são responsáveis Agora, não precisamos que
isso seja visual, mas o que podemos fazer com isso é que agora
podemos movê-lo e ter controle direto de onde queremos que o
projétil apareça Poderíamos ter isso um pouco
na frente do avião. Bem, como
mencionei, podemos querer que isso fique um pouco
dentro do avião, para que não
pareça que está
surgindo magicamente do surgindo magicamente Quando você estiver satisfeito
com a posição do local de
geração do projétil, novamente, se clicarmos em compilar,
obteremos esse resultado ruim do plano no visor, mas
tudo bem Só queremos voltar
à nossa função de bombeiros. Vamos controlar o arrasto local de geração
do projétil até o solo Vou partir daqui
e vou procurar algo chamado get
world transform. Então, queremos essa opção
aqui com a função verde? A transformação Get World fornecerá
a transformação
desse componente específico no mundo em relação à rotação e a
tudo o que aconteceu. Assim, podemos garantir que o projétil
esteja voltado para frente Vamos conectar isso,
clicar em Compilar e podemos ver que
os problemas desapareceram. Eu só queria
mostrar outra coisa, e acho que pode realmente
valer a pena mudar
isso aqui de um ator para especificamente
a classe baseada em projéteis Se voltarmos para
nossa classe de projéteis aqui, clicaremos duas vezes para
abrir a classe base e garantir
que temos
duas coisas expostas aqui Então, queremos que a
cor do projétil seja exposta, a força de
emissão do projétil e talvez a velocidade de
movimento do projétil também possam
ser Garantir que esses
três sejam públicos. Você pode voltar e voltar, estou tentando estabelecer as
bases para você. Você pode voltar e, depois ver o que
estamos prestes a fazer, fazer as outras alterações
que desejar. São totalmente opcionais, mas
acho que esses três
serão bons para testes. E se clicarmos em compilar e salvar, voltaremos para
nossa classe base de avião e para a função de disparo Agora, por padrão, como isso
é definido como um ator genérico, não
há dados expostos. Agora, o que podemos fazer
usando uma digitação específica é pesquisar nosso
projétil de sublinhado BP Queremos usar a opção base, precisamos
soltá-la e selecionar o tipo de referência da classe,
não o tipo de objeto. Isso apenas nos dirá que algumas coisas
precisarão mudar. Talvez tenhamos algumas referências ou
links essencialmente
quebrados para diferentes tipos de classes, e isso é perfeitamente normal. Digamos que mude essa variável. Vamos deixar isso funcionar. Realmente não vai
quebrar nada porque, de qualquer forma, não estamos usando nada específico neste momento. Só tínhamos um ator genérico.
Então, podemos fechar isso. E o que eu queria mostrar é
que, se clicarmos com o botão direito
do mouse no ator de spawn e escolhermos a opção refresh node aqui ou nos certificarmos de
clicar em compilar primeiro, o que deveríamos ver são
as propriedades que
acabamos de expor,
e acabei de perceber
qual é o problema Há uma outra etapa que
é muito fácil de ignorar. E vamos voltar
para a base do projétil. Além de torná-los públicos
, precisamos de outra
caixa de seleção. Então, apenas algumas das coisas que você
precisa saber sobre o Unreal, e você aprenderá isso
à medida que avança Portanto, para a velocidade de movimento e as outras duas que
expusemos, também queremos escolher
essa opção aqui, expor no spawn
no painel de detalhes Então, precisamos fazer isso
para cada um deles, então pegue sua variável e marque a exposição em span Eu sugeriria que ele apenas
expusesse essa propriedade sempre que
geramos essa classe em Também é muito importante que
tenhamos certeza compilar e salvar na
classe projétil Caso contrário, se voltarmos para nossa base aérea,
não veremos isso. E você pode ver agora que a
principal razão pela qual
queríamos isso é
especificando que usaremos especificamente base de
projéteis de sublinhado
da BP vez Agora temos essas
propriedades expostas, o que é muito útil. Isso nos dá o
poder de mudar
a cor com base na classe em que vamos
gerar isso, bem
como na velocidade de movimento,
na força de emissão
e coisas assim,
dependendo de como você quiser bem
como na velocidade de movimento, na força de emissão
e coisas assim, dependendo de como você Com suas classes de projéteis. Agora, tudo isso é feito
uma vez na classe base. Queremos que isso seja
facilmente reutilizável sem precisar
mergulhar Então, é claro, não vamos deixar esses números mágicos. Em vez disso, vamos
promover cada um
deles para uma variável. Promoveremos o
primeiro, e chamaremos isso de velocidade de
movimento do projétil E então, é claro,
faremos a mesma coisa. Vamos promover a cor do
projétil e a força de
emissão do projétil em
suas próprias propriedades . E
está tudo pronto. Isso significa que agora podemos ter essa única função reutilizável avião do jogador e
no inimigo do jogador,
e tudo o que precisamos ajustar por classe é a rapidez com que queremos que os
projéteis se movam Porque eu lembro que
no projeto de exemplo, o inimigo é disparado
mais devagar que o jogador, e podemos mudar
a cor
dependendo de quem está gerando Isso significa que não precisamos de
muitos tipos
diferentes de projéteis específicos Podemos simplesmente pegar nossa base de
projéteis e fazer algumas mudanças rudimentares muito
simples por avião A única
coisa realmente importante antes de sairmos daqui lembrar que
a funcionalidade da colisão
que estamos fazendo é a seguinte:
se estamos sobrepondo, no momento, nosso próprio dono, não
queremos causar danos a nenhum Precisamos ter certeza de que o
que está gerando a classe, o que estamos fazendo agora na base
do avião, está realmente transmitindo as informações
de quem é o proprietário Então, outra coisa
que podemos colocar aqui no ator de desova na base do avião é
o proprietário aqui Então, de forma simples e simples,
podemos usar esse pino e procurar a referência G
para vender. Ou você pode simplesmente digitar
a palavra célula e verá obter
referência a si mesmo aqui. Então, agora isso é
apenas garantir que qualquer avião que gere
esse projétil quando
essa função for chamada,
ele se marque esse projétil quando
essa função for chamada, como o
dono do projétil,
garantindo que não cause danos a si mesmo garantindo que não cause Tão bonito e limpo,
podemos bater e empilhar, economizar, e
aquele está pronto para ser usado Então, agora estamos em um bom
ponto em que podemos adicionar a
versão mais simplista do disparo, que
será nossa classe inimiga Antes de fazer isso, acho que
há mais uma variável que ambas as classes
poderão usar,
que é a
taxa de tiro, com que frequência o avião será
capaz de disparar. Então, vamos criar uma nova
variável aqui embaixo. O primeiro será do tipo de voo, então pressione Control ID em
qualquer um dos outros voos, e eu chamarei isso de taxa de
tiro.
Ele compila. Acho que só para
garantir que não esqueçamos de definir isso mais tarde, vou reduzir
isso para zero e garantir
que modifiquemos isso por plano. E então, a outra coisa
que eu acho que será bastante útil em nossas duas classes mais tarde será um vetor dois D para a taxa de tiro mínima e
máxima. Então, temos alguma randomização. Então, vou criar uma nova
variável. Queremos que isso seja um vetor dois D novamente. Mas, por enquanto, chamaremos
isso de taxa máxima de tiro de um mínimo. Queremos aquele vetor dois
D que tínhamos anteriormente
e, novamente, podemos
deixá-los em zero por enquanto. Voltaremos e os
modificaremos mais tarde. E esse é um daqueles
casos em que obtemos
muitas variáveis semelhantes
para um sistema. Então, talvez queiramos
colocá-los em uma categoria, especificamente para projéteis ou combates ou o que
você quiser que seja Também poderíamos ter uma categoria de saúde,
algo assim. Como mencionei, não vou
continuar fazendo isso na tela, pois é apenas um
trabalho árduo em segundo plano, mas definitivamente poderia
ajudar, pois obtemos muito mais variáveis à medida que
exibimos as classes individualmente. Mas isso é bom. Isso é bom para um ponto de trabalho básico, então agora podemos entrar em
nossa classe inimiga, então vamos para o núcleo. Jogue como inimigo e queremos
criar uma sequência
no início do jogo. A razão para isso
é que agora estamos tendo algum tipo de lógica confusa Estamos fazendo algumas coisas
diferentes na inicialização de nossa classe,
o que é perfeitamente normal, mas
podemos simplesmente manter as coisas organizadas novamente Então, um truque rápido aqui
é que podemos retirar
o pino de execução após a chamada principal e entre
o que já estamos fazendo, e chamaremos um nó de
sequência aqui. E isso conectará
automaticamente a lógica que temos
sem quebrar nenhuma delas , então zero é essencialmente nossa inicialização para randomização
genérica Então, poderíamos fazer um comentário
dizendo: randomize os valores aqui. Então, a próxima coisa que
vamos querer fazer é configurar nossos detalhes de disparo Então, na verdade, isso
ainda será baseado em algum nível
de randomização Então, vou
clicar com o botão direito do mouse e obter
a propriedade de taxa de disparo. Então, queremos definir
a taxa de tiro aqui, e ela será novamente definida em uma flutuação aleatória no alcance Vamos conectar isso, e
esse flutuador aleatório, é claro, será
o mínimo que
acabamos Então, obteremos a taxa de tiro máxima
mínima, dividiremos o
pino da estrutura como fizemos antes e os conectaremos aqui. Então, mínimo, máximo
para o X e o Y. Então, outra boa
randomização simples para que todos os inimigos não atirem exatamente
na mesma velocidade
e, caso contrário, pareça muito repetitivo e Se clicarmos em compilar, também queremos
ter certeza de que, para
a classe inimiga, definimos uma taxa de tiro Minimax, que acho que talvez esteja
entre 0,4 e 0,8 Novamente, você pode ajustar todos
esses valores conforme desejar
e, em seguida, a
taxa de tiro será definida especificamente entre esse intervalo Então, a partir da segunda saída e agora que fizemos nossa
randomização, podemos realmente começar a configurar a funcionalidade de
disparo
a ser chamada Então, vamos
usar o cronômetro definido pelo nome da função novamente,
a partir daqui Vamos usar o
cronômetro definido pelo nome da função. Claro, vamos
chamar a função de fogo. Isso criamos
em nossa classe base, e o tempo será nossa taxa de tiro. Então,
obteremos a taxa de tiro que
acabamos de randomizar e garantiremos que ela
esteja configurada para um loop Portanto, isso continuará sendo chamado enquanto o
inimigo estiver em jogo. A randomização garante que cada inimigo atire em sua
própria taxa aleatória Alguns serão um pouco
mais agressivos e outros mais descontraídos Outra coisa para os inimigos é que, ao
saírem da tela, se o jogador errar, como acontece com os projéteis, eles também devem estar se
limpando Então, vamos entrar
na classe de projéteis
e, na verdade, vou usar
a lógica exata de verificação
fora dos limites aqui Podemos copiar tudo isso, pressionar control NC, voltar
para a classe inimiga Criaremos uma nova
função. Novamente, vamos chamar isso
de fora da verificação dos limites E nós apenas colamos isso
no gráfico aqui. Então, um pouco de duplicação. E, novamente, é aqui que você pode começar a considerar coisas como o uso de componentes seria algo
valioso aqui. Você pode ver que, ao se
aprofundar na programação,
o conceito geralmente chamado de herança
versus composição, fazendo uso de
componentes como esse Um pouco fora do escopo desse sistema realmente introdutório Então, usaremos
um pequeno atalho para algumas coisas , mas essa ainda não é uma
abordagem terrível para fazer isso, apenas uma pequena duplicação Mas a
variável de verificação fora de banda aqui que
copiamos da outra classe obviamente não existe aqui, então vamos clicar com o botão
direito do mouse e criar uma variável E neste,
acabamos de clicar em Compilar. Vamos verificar a localização
do inimigo pela câmera. Para a distância fora dos limites, podemos usar um valor similar Acho que 3.500 estavam
funcionando muito bem. Só queremos ter
certeza de que estamos de
olho nos inimigos que
saem da área de jogo
e, se percebermos que eles estão simplesmente
desaparecendo, talvez
queiramos ajustar
isso de alguma forma Agora, com isso
pronto, queremos
voltar ao nosso gráfico de eventos. Talvez queiramos começar a arrumar um pouco
as coisas e apenas movê-las
para nos dar espaço O principal aqui é que poderíamos
configurar outra hora aqui, então essa pode ser nossa lógica para configurar as
funções recorrentes Então, criaremos outro TO pelo nome da
função para este. Essa será nossa verificação
fora dos limites, e talvez queiramos fazer
isso uma vez a cada segundo Então, vamos definir um horário aqui
, mas uma vez a cada segundo. Vamos promover isso para
variável. E vou configurar este para ser chamado fora
da duração da verificação de limites Como antes, clicaremos em Compilar. Queremos ter certeza de atribuir a isso um valor, de
modo que seja 1 segundo, e definiremos isso como
loop, para que continue continuamente até que
seja removido do Como eu fiz
no passado, também. Acho que vou
escrever clique aqui e encontre a função de disparo. Então, vamos apenas
chamar FireFunction. Na verdade, não
vamos usá-lo. É só para que, novamente, se
quisermos verificar o que está acontecendo dentro
dessa função, podemos clicar duas vezes aqui. Vou pegar o cheque fora dos
limites, obter o nome e garantir que
preenchamos isso aqui em
nosso tempo e, em seguida,
arraste-o pelo mesmo motivo novamente Caso eu queira
ver o que está acontecendo, posso clicar duas vezes
e ver o código exatamente. Como mencionei, é apenas
uma preferência pessoal, mas algo que sempre
costumo fazer em meu próprio código. Uma última coisa que acho que
esquecemos de fazer é porque trocamos um pouco as classes de projéteis Se voltarmos para a classe base
em que
implementamos a função de fogo, se pegarmos nossa classe de
projéteis aqui, podemos ver que a
classe está Então, se tentássemos isso agora, não
conseguiríamos que nenhum
inimigo realmente disparasse nada
porque eles não o
tipo específico de classe para atirar Então, no momento, só
temos uma, que
é a classe base. Mas se fizéssemos algumas aulas para
crianças a partir disso, também
poderíamos usar essas versões
exclusivas. Então, enviamos isso para ser a base padrão de projéteis
porque, no momento, é a única coisa com a qual
temos que trabalhar Clique em compilar e salvar.
E então, no inimigo, o que você verá é que isso se propagará automaticamente. Portanto, também temos a
classe de projéteis definida aqui. Clique em compilar e salvar, e
podemos aninhar o inimigo atirando. Então, nada muito sofisticado,
mas eles são de fato. Atirando e podemos
ver que obtemos isso em taxas diferentes, velocidades
diferentes Portanto, temos uma jogabilidade um pouco
única
dos diferentes inimigos. Devemos também observar que após um certo número de golpes, o jogador deve ser
retirado do jogo, para que o dano
funcione automaticamente. Portanto, temos tudo funcionando
conforme o esperado, pelo
menos para a
classe inimiga, o que é ótimo. A última coisa
que notei é que provavelmente será um pouco
rápido, e tudo bem. É por isso que definimos que todos esses valores sejam expostos para
que sejam fáceis de ajustar e
alterar com base nos testes de jogo, feedback e no campo geral do jogo
que você pode estar buscando Então, acho que no inimigo,
vamos
diminuir um
pouco a velocidade de seus projéteis , porque haverá muitos deles. O jogador provavelmente
quer atirar mais rápido e os inimigos podem ficar um
pouco mais relaxados. Então, vamos definir isso para
algo como 1.500. E se acharmos que isso é muito lento. Então, estou apenas selecionando
aqui na classe inimiga,
pegando a velocidade de
movimento do projétil e reduzindo-a para 1.500 Também podemos mudar a cor. Então, meus inimigos são verdes.
Vou pegar uma cor que esteja um pouco mais próxima
do estilo inimigo aqui. Você deve ser capaz de
usar o seletor de cores que
possamos entrar na cor,
obter o seletor de cores e clicar na parte
do plano que deseja combinar com
a cor Para mim, isso não está funcionando. Isso é selecionar
a correspondência estática. Então, vou
pegar uma cor que é mais ou menos semelhante ao corpo
do avião. Isso seria perfeitamente
bom, eu acho. Então, novamente, se
clicarmos em compilar, temos projéteis se movendo
em velocidades diferentes
e, na verdade, eles
representam a cor da nave, que os
está disparando Você também pode alterar coisas como a força emissiva
se não quiser que elas brilhem ou se quiser que
elas brilhem mais ou menos Mas é isso. Então, esses são
os inimigos configurados e prontos. Apenas uma pequena tarefa paralela para você pause o conteúdo novamente
entre os tópicos e talvez comece a analisar diferentes variáveis
que você acha que podem funcionar para a taxa de tiro mínima
e máxima Talvez você não esteja sentindo diferença
suficiente entre os diferentes
inimigos à medida que eles aparecem Talvez mude a cor, os diferentes tipos
de velocidade de movimento, o dano causado,
exponha outras variáveis, brinque com
todos os valores aos quais você agora sabe que
tem acesso A seguir, daremos uma olhada na funcionalidade de
disparo do jogador. Vai ser um
pouco diferente, um pouco mais prático, mas você pode ver que
já temos uma base muito boa sobre a qual construir.
22. 21 — ProjectileFire Player: Agora pode ir
direto para fazer que o jogador atire de forma
semelhante ao inimigo Então, vamos reutilizar
parte dessa lógica básica, propriedades expostas
do projétil, e ter um controle um pouco
mais refinado sobre se e quando o
jogador deve atirar Então, se entrarmos e abrirmos o player de avião de sublinhado da
BP, temos duas
opções diferentes Agora, uma é que muitas
pessoas podem simplesmente colocar a funcionalidade principal fora das funções em seu gráfico de eventos
principal. Outra coisa que eu
queria apresentar, porém, é que podemos criar nossos
próprios gráficos personalizados Portanto, o gráfico de eventos padrão vem com coisas
como o início
do jogo, os eventos, aquelas
coisas incorporadas ao mecanismo por
padrão. Perfeitamente bem. Uma coisa que eu gosto muito de
fazer é pressionar esse botão de adição aqui e
criar um gráfico totalmente novo. Vou dar o nome
dessa nova entrada gráfica. E será aqui
que colocaremos toda a nossa lógica especificamente com base no recebimento
de informações para o jogador. Então, novamente, começamos a
adicionar coisas mais tarde, como um botão de reinicialização ou um botão de menu ou diferentes
tipos de power-ups e outras coisas Todas essas entradas
podiam ser rastreadas aqui em um
local agradável e conveniente Para registrar a
entrada de incêndio, finalmente
usaremos um evento de entrada. Então, anteriormente, usávamos
apenas as variáveis que são
armazenadas em coisas como o sublinhado IA em nosso movimento de alça que
vimos aqui Portanto, este é nosso exemplo de usar apenas o
valor flutuante retornado Dentro do gráfico de entrada,
clicaremos com o botão direito do mouse e procuraremos
por IA underscore Fire E vemos que temos
a opção aqui, na verdade, queremos fazer uso
desse evento que é retornado. Portanto, sempre que o
botão de disparo é pressionado, podemos fazer com
que algo
aconteça com o resultado acionado
da entrada recebida. Agora, a primeira coisa que sempre
queremos
considerar é que queremos um feedback
imediato, algo que é mais
do lado do design de jogo e da teoria,
é que, quando o jogador
pressiona algo, ele tem a expectativa de receber um feedback
imediato Não há atraso entre eles pressionarem algo
e algo acontecer Então, por esse motivo,
assim que a entrada for recebida, queremos ter certeza de que
algo comece a acontecer. Portanto, temos vários eventos
diferentes
que são acionados aqui e queremos usar o Started
antes de tudo. Portanto, queremos ter certeza de
que a função de disparo seja chamada imediatamente no Início. Vamos
chamar aqui a
função de fogo da nossa turma principal. Podemos ver que essa é
a classe base. Iniciado é chamado
imediatamente assim que o pressionamento do botão for reconhecido e, em seguida, concluído,
será
acionado assim que o
botão for solto. Portanto, podemos usar esses diferentes
estágios
do pressionamento do botão, mas o
importante por enquanto é que fogo seja acionado imediatamente. Depois que a primeira
função de disparo for chamada, retiraremos o pino de execução e
criaremos outro
cronômetro definido pelo nome da função A função, claro,
será fogo. Principalmente por causa do hábito aqui. Vou apenas duplicar a função de
disparo que
já temos e, novamente, vou colocá-la
abaixo do cronômetro porque sabemos que é a
que estamos usando aqui A quantidade de tempo
entre isso, vamos
sair daqui e eu vou
encontrar nossa taxa de tiro. Então, vamos obter o valor
da taxa de tiro. E acho que para o
jogador, embora eu tenha dito, talvez
queiramos considerar
a randomização, essa é outra
daquelas coisas agora, quando se pensa em coisas
mais do que um princípio de design Provavelmente queremos
definir isso, em
vez de definir um
mínimo e um máximo, o jogador
terá a expectativa de que toda vez que atirar e toda
vez que jogar, sua taxa de tiro
seja a mesma A menos que você esteja criando
algo como um ladino,
dizendo especificamente ao jogador que, com base em seu personagem ou em estatísticas aleatórias, a taxa de tiro pode ser Nesse tipo de jogo,
eles esperam que sempre
pareça o mesmo para que possam se
acostumar com a mecânica e
aprender a Então, se clicarmos em compilar,
pegaremos a taxa de disparo e
definiremos isso para 0,2 Vamos nos certificar de
configurar isso para ser repetido. Então, basicamente, o que estamos
dizendo é que pressionaremos fogo
e, quando você
segurar o botão, chamaremos
essa função para
que , quando estiver segurando,
continue atirando Então, podemos voltar
aqui e
agora podemos fazer uso dessa função
completa. Então, como mencionei,
isso é chamado quando você solta o botão
que está segurando. Então, depois de concluído,
podemos realmente usar outra parte do tempo de funcionalidade
incorporado, e essa é uma maneira muito boa de manter seu código
novamente limpo e organizado Você pode ter visto em outros
exemplos isso associado ao evento
com alguns atrasos, que pode ser muito confuso
se você pensar em executar um
evento e um atraso juntos,
combinando essencialmente a lógica, que serve para ser executada
constantemente em um determinado intervalo, e também tentar atrasá-la
enquanto
a enquanto Então, vamos evitar códigos
desleixados como esse. Em vez disso
, vamos encontrar
uma função chamada clear
Tir pelo nome da função. Então, vamos usar essa função aqui, e isso é muito
bom e simples. Vamos pegar
nosso nome de fogo aqui, então vamos pegar o texto aqui e depois
colá-lo aqui. Portanto, agora temos controle
total sobre quando isso começou
e quando termina. Então, na primeira vez que
pressionarmos o botão de disparo, chamaremos a função de
disparo. Em seguida, também garantiremos que
continuemos lembrando isso enquanto estivermos
pressionando o botão Mas se
quisermos que isso pare, assim que reconhecermos que o
botão foi liberado, vamos limpar o nome dessa função, ou
seja,
essa função de cronômetro Então, ele vai encontrar isso porque eles compartilham
o mesmo nome. Isso cancelará
o loop aqui, e isso significa que
não vamos mais atirar Portanto, não temos fios
em todos os lugares, coisas que tentam
se cancelar no evento funcionam. É apenas um único evento de incêndio, e estamos adicionando apenas uma
pilha a cada 0,2 segundos. Chame uma função muito simples. Então, novamente, sobrecarga muito baixa, muito bom para
desempenho, muito limpo ler e muito
mais fácil de gerenciar E, na verdade, para o jogador, restam apenas
algumas coisas aqui. Portanto, a funcionalidade de disparo
é relativamente simples. Só queremos
entrar nos detalhes da aula aqui e fazer algumas mudanças
semelhantes às que fizemos antes. Então, a velocidade de
movimento do projétil, eu acho, 2.500 para o jogador é boa Deixe que a emissiva
esteja perfeitamente bem. E vamos apenas
mudar a cor. Meus jogadores têm
uma cor meio azulada, então vamos embora.
Com isso aqui. Talvez tente combinar
isso um pouco mais. Como mencionei, em seu sistema, talvez
você consiga usar o seletor de cores Mas para mim, isso é
apenas selecionar preto. Então, vou definir
isso de uma forma mais manual. Podemos então clicar em compilar, salvar
e, em seguida, podemos entrar
e testar isso Aí está. Assim, o jogador
tem feedback contínuo ao
pressionar o botão. Isso ocorre continuamente
até soltarmos o botão de
disparo Então, como eu mencionei,
muito bom e limpo. Se você nunca viu isso
antes, não vou
encontrar tutoriais
específicos para destacá-los,
mas dê uma olhada no YouTube
antes de algo
como o Unreal Engine, mas dê uma olhada no YouTube antes de algo
como o Unreal Engine funcionalidade de fogo de
projeto
ou a lógica do tiroteio, algo genérico como esse
e veja Fique atento especificamente a
eles, que o
levarão ao evento. Reduza alguns atrasos
com base na
taxa de tiro e veja
como eles usarão
coisas como portões para
cancelar a chamada da função de
disparo quando
um botão for
pressionado ou solto taxa de tiro e veja
como eles usarão coisas como portões para
cancelar a chamada da função de disparo quando um botão for
pressionado ou E então compare isso com o que
acabamos de fazer aqui com duas chamadas muito simples para iniciar
a função e finalizá-la
ao longo do tempo Novamente, como mencionei, com exemplos épicos
e coisas assim,
isso nunca significa chamar a atenção de
outras pessoas ou projetos. Explicitamente. Definitivamente, o Mcde
nem sempre é o melhor, mas é só para fazer
você pensar e realmente criticar
o que está vendo enquanto aprende, porque
uma das piores coisas que você pode fazer é seguir tudo cegamente e presumir que é sempre a melhor ou
a Sempre haverá maneiras
diferentes de
abordar um problema, e eu só quero
que você
pense se o que você está
fazendo em seus projetos ou o que você está vendo on-line é uma forma que você
deseja implementar em seus próprios projetos para torná-los gerenciáveis e
fáceis de trabalhar É basicamente
isso para projéteis. Novamente,
certifique-se de
verificar se tudo
tem os valores precisos preenchidos se quiser
as etapas extras que você poderia seguir para
melhorar seu projeto. Vou deixar isso em paridade com o projeto de exemplo, mas temos problemas
que podem não ser facilmente perceptíveis, mas
eles definitivamente existem Por exemplo, podemos,
na verdade, clicar no botão de
disparo de spam mais rápido do que a taxa de disparo. é muito difícil de
fazer porque defini De qualquer forma, é muito difícil de
fazer porque defini
a taxa de tiro relativamente
rápida, mas você pode ver que
estou clicando aqui mais rápido do que se eu simplesmente
aguentasse. Então, talvez considere como você
pode consertar isso sozinho. Eu não vou
passar por esse processo. Seria essencialmente o caso de rastrear um valor em talvez
um cronômetro
separado quando você pressiona o botão
pela primeira vez Na próxima vez que você
pressionar o botão, se for menor do que
a taxa de disparo definida
, você simplesmente cancelará a
chamada da função de disparo. Nesse caso, não é um projeto
tão complexo que eu realmente ache que
faça uma grande diferença. E, como mencionei, essa
mesma funcionalidade está no projeto de exemplo com
o qual estamos tentando atingir
a paridade de qualquer maneira Mas é apenas um bom tipo de prática mental e veja se você consegue pensar em como
incorporar uma lógica semelhante, mas impedindo o jogador
de clicar e atirar mais rápido do que
a taxa de tiro especificada Nossos principais próximos passos, porém, são
que os navios estão armados. O jogador e os
inimigos estão atirando, ambos usando cores e taxas de tiro
diferentes Você também pode ajustar esses
valores novamente. Se você achar que o
jogo é muito difícil ou muito fácil, mude coisas como o dano, que é aplicado com base na origem dos projéteis
disparados,
nas taxas de tiro e
coisas assim Em seguida,
voltaremos a usar nosso gerador genérico
de atores. E vou começar a adicionar alguns planos
de fundo rolantes para fazer com que as coisas pareçam um pouco mais interessantes
23. 22 - RolagemFundos Fundo: É hora de levar esse
projeto um pouco mais longe e realmente fazer com
que pareça um jogo. Vamos adicionar um pouco de água,
algumas ilhas rolantes, e faremos isso
reutilizando nosso sistema Spanus, é por isso
que o construímos
para ter uma configuração tão Podemos encerrar qualquer uma
das aulas que temos
no momento. Clique com o botão direito na guia principal e selecione fechar outras guias, e isso eliminará
tudo o que você não está usando no
momento, e então
podemos simplesmente fechar o player De volta à inicialização da visualização principal,
queremos usar o
botão Adicionar aqui e
adicionaremos um plano simples. Então, se formos para as formas e pudermos encontrar um plano, queremos apenas que
seja uma superfície plana. Vamos
redefinir a localização, então definiremos isso como zero clicando no
botão desfazer aqui Pressione o botão de bloqueio para garantir que isso seja
dimensionado uniformemente
e, em seguida, definiremos o valor para algo como 80 para garantir que cobriremos toda
a zona de jogo, ou
seja, tudo o que podemos ver Também podemos nos
livrar do chão. Anteriormente,
usávamos isso apenas para contextualizar, para que possamos ver exatamente para onde e
quando estamos nos movendo. Estamos usando essa grade
essencialmente para detectar movimento. Não precisaremos mais disso,
então podemos nos livrar
da localização real
do próprio avião. Queremos que isso seja
menos 4.000 no z. E, novamente, isso se baseia apenas em como eu tenho minha câmera configurada, avião e
na localização do inimigo Você pode achar que seu nível tem
uma configuração um pouco diferente, mas se estamos partindo de um projeto
mais ou menos semelhante por enquanto, você pode
ajustá-lo mais tarde Estar tão baixo mantém as sombras um pouco mais
sutis e nos dá espaço para as
ilhas flutuantes, porque alguns
dos objetos que forneci
são intencionalmente muito grandes Da pasta, vamos
para nossa pasta de ativos. Vamos encontrar os materiais,
e podemos encontrar a água do sublinhado MI e simplesmente arrastá-la
para o avião Então, isso
nos dará um material aquático animado, simples e
básico. Como mencionei,
alguns detalhes e propriedades podem
precisar ser alterados aqui, como o tamanho do
avião ou a localização. fazemos um tipo completo de
varredura e refinamento quando chegamos ao final do tópico ,
com base na aparência das
coisas Se você quiser trocar
sua água, novamente, podemos clicar duas vezes no material
aquático MI underscore Arraste isso para a janela aqui. Essa é uma boa maneira
de, mais uma vez, fazer uso da instância
material. Se você achar que a água
fluindo muito rápido ou não
gostou da cor, podemos receber esse feedback ao vivo
mesmo enquanto jogamos para ver
exatamente o que você queria
fazer com coisas como
o desvanecimento da profundidade,
a distância, as diferentes propriedades da
cor e
coisas assim Assim, você tem
controle total sobre a aparência da água. Vou
manter isso como está, mas só para dizer
que esses valores estão aqui se você
quiser ajustá-los. Em seguida, queremos
considerar nossas ilhas. Então, vamos voltar para nossa
pasta Blueprints. Criaremos uma nova
pasta aqui. Vamos nomear essa ilha. Dentro da pasta das ilhas, vamos clicar com o botão
direito do mouse, ir para a classe
Blueprint e
criar um novo ator Só precisamos de algo com presença no mundo novamente, e chamaremos isso de
BP Underscore Island Dentro da classe, configuração
muito padrão agora. Vamos adicionar
uma nova malha estática. Definiremos isso como a raiz de cena
padrão, então substituiremos a raiz de cena
padrão aqui E com a
malha estática selecionada, vamos para
o painel de detalhes. Encontraremos a ilha de
sublinhado SM redonda, então a maior para
começar Podemos pressionar F no ponto de vista, para que possamos ver como seria a
ilha E então nós só queremos ir
até as propriedades da colisão, e vamos ver os detalhes da
colisão Vamos deixar isso no chão e
definir isso para não colidir. Desativaremos a
geração de eventos de sobreposição. Apenas certifique-se de que
isso não tenha física, não
tenha verificações de sobreposição Esse será um objeto descartável muito
barato, que existe apenas para Agora, antes mesmo de começarmos usar nosso gerador para
trazê-los ao mundo, sabemos que isso
vai parecer muito repetitivo, muito chato Vamos obter a mesma malha
estática com o mesmo tamanho, a mesma rotação toda
vez que uma for gerada Vamos começar o jogo
e resolveremos
isso imediatamente Da mesma forma,
vamos nos livrar da chamada
da função Actor start
overlap Queremos começar a jogar
aqui, e podemos fazer algumas coisas simples a partir
do pino de execução aqui. Então, primeiro de tudo,
podemos randomizar um pouco
a escala do
ator Então, chamaremos o conjunto de escala de
ator de três D. E vamos fazer
isso de uma forma um pouco estranha Mas se clicarmos com o botão direito do mouse e pesquisarmos por flutuação aleatória no intervalo, podemos definir esse intervalo mais uma
vez com
base em um vetor dois D. Então,
criaremos uma nova variável Chamaremos isso
de escala Min Max. Largue isso, encontre o
vetor dois D. Ele compila e fornece
alguns valores aqui para talvez algo como 0,8 a 1,2 Coloque-os como
fizemos antes. Então, você pode ver que, novamente, estamos
chegando ao ponto muitos códigos
se tornarão muito familiares. E essa é a
ideia de repetição. Vamos deixar você mais
confortável com o projeto e com o Unreal. Então,
vamos dividir a estrutura em. Vamos conectar isso ao
mínimo e ao máximo. E podemos, na verdade,
pegar nosso valor flutuante aqui e convertê-lo
em um vetor Do jeito que isso funciona,
pode parecer um
pouco estranho como estamos usando
um flutuador ou um vetor Basicamente, vou
garantir que o X, o Y e o z obtenham
qualquer que seja esse resultado. Portanto, se escolher
1,1, significa que X, Y e Z serão
todos definidos como 1,1 Agora, se você quiser
esticar as
coisas , tenha um controle mais refinado. Obviamente, você sabe que pode dividir o pino da estrutura do vetor e talvez fazer uma flutuação
aleatória no X, no Y e no z individualmente O problema que eu acho com isso é
que você realmente não tem um controle
muito refinado sobre como impedir que a malha fique completa. Você pode acabar com algo
como muito estranho e
esmagado ou muito
estranho e esticado. Então, por esse motivo, vou definir
isso para ser uniforme, então é só escalar todos os
eixos juntos. Então, também podemos pegar
nossa malha estática. Vamos colocar isso
no gráfico de eventos e extrair
nossa referência de malha aqui,
então, uma referência ao nosso componente, procuraremos a função de malha estática
definida. Queremos este
aqui, aquele que nos
dará o componente de malha, só para ter certeza de que você viu que queremos ir para a malha
estática dos componentes e definir a
malha estática. Não esse aqui. Na verdade, isso é atualizar
a variável em si, enquanto isso está pegando o
componente que temos e acessando os detalhes por meio de
nosso painel de detalhes aqui. Então, talvez também queiramos randomizar a malha estática que
usamos Então, podemos começar a partir
daqui. Você provavelmente tem uma ideia para onde isso
está indo porque, novamente, já
fizemos isso várias
vezes antes. Só temos duas
opções estáticas diferentes para as ilhas Então, vou
usar um nó de seleção. E como temos apenas
dois, a maneira
mais fácil ver isso é
se tivéssemos mais, talvez
queiramos usar algum número inteiro
aleatório dentro de um intervalo
e, se tivéssemos cinco,
escolheríamos um intervalo de
0 a 4 ou um , cinco, E dependendo do que foi escolhido entre esse intervalo inteiro, ele escolheria um dos quatro
ou cinco modelos diferentes Agora, como só temos dois, vou usar um booleano Vou escolher uma bola
aleatória aqui. Nem precisamos que
isso seja uma variável. E então
temos basicamente 50% de chance de desovar na
ilha grande ou na ilha pequena Então, simples e simples,
não precisamos tornar
isso muito complexo, pelo
menos agora estamos recebendo
alguma randomização Podemos gerar a mesma
ilha grande três vezes seguidas, mas pelo menos a escala
será um pouco diferente
em cada uma Se não, então podemos
estar aleatoriamente
entre a ilha grande e
a pequena E, novamente, eles ainda
terão uma boa escala aleatória aplicada. E, finalmente, todos
eles ainda terão
a mesma aparência. Assim, podemos pegar nossos detalhes de
rotação e também podemos
randomizá-los Então, vamos extrair
da malha estática e eu vou encontrar
a rotação ativa definida. Neste caso, só queremos girar em torno do eixo z
porque, lembre-se, isso vai ser para cima
ou para baixo no mundo Então, vamos clicar com o botão direito do mouse
e dividir a estrutura. Na verdade, vou
ser um pouco preguiçoso e pegar o
flutuador aleatório ao alcance Duplique isso aqui,
vamos apenas
girar de 0 a 360 graus Então, essa é uma daquelas
vezes em que não acho que
haja valor em realmente
promover isso para uma variável. Acho que está bem claro.
Quando olhamos para algo, estamos definindo a rotação dos
atores e vamos de 0 a 360, então, obviamente, estamos permitindo
uma rotação completa Então, na verdade, eu não
recomendaria promover
isso para uma variável. Algumas coisas podem funcionar
como um número mágico, especialmente porque
sabemos que não vamos atualizar ou ajustar isso Não há razão
para eu ver que vamos querer vincular isso
a uma coisa diferente Promover isso
para uma variável significa que não precisamos
voltar ao código. E se quiséssemos mudar
completamente a escala sem
encontrar o código em si, poderíamos definir isso para
0,4 ou 2,5 ou o que quiséssemos
para realmente exagerar a escala.
Eu não vou fazer isso. Vou manter isso como 0,8 e 1,2. Então, apenas essas três
mudanças,
teremos algo que agora
parece muito mais aleatório e um pouco mais exclusivo do que apenas ter
os mesmos dois objetos aparecendo exatamente
na mesma escala e rotação quando são
colocados em jogo Agora podemos passar para
o movimento. É por isso que mantivemos o evento. Novamente, queremos um movimento agradável,
consistente e suave
e, com uma lógica muito
simples, não vai ficar
muito caro de executar. Vamos retirar
o pino de execução e encontrar a diferença mundial do
ator publicitário Queremos esse
aqui? Adicione o deslocamento mundial do ator para todo o
ator da ilha Dê a nós mesmos algum espaço
porque precisamos fazer alguns cálculos
aqui para o deslocamento Criaremos uma nova variável. Vou promover os Delta Seconds novamente só
para ser preguiçoso aqui Transforme isso em variável para
obtermos o tipo correto, e eu chamarei isso
de velocidade de movimento. Clique em Compilar e definimos isso padrão de algo
como 400 unidades de velocidade, mas vamos querer
ter certeza de dar a isso
um valor negativo, ou seja, 400 negativos para garantir que isso esteja
rolando para baixo na Podemos nos livrar da
nossa velocidade de movimento. Só queremos
multiplicar
nossa velocidade de movimento por segundos Delta. E vamos inserir isso
em nosso valor aqui. Acabei de perceber
olhando para isso. Não queremos adicionar
um deslocamento mundial aqui, então vamos excluí-lo Na verdade, queremos
adicionar o deslocamento local. Então, usaremos o deslocamento local do
ator de adição. Divida a estrutura
p para o Delta
e, em seguida, conectaremos isso à nossa localização no Delta X
porque, novamente, estamos apenas movendo isso
no X para frente na tela Não precisamos calcular com nenhuma física ou
algo parecido, tentar criar qualquer
pseudofísica ao longo do tempo Portanto, não estamos usando
a compensação mundial. Podemos usar o deslocamento local. Vou ver onde o
ator está atualmente, e isso apenas adicionará esse
valor à direção X. Na verdade, o motivo
que me veio à mente é que, se voltarmos ao tutorial de
tiro,
acessaremos nossos projéteis
e abriremos uma classe de projéteis Podemos ver o evento aqui. Na verdade, essa é a mesma lógica que estamos usando para
mover nossos projéteis A ilha é essencialmente
um projétil
muito lento e muito grande na
forma como temos nosso código Novamente, isso é na verdade
algo que está usando o mesmo código. Lembre-se de que estamos fazendo um pouco de
duplicação novamente,
e isso pode ser
em um projeto
maior, em você começa a
analisar coisas como composição, onde poderíamos ter um componente de
movimento personalizado,
que, por ser muito
semelhante e tudo o que
realmente precisamos é de uma
direção ou velocidade, podemos ter esses valores
expostos em um componente personalizado e poderíamos distribuí-las aos diferentes atores que precisam delas. Como mencionei, um pouco fora do escopo
do conteúdo que estamos analisando
no momento, mas apenas algo a considerar. Isso não é o fim do mundo, então vamos
manter isso como está. E agora podemos realmente
começar a gerá-los. Então é aqui que a classe simples de ator
genérico, a classe geradora
que criamos se tornará bastante útil Então, se entrarmos em
nosso nível, primeiro, eu só quero
testar rapidamente a aparência das ilhas
, então vou pegar uma
das ilhas e
jogá-la no
hidroavião na parte inferior. Queremos ter uma ideia aproximada
da altura em que
queremos gerar isso Novamente, isso
se resumirá a alguns ajustes. Vou fazer um pouco
disso agora, mas
provavelmente vou refinar isso fora Então eu acho que, na verdade, a primeira vez que eu deixei cair um desses, foi, na verdade, o mesmo que o avião
em si, então -4.000 Então, podemos usar
isso como base. Provavelmente colocaremos o
gerador no mesmo local. Queremos ter
certeza de que isso está mais longe da câmera. Então, isso é algo que agora
podemos testar facilmente. Vamos pegar
nosso ator de câmera. Vamos fixar isso aqui
e podemos começar a realmente ajustar e
garantir que tudo
apareça fora da tela Então, para a ilha grande aqui, além de talvez alguma
contabilização de que possamos até uma escala de 1,2, lembre-se, é nossa escala
aleatória Então, se obtivermos o
maior spondm da ilha, precisamos que ele esteja
pelo menos no ponto de 11.360 no X para ficar completamente fora de
vista quando houver Então, esse é o nosso
ponto essencial em que
queremos que nosso gerador de ilhas
seja colocado Então, na verdade, vou
pegar isso aqui, virar aquele zero no y, então vamos
começar pelo meio. O que vou fazer
é, com o selecionado, voltar para a pasta
do blueprint aqui Eu vou para a pasta de
spawners. Selecione isso. E com isso
selecionado no sorteio de conteúdo, só uma dica útil que você está
prestes a ver aqui Podemos clicar com o botão direito
do mouse nesta ilha. Vamos substituir o Actor e podemos substituí-lo
pelo que
selecionamos atualmente em nossa gaveta
de conteúdo Então, vamos renomear
isso. Este objeto, podemos ver, agora é uma chave de sublinhado da
BP Vou renomear este para Island spawner. Então está
claro o que isso está fazendo. E, de fato, quando se
trata de nomenclatura, isso vai começar a ficar
um pouco descuidado à medida que nós O que eu realmente deveria
ter feito é chamar essa ilha de sublinhado do gerador porque podemos ver que
isso Então, também podemos
renomear este para gerar sublinhado inimigo. Então, agora está um pouco claro que esse é o
nosso gerador inimigo. Este é o nosso criador de ilhas, e eles serão
agrupados Agora, outra coisa que
podemos ver como um problema é que a malha estática tem
o tamanho errado. Acho que talvez
estivesse considerando um ativo
diferente com o qual estava
trabalhando antes. Então, nós só queremos talvez
aumentar isso para algo como 120 em todos os eixos, talvez até 160. Perfeitamente bem. O principal é
cobrir toda a câmera. Então, podemos ver agora, no modo de jogo, que
temos a água
cobrindo tudo. O gerador estará do
lado de fora da câmera para possamos garantir que as
ilhas apareçam fora da Agora, uma coisa muito importante que
eu estava prestes a
perder completamente é que, se voltarmos
para a ilha geradora, quando eu estava ajustando isso,
ajustei a escala Agora, sempre queremos ter
certeza de
mantê-los uniformes, porque em
alguns códigos de desova, você pode considerar a rotação da localização do
ator em escala como o ponto
no qual a geração será escala como o ponto
no qual a Portanto, não queremos
adicionar nenhum padrão, como um deslocamento predefinido,
à escala de nada, então certifique-se de
transformá-lo Então, para fazer isso funcionar
para a desova da ilha, vamos
querer inserir isso e selecionar nossa classe de ilha Então, queremos a ilha de
sublinhados da BP. Vamos permitir um
deslocamento aleatório, então vamos marcar isso. Forneceremos uma distância de
deslocamento de, digamos, 5.000
unidades em cada lado Portanto, lembre-se de que isso é apenas usar a funcionalidade
integrada que já implementamos quando
planejávamos um
pouco com antecedência ao criar nossa classe geradora
genérica E nos intervalos de desova, não
queremos muitas ilhas
bagunçando Então, vamos definir isso
para algo como 5 segundos e a cada 10 segundos. Então, de 5 a 10 segundos,
devemos comprar uma nova ilha. Acabei de recapitular
rapidamente o motivo pelo qual estamos usando
o deslocamento aqui. Lembre-se de que
criamos em
nossa base de geradores, iniciamos nossa ramificação
no spawn iniciamos nossa ramificação ou
uma verificação booleana aqui,
desculpe, para saber se devemos permitir algum deslocamento aleatório Se dissermos não, então simplesmente
geraríamos a ilha exatamente no ponto
do gerador, o que significa que temos apenas uma linha reta
de ilha constante, o
que, novamente, seria
um pouco estranho Se dissermos que sim,
ele escolherá um flutuador aleatório dentro de um
intervalo, o que, no nosso caso, porque definimos isso como 5.000, o
que seria entre
5.000 em Y e menos 5.000 em Y. Então, isso deve nos dar muita variação em seu ponto inicial,
sua escala, sua rotação
e até mesmo na malha Então, podemos testar isso agora, se
pressionarmos , veremos
em algum lugar dentro de 5 segundos. Vou me livrar
da câmera muito rapidamente. No modo de jogo, podemos testar isso e esperar
um pouco, e veremos as
ilhas começarem a aparecer. Estamos procurando
coisas como garantir elas não estejam simplesmente
surgindo, garantir que estejam
indo na direção correta, o que acho que podemos
ter problemas aqui, e também que elas estejam
surgindo corretamente
dentro do deslocamento que fornecemos que
elas não estejam simplesmente
surgindo,
garantir que estejam
indo na direção correta, o
que acho que podemos
ter problemas aqui,
e também que elas estejam
surgindo corretamente
dentro do deslocamento que fornecemos.
Então eu não estou
vendo nada. Há uma ilha muito pequena. Isso pode ter levado
10 segundos, mas temos uma ilha
muito pequena surgindo
do fundo É meio cômico, mas acho que ainda
parece muito bom E devemos ver,
esperançosamente, mais algumas ilhas chegando nos
próximos segundos. Ok, então, na verdade,
temos muitas ilhas. Um problema temos é que, com
sua rotação aleatória, elas estão avançando com base
na direção em que
foram geradas Então, vamos em frente. Acho que talvez eu tenha
estragado um pouco
da lógica quando
criamos a lógica do movimento E eu acho que, na
verdade, está voltando ao que estávamos
vendo anteriormente. Então, na classe da ilha,
acho que era isso aqui, a compensação local versus a
compensação mundial que eu tinha em mente Portanto, seria bom se
pudéssemos manter o código, semelhante ao
projétil, e
provavelmente pudéssemos alterar o código do
projétil Mas acho que o que
estamos fazendo, apenas para manter isso simples e simples, vamos
mudar isso de nosso deslocamento
local, porque lembre-se, quando estamos fazendo uma adição
local ou um deslocamento para a
posição local do ator, isso levará em consideração a rotação atual
que ele tem, porque queremos girar
ou se estamos girando 180 graus para o outro
a direção e, em seguida, o avanço local
mudou, então vamos
nos mover na outra direção. Dizer isso, porém, me
fez perceber que provavelmente
poderíamos fazer algo um pouco mais limpo aqui, focando na hierarquia Então, novamente, isso é
algo em que no pré-desenvolvimento, eu
simplesmente esqueci isso E esse sou eu, pensando
meio que na hora, é por isso
que estou mantendo isso
apenas para mostrar maneiras resolver
problemas diferentes de várias maneiras. Então, o que eu estou tentado a fazer é porque eu quero
manter essa lógica Eu quero fazer o movimento local de
compensação. O que eu acho que faremos em vez disso é adicionar
um novo componente. Vamos criar um componente de cena
vazio e fazer disso
a nova rota. Então, o componente da cena
será a forma como estamos encarando, que sempre será
avançada no mundo. E acho que o que
faremos em vez disso é definir nossa rotação, mas não vamos definir
a rotação de todo
o ator. Vamos deixar o componente
da cena
sempre voltado para frente. E isso também
lhe dará um bom exemplo de maneiras
diferentes de
usar a hierarquia Podemos pegar nossa partida estática
e, em vez disso, vamos
definir a rotação dela. Isso também é algo
que ainda não vimos, então podemos definir a rotação
relativa de nossos componentes em
relação ao componente pai ao
qual eles estão conectados. Mas exatamente a
mesma lógica. Vamos conectar
isso. pegar esse flutuador aleatório
que já temos e
dividir o pino da estrutura
como fizemos antes Em vez disso, vamos apenas conectar isso
ao Z aqui. Isso significa que podemos manter nossa lógica de movimento
exatamente a mesma. E agora não estamos
mudando a rotação de todo
o ator e
a forma como ele está voltado. Isso ainda está voltado para
a mesma direção. Estamos apenas alterando a
rotação do elemento visual. Mais ou menos como
separamos isso dos aviões,
onde o elemento visual
é apenas o corpo do avião, mas a
colisão real e
tudo
está apoiado nessa colideosfera Então, se voltarmos e jogarmos, veremos
que isso está funcionando agora. Outro comando útil do console aqui é que podemos pressionar
a tecla Tilda, digitar slow mo e definir quantas vezes
mais rápido queremos que seja Então, se configurarmos isso
como slow mo five, você pode ver que isso está
se movendo cinco vezes mais rápido, muito mais fácil de
testar e realmente ver se as ilhas
estão surgindo corretamente Então, agora eles estão se movendo
para baixo na tela. Parece que está
funcionando corretamente. Lembramos aquele teste em que não vamos
continuar gerando Se o jogador estiver morto. Comando novamente o console,
podemos digitar um nível de reinicialização, voltar direto para o Slom five e fazer alguns testes
apenas para garantir que
as ilhas, apenas
garantindo que façamos as ilhas, apenas
garantindo vários
testes em qualquer lugar, que as ilhas
estejam funcionando bem Então, eles estão se agrupando
muito, mas quero dizer,
novamente, é aqui que entra a
randomização Talvez isso aconteça,
mas está fornecendo bom
tipo de variação, e acho que
parece muito bom. Talvez queira adicionar um
pouco mais de atraso entre as ilhas
iniciais, mas acho que só para
esse tipo de projeto, isso parece muito
legal e ter alguma sobreposição só
dá uma variedade extra Outra coisa que
você pode querer fazer é entrar na classe base do gerador.
Se entrarmos aqui,
geraremos
imediatamente o Actor Se entrarmos aqui,
geraremos
imediatamente o Actor geraremos
imediatamente Então, devemos ter
um. Se apenas clicarmos em simulações. Devemos
apenas verificar novamente. Sim, recebemos um imediatamente, o
que é perfeitamente normal. Eu estava pensando que talvez já
tivéssemos tido um atraso inicial, mas acho que a única
razão pela qual não vemos por um
tempo
é porque demora um pouco
para aparecer na tela. Então, na verdade, nascemos em
uma ilha imediatamente. Mas estou meio que
me perguntando onde isso
está agora. Então, é só demorar especialmente se gerar uma
pequena, antes de tudo Vai demorar um
pouco mais para vê-lo antes de entrar em cena.
Não é o fim do mundo. Novamente, randomização, você terá alguns resultados
diferentes lá Mesmo com a
ilha maior, acho que está demorando um pouco
para aparecer na tela. Então, talvez o que eu fique
tentado a fazer e, novamente, isso se resuma a
muitas viagens agora brincando Talvez estivéssemos um
pouco preocupados com
a distância desta manhã. Então, vamos trazer isso de
volta um pouco
e, novamente, garantir que toda vez que você pressionar a placa, olho para
garantir que nada apareça, mas queremos que essa ilha talvez
apareça na tela um
pouco mais cedo Então, como mencionei, tentativa e
erro, veja como as coisas correm, fique de olho nos resultados
que você está
obtendo e certifique-se de que o jogo esteja funcionando bem
à medida que
você avança. Então eu acho que isso é muito legal
lá. deveriam começar a ficar um No entanto, é aqui que as coisas
deveriam começar a ficar um
pouco mais
interessantes. Agora você tem controle total sobre o design dos níveis, onde
queria que as coisas surgissem, a velocidade com que queria que elas se
movessem, na verdade, apenas refinando a jogabilidade e a aparência do jogo que você tem Se as coisas estiverem
surgindo, você pode simplesmente mover o gerador
um pouco mais para trás Se você quiser que eles
apareçam mais cedo
, podemos aproximá-los
um pouco mais. Se a água não estiver
cobrindo toda a visão, basta aumentar o
plano como você acabou de ver. E se as ilhas
estiverem muito próximas, basta diminuir a
velocidade de desova e coisas assim E isso é pura iteração,
jogar, observar, ajustar, repetir É raro que você consiga
essa primeira vez perfeita. Você acabou de me ver precisando
ajustar e mudar algumas coisas até mesmo para
esta demonstração aqui, mas deve ser
aí que
entra parte da diversão de criar jogos, porque é aqui que agora
você tem muito mais controle sobre como refinar o resultado final Agora, uma coisa que eu
diria é
que neste momento também valerá a pena ficar olho no esboço, como mencionei Temos algumas coisas, mas nossos volumes de bloqueio
estão perfeitamente corretos. Talvez colocando
coisas em pastas como a iluminação
que veio por padrão. Uma coisa que eu percebi que
não estamos realmente usando é a esfera
do céu ao fundo.
Esse é um objeto antigo. Não está fazendo nada. Podemos nos livrar da esfera
do céu. Você pode ver que nada muda, apenas para garantir que não tenhamos mais objetos no
nível do que precisamos. Todo o resto está bem. Isso está fornecendo a luz e a atmosfera em
segundo plano. Mas fique à vontade para começar a
brincar com elas, mudando a direção da luz direcional,
a força dela para fazer com que
as coisas pareçam mais claras Novamente, comece a ser
criativo e a jogar com as diferentes
propriedades e detalhes para fazer com que o jogo
tenha a aparência que você pretendia. Então, isso é tudo para o nosso
nível. As coisas agora parecem um
pouco mais vivas. Temos ilhas de água, com as quais você pode jogar
paralaxe. Na verdade, está começando a parecer um
pequeno jogo. Em seguida, podemos começar a usar
o passe polido, fazendo com que as coisas pareçam
realmente interessantes e muito mais
atraentes visualmente para o jogador
24. 23 — NiagaraParticles: Ponto em que podemos
começar a melhorar a sensação geral e apelo de alguém que
joga nosso jogo. Vamos começar com uma série
sofisticada de efeitos,
adicionando coisas como
propulsores, explosão e
impacto, tudo usando o motor
Unreal embutido Então, uma rápida visão geral
dos sistemas e emissores que veremos
em nosso projeto Se navegarmos até nosso projeto, acessarmos a
pasta Assets and effects, teremos nossos
sistemas Niagara aqui Mas basta abrir um
desses. Por enquanto, usaremos
o mecanismo de pixels apenas para mostrar com o que
estamos trabalhando. Então, o que estamos dentro no momento
é um sistema
de Niágara Os sistemas geralmente são
compostos por um e, muitas vezes,
mais de um emissor. Podemos ver aqui que os painéis com abas
laranja são nossos emissores que compõem os diferentes pontos
do nosso sistema geral Isso torna o Niagara muito
mais flexível para trabalhar do que o antigo
sistema de partículas em
cascata É muito mais fácil
criar alguns emissores básicos
no novo sistema e, em seguida, podemos começar a
juntá-los para criar sistemas personalizados e
exclusivos De uma
forma muito simplista, você pode pensar nisso
como algo como um sistema de partículas de
chama Você pode ter muitos emissores
que entrariam nisso. Você teria as faíscas
vindo do topo da chama. Você
teria um pouco de fumaça. Você poderia ter o efeito
de distorção e teria o corpo
principal da chama e o próprio fogo Todos esses podem ser emissores
individuais construindo esse grande sistema O importante é
ter em mente que os emissores
devem ser reutilizáveis Não os colocamos diretamente em nossos projetos ou
nos sistemas que usaremos e realmente
usaremos dentro do nosso código
ou do próprio nível Se você quiser começar
a experimentar alguns
dos sistemas que eu
já forneci, você pode ver que
tenho vários aqui. Você pode facilmente
entrar e começar a brincar com as
propriedades dos emissores Se você quiser ver qual
parte é responsável por um determinado efeito
acontecendo aqui
no pote de visualização, podemos
desmarcá-las aqui Podemos ver que isso é
apenas uma fonte de luz, então nada realmente muda. Se ligarmos isso novamente, mas depois desligarmos o outro emissor, podemos ver que ele é claramente
o responsável pelo efeito de
partículas
do corpo do nosso motor Então, se você quiser começar
a tentar brincar com
coisas como a cor, o tamanho disso, talvez
não
saiba exatamente o que está procurando imediatamente, o
que é Mas só de dar uma olhada rápida nas
propriedades fornecidas, podemos ver que
provavelmente poderíamos alterar a cor de nossos valores de
escala aqui Isso está deixando a cor amarela
laranja aqui. Se dermos mais azul,
obteremos
uma cor diferente ao longo da
vida útil da partícula É outra ótima
maneira de se acostumar com alguns dos sistemas
do Unreal, apenas encontrando as coisas que
instintivamente fazem sentido para você e brincando e enfraquecendo os
valores que você pode Você também pode adicionar
coisas diferentes, como velocidade
extra, para fazer essa
viagem ainda mais longe E, como
mencionei antes, uma ótima maneira
de descobrir por que as coisas são responsáveis é adicionar um valor muito
grande a isso, para que
possamos ver que, se
fizermos a velocidade aqui 11.000 em vez de 1.000, podemos ver exatamente pelo
que isso foi responsável, e então podemos refinar
e ajustar até um valor com o qual achamos que
talvez queiramos trabalhar Então, como em alguns
dos outros
sistemas do projeto que
analisamos até agora, o lado mais artístico
das coisas realmente não é o foco do que
estamos
tentando abordar nesses tópicos. Então, eu não vou me aprofundar no Niágara. Quero mostrar
como usá-lo e como podemos
implementá-lo em um projeto. Útil se você tiver coisas como acesso a Asset PACs ou alguns exemplos gratuitos de coisas como
o
projeto
de exemplo de conteúdo fornecido pela Epic A primeira coisa, como
já estamos nessa partícula, podemos usá-la para o propulsor de ambas as
classes de aviões Ambos precisarão disso, tanto o inimigo quanto o jogador. Então, se formos para nossa aula de
blueprint, iremos para CR e encontraremos sublinhado
da BP Então, podemos colocar isso
na classe base novamente, e isso será usado para nossos
dois planos diferentes. Precisamos ter muito cuidado novamente onde
vamos colocar isso. Poderíamos colocá-lo
diretamente na esfera, mas acho que, no momento, caso quiséssemos fazer alguma rotação de deslocamento
específica, coisas assim
na malha estática, vamos colocá-lo aqui Então, vamos pegar a malha estática. Vamos adicionar
um novo componente e queremos
pesquisar o Niágara Podemos ver aqui que temos
apenas uma opção, o componente do partículas
do Niágara E no painel de detalhes,
veremos a lista suspensa que provavelmente
estamos procurando
e com a qual já estamos bastante familiarizados. Podemos soltar isso e
selecionar o mecanismo de pixels. Se navegarmos até o visor, podemos ver que ele está meio que
encaixado no meio do Amopla, então
precisaremos recuar um pouco recuar um E acho que vou
colocar isso mais ou menos perto do círculo de metal que
adicionei no plano aqui. Se clicarmos em Compilar de forma segura, talvez
precisemos testar algumas coisas com isso Então, a primeira é
a rotação diferente que vamos
aplicar
às diferentes classes infantis. Então, se começarmos dentro
do player simples e apenas
verificarmos o ponto de vista aqui, este parece
perfeitamente bom Essa é essencialmente a
mesma configuração da base do avião. Se entrarmos em um inimigo simples,
vá até o visor aqui, para que possamos ver que
o efeito de partícula está bom aqui No entanto, se pressionarmos play, então se entrarmos em nosso
visor e no modo de jogo aqui, podemos ver que está
tudo bem para o jogador, mas as partículas do inimigo estão
um pouco estranhas, porque lembre-se de que,
quando entramos no modo de jogo, estamos invertendo completamente a rotação nosso inimigo com base na
localização
dos E mesmo que esse efeito de
partícula esteja aninhado, se observarmos a configuração no mecanismo
P underscore pixel, podemos ver que a
velocidade está definida uma direção específica Então, o que queremos fazer, e
isso será apenas um ajuste muito simples em um sistema de partículas
existente Para que você possa começar a trabalhar
pelo menos um pouco, precisamos fazer uma cópia
do mecanismo de pixels Então, vamos
voltar aos nossos efeitos. Vamos para
nossos sistemas de Niágara. Temos nosso
motor de pixels aqui. Outra coisa, eles
foram copiados
dos exemplos de conteúdo que
não têm a melhor nomenclatura, então vamos
pegar isso e
renomeá-lo para renomeá-lo Portanto, a convenção de nomenclatura adequada
seria sistema Nagra, motor de
sublinhado de pixels, e chamaremos isso Então, podemos deixar
este exatamente como está. Podemos então pressionar
Control, na verdade, para duplicar isso,
e chamaremos isso de inimigo sublinhado E se clicarmos duas vezes para
abrir a versão inimiga, o que queremos fazer é encontrar nossa velocidade Já vimos que
isso controla a direção em que o efeito da
partícula está indo, e vamos apenas remover
a opção de negação Também podemos fazer algo
enquanto estamos aqui, tornando este talvez um
pouco mais verde para que
possamos arrastar o valor até aqui para dar a ele uma tonalidade um pouco
diferente E se considerarmos isso
além do valor vermelho, podemos ver que é um
pouco mais de um propulsor verde
aqui, apenas para torná-lo um pouco mais exclusivo para a versão inimiga em que
vamos colocá-lo Então, podemos clicar em compilar
e economizar nisso. Vamos voltar para
a classe inimiga. Vamos pegar nosso sistema de
partículas do Niágara aqui, e tudo o que queremos fazer é
mudar isso do jogador, que
acabamos de renomear e mudar para a
versão inimiga Então, isso vai parecer
quebrado na planta. Tudo bem, porque
assim que entramos no playode, isso leva em consideração a direção mundial
do
movimento do sistema de partículas, e não
a entidade
que Então, podemos ver que agora está
funcionando perfeitamente bem. Um pouco diferente porque
temos cores diferentes, então também parece um
pouco mais interessante. Um bom ajuste simples só para colocar um pouco de mãos no sistema de
partículas existente, e temos o sistema do jogador
e do inimigo funcionando Então, essa é uma forma de
aplicarmos partículas sem código diretamente em componentes
e recursos existentes. Agora, se você se lembra, também
temos algumas coisas
prontas para começar a ser implementadas
em nosso código. Lembre-se de algumas
delas para fazer comentários. Então, um dos que eu me lembro de
ter estava na verdade em nossa classe de plantas
para nossos projéteis Então, se entrarmos na base de projéteis de
sublinhado da BP, e exatamente o que eu
mencionei anteriormente, vou
digitar todo Encontraremos aquele
comentário que eu
mesmo deixei , e está aqui embaixo. Então, se você não deixou esse
comentário, basta
navegar até a sobreposição de início do
componente, e é aqui que queremos
colocar alguns efeitos E vamos começar com
nosso sistema de partículas simples para mostrar que duas
coisas tiveram impacto Então, entre aplicar dano
e, novamente, o que é muito importante antes de
destruirmos
o projétil, vamos puxar o
pino
de execução e
procurar algo chamado
sistema de desova no local Então, queremos essa
opção aqui, abranger o sistema no local. Agora, há algumas coisas
diferentes se
você mesmo começar a
examinar mais as partículas para aproveitar o que
estamos fazendo aqui. Você também pode se deparar com
o termo emissor de spawn. Então, se pesquisarmos o
emissor Born no local, é uma terminologia muito semelhante, e essa é essencialmente
a versão antiga
do sistema de partículas Portanto, ainda não foi totalmente removido, mas eu o mencionei
brevemente há pouco. Costumava haver
algo chamado sistema de partículas em cascata Não era tão flexível, não tinha tantos recursos. Não é tão fácil
programar, mas agora usamos
o sistema Niagara Portanto, quando você quiser
trabalhar com o Niágara, que é o
ideal em que
você se concentrará, procure algo chamado sistema de palavras que
surja bastante Ao trabalhar com
cascata, se estiver em um projeto antigo ou
antigo, talvez
você veja a
palavra emissor aparecer Então, os artigos em cascata eram
chamados de emissores, enquanto agora, como mencionei, um emissor é apenas um único elemento
que constrói
um sistema inteiro que constrói
um Então essa é a
maneira mais fácil de se lembrar disso. Então, estamos
procurando um sistema. Você sabe que
também tem
o correto , porque se
colocarmos isso abaixo, não
temos nada
válido para colocar no slot
do emissor. Então,
vamos nos livrar disso. Se
derrubarmos este, queremos
encontrar nosso impacto metálico. Então é isso que
queremos usar quando dois projéteis ou um projétil
atingem outra superfície Então esse é o emissor
que queremos gerar. E isso nos permite
trazê-los em tempo de execução, fazendo com que os projetos pareçam um
pouco mais dinâmicos. A localização será muito simples. Vamos partir daqui
e vamos
procurar a localização do ator. Então, é
aqui que queremos que o efeito de
partícula apareça, o ponto de impacto, essencialmente,
de onde duas coisas acontecem A rotação em escala
deixaremos como padrão. Não precisamos
alterá-los. Voltaremos e faremos alguns
efeitos sonoros e outras coisas mais tarde. Então, na verdade, vou deixar esse comentário para mim mais tarde, pois precisarei voltar
e adicionar mais algumas coisas. Mas, novamente, agora podemos
entrar e testar,
e o que devemos
ver é que toda vez um projétil atinge algo, teremos algum tipo de efeito de partícula sendo Então, é um
pouco extremo, mas podemos definitivamente
ver que isso está acontecendo. E, novamente, você pode
entrar, refinar as diferentes escalas
e coisas assim Mas agora recebemos alguns comentários de que duas
coisas colidiram, que faz com que o
jogo pareça muito mais interessante e
intuitivo de jogar Eu também forneci,
além do impacto metálico. Você também pode
usar a explosão de pixels, então depende totalmente de você. Eu acho que eles parecem
um pouco diferentes. Basta verificar
sua aparência. Esse pode ser um
pouco mais adequado na verdade, para o impacto
menor Então, vou manter isso
com a explosão de pixels. Mas essa é a principal coisa que temos agora: esse feedback visual. E então queremos
fazer a mesma coisa nossos dois aviões. Então, novamente, mostramos
isso na classe base,
então vamos para a base do plano de sublinhado da
BP Acho que também me
deixei aqui, e vamos
clicar duas vezes nisso. Então, para implementar efeitos de morte de
avião. Então, esses serão os
efeitos que eu quero reproduzir quando qualquer um dos
aviões for destruído. Então, a mesma coisa novamente. Nós
vamos sair daqui. Vamos procurar a opção do sistema
Born. Pegue o sistema de extensão no
local. Mesma propriedade. Então, onde quer que o avião tenha
acabado de ser destruído, esse
será o local. Então, vamos encontrar
a localização do ato. E vamos fazer isso de uma maneira um pouco
diferente aqui. Então, como fizemos
no passado, queremos tornar isso flexível
porque estamos expondo isso para uso nas
classes secundárias do pai, onde está
a lógica central Então, vamos pegar
nosso modelo de sistema aqui e vamos apenas
promovê-lo para uma variável. Estamos renomeando este para efeito de partícula de
explosão. E precisaremos mudar isso nas classes infantis
porque o jogador e o inimigo têm efeitos de
partículas
ligeiramente diferentes Então, clicamos em compilar e salvar. Vamos
entrar na classe avião, a classe avião
do jogador. Certifique-se de que selecionamos
o elemento superior, e devemos ser capazes de
ver em algum lugar aqui embaixo, agora
temos um efeito de
partícula de explosão A partir deste, vou
encontrar o Pixel Explosion Player
e, em seguida, clicaremos em
compilar, exceto entrar no avião inimigo O mesmo de novo. Pegue
o elemento superior. Vamos encontrar nossa partícula de
explosão e mudá-la
para a versão inimiga Tão bonito e simples,
compile e salve novamente. E agora queremos
testar e ver como isso funciona quando as coisas
realmente se chocam. Então, vemos que há um pequeno atraso na primeira
vez que chega Em um jogo totalmente leve, você vai querer executar algo
para que os shaders sejam pré-compilados,
para garantir que todos os efeitos sejam
essencialmente
redondos , pelo menos
um, para que não tenhamos esse atraso Mas agora que
superamos isso,
podemos ver que temos os
diferentes efeitos. E também podemos testar. Quando o jogador morre,
recebemos a mesma coisa. Portanto, é um pouco diferente se
verificarmos e olharmos para eles. Acho que um é um
pouco mais azul, então temos uma espécie de explosão
azul aqui, e o outro
tem aquela tonalidade verde Portanto, talvez você queira entrar e alterar as propriedades da cor. E você pode ver que, à medida que as coisas ficam
um pouco mais complexas, podemos ver a complexidade, o número de emissores que está aumentando Mas quando você começa a se familiarizar com as coisas
que está procurando, elas são relativamente
fáceis de ajustar alterar
e configurar para
funcionar exatamente como você deseja Esse é o
lado da programação. Isso é realmente tudo o que
precisamos
fazer para que alguns
efeitos de partículas sejam reproduzidos. Portanto, é uma etapa relativamente simples adicionar um bom polimento
ao nosso projeto. E essa é outra
daquelas coisas em que
experimentar e brincar com
as coisas realmente vão beneficiar você
mais do que qualquer outra coisa. Por exemplo, tirei os efeitos
das partículas diretamente dos exemplos de conteúdo épico
e acho que, apenas para
a configuração geral as explosões parecem
um pouco finas demais, não tão grossas quanto
eu gostaria Então, o que eu poderia ficar tentado a fazer em ambos
seria entrar e encontrar as coisas especificamente relacionadas à
escala da malha Então, essas são três
dessas medidas estáticas. Eu posso ver aqui que
temos um tamanho de malha de escala, e eu poderia simplesmente
aumentá-lo para algo muito
maior por padrão. Eu posso ver aqui exatamente qual elemento está
tendo efeito,
para que possamos ver quais
acabaram de ficar muito maiores. Eu fiz isso quatro vezes
maior do que era. Agora, novamente,
isso
consome um pouco de tempo porque preciso
fazer isso para cada um dos
diferentes elementos. Então, eu entraria neste, por exemplo, definiria isso
para quatro, quatro e quatro. Mas agora temos imediatamente
um tipo muito maior de explosão robusta para o tipo de estrela
que estamos procurando Então, mudanças realmente simples como essa podem realmente
fazer a diferença nos emissores e tudo que
eu tive que fazer foi entrar e encontrar o tamanho da malha Então, se eu quisesse testar isso em nosso inimigo, faria
a mesma coisa novamente, para que pudéssemos pegar a escala de malha definir isso para quatro, quatro e quatro, para que corresponda ao jogador. E estamos fazendo
isso apenas para cada um
dos diferentes emissores, para que
tudo permaneça um pouco uniforme
, porque eles representam elementos
diferentes do sistema de
explosão Então, compile e salve
isso, podemos
entrar e jogar e ver
como fica R: Acho que é muito melhor. Acho que mostra uma
boa diferença entre o
impacto geral do projétil em comparação com a explosão
dos navios. Então, coisas muito
pequenas como essas. Você também pode encontrar as
cores, especialmente se tiver inimigos de cores
diferentes dos
que eu escolhi. Você pode entrar
na explosão inimiga, encontrar todas as
propriedades de cor entre todos os diferentes emissores, ver quais são
responsáveis por qual cor e depois
alterá-las de acordo com sua preferência Lembre-se de que uma
dica rápida
é que, se você não tiver certeza de
qual elemento deseja alterar, podemos simplesmente desmarcar os diferentes emissores aqui e ver o que é responsável por qual
parte. Então você pode passar. Isso seria apenas
aquele tipo de após o fumo, então podemos
desligá-lo. O do meio é
para a cor principal. Então, se meus inimigos
são, na verdade, verdes. Então, talvez
fizesse mais sentido
ter uma cor mais verde, para que possamos
valorizar o verde e aumentar isso
até o fim. E depois vamos. Temos mais uma
explosão verde para a noite inimiga. Então, temos um bom
tipo de amarelo começando com uma explosão
aquecida. Mas então estamos mostrando
que isso na verdade está voltando para
uma prorrogação verde, que é a cor da carroceria
da nave inimiga Então, novamente, uma mudança
muito, muito rápida. Desde
que você saiba mais ou menos o que está procurando, podemos fazer essas alterações
rapidamente. E veja isso meio que se
encaixar muito bem. Então, brinque com
esses tipos de coisas. Esses são tipos de abordagens
que farão com que você
entenda os sistemas
muito mais rapidamente. Você não necessariamente
saberá exatamente o que está procurando ao começar,
mas acho que, especialmente
com algo como
o sistema Niagara, as convenções de
nomenclatura, as coisas que você está
procurando e
o feedback imediato que você
recebe
do ponto de vista, é uma maneira muito útil de
aprender isso rapidamente,
apenas por meio de alguns erros de tentativa Então, essa é a primeira etapa para melhorar nosso feedback
visual. Isso faz com que tudo pareça vivo. Os inimigos ainda estão meio
que surgindo do nada. Em seguida, no próximo tópico,
queremos adicionar aquelas animações de
desova muito boas que foram fornecidas
no
25. 24 — Efeitos de áudio: ter dito que
vamos
entrar no Festival de Animação, mas percebo que,
na verdade, estamos ignorando a peça
que faltava aqui. E isso geralmente é algo
que é deixado
tarde demais no desenvolvimento de
jogos, que é o áudio. Queremos começar a
analisar o uso de San cues para randomizar uma quantidade mínima de arquivos de
áudio para fazer que as coisas pareçam um pouco
mais variadas e interessantes Também é uma dessas coisas
que, se você está protótipo de seu próprio
jogo, é muito,
muito fácil ignorar e
subestimar a importância do
áudio Você pode achar que seu jogo
parece monótono ou chato. Você pode adicionar coisas
como efeitos de partículas, trepidação da
câmera e todas
essas outras coisas, e pode ser
que
falte algum áudio no projeto que realmente
ajudaria a
dar vida a ele Então, vamos nos
concentrar neste festival. Então, se entrarmos em
nosso sorteio de conteúdo, vamos para
a pasta de áudio. Eu forneci alguns arquivos de som
diferentes. Temos um para a explosão, então vamos usá-los
para nossos aviões
quando eles explodirem,
e temos o efeito de tiro,
que será reproduzido
sempre que estivermos atirando para nossos aviões
quando eles explodirem,
e temos o efeito de tiro, que será reproduzido
sempre que estivermos atirando que será reproduzido
sempre que estivermos Provavelmente não vamos usar isso
para o
inimigo, mas, novamente, você pode ajustar e
contornar as coisas para ver como gostaria que o
projeto fosse configurado Acho que se houver muitas
coisas disparando ao mesmo tempo, isso pode facilmente se tornar
uma sobrecarga auditiva Se você quiser testar os arquivos de áudio e
ver como eles soam, podemos pular
o botão de reprodução aqui e você terá uma
reprodução imediata no editor Se nos concentrarmos em nossos tiros, primeiro, já que
temos dois deles, queremos
selecionar os dois, clicar com o botão
direito do mouse em qualquer um deles clicar com o botão
direito do mouse em qualquer um e temos essa opção aqui
para criar uma única fila Então, se escolhermos
criar uma fila múltipla, isso criará um
arquivo, um arquivo que para cada arquivo wave que
temos aqui embaixo. Em vez disso, podemos pegar esses
dois arquivos wave e compactá-los
em uma única fila Então, clicaremos nesse
. Renomeie este para SC Underscore gunshot Você pode ver que é um tipo de ativo um pouco
diferente. E, basicamente, as dicas SN são uma maneira muito simples se clicarmos
duas vezes para abrir Eles nos permitem trabalhar com vários arquivos de áudio sem precisar editar o arquivo de origem Assim, podemos manter o
gunshot
1 e 71 exatamente como estavam
quando foram importados, e podemos substituir
aqui individualmente coisas como se
ele deve ser
repetido, o volume padrão
e coisas Uma coisa a notar
é que você pode ver os pregos de forma inteligente o suficiente Ele sabe que, como
trouxemos mais de um arquivo assinado
diferente, provavelmente queríamos randomizar
a ordem em que
eles são reproduzidos, que é, na verdade,
o que queríamos Depois que as randomizações
foram feitas, porém, queremos partir
daqui e vamos
procurar por algo
chamado modulador Ou, na verdade, você pode
ver isso aqui embaixo. Vamos conectar
o resultado do nosso modulador na saída Então, isso alternará entre o som
a ser reproduzido. Ele vai randomizar
um desses. Vamos colocar
um modulador para que
possamos ajustar um pouco o áudio E então, qualquer
que seja o resultado da saída,
é o que será reproduzido
para o usuário final. Com o modulador
ainda selecionado. Você pode ver que a principal coisa
que eu queria ignorar aqui é o tom mínimo
e o máximo Isso só vai ajudar
a garantir que embora
tenhamos apenas dois arquivos de som, eles não soem
exatamente iguais quando
os dispararmos potencialmente centenas ou
quantas vezes seguidas. Eu dou uma
grande mudança de tom a ambas, então vamos definir 12,5 e
a outra para 1,5 E, novamente, esses valores podem
ser bastante extremos
e, se o som
estiver muito distorcido, é aqui que podemos
voltar e começar a refiná-lo
gradualmente para que
soe exatamente como queremos O mesmo com o
volume, podemos definir um para 0,9 e outro para 1,1. Portanto, temos uma espécie
de deslocamento semelhante ao volume mínimo e máximo
dos dois efeitos
sonoros
sempre que eles tocam Então isso foi ótimo.
Pudemos ver que isso definitivamente estava funcionando exatamente
como
queríamos , com uma pequena ressalva Pegadinha comum com
o antigo sistema Q que estamos usando aqui A randomização não é
realmente tão aleatória. Você pode ver que é
simplesmente
alternar entre
as duas opções Ele tocará A, depois B, depois A, depois B. Bastante previsível. Então, se pegarmos nossa nota aleatória, uma coisa que queremos fazer é
desmarcar isso aqui, a randomização
sem substituição Algo que as pessoas
geralmente ignoram. Mas agora, se
pressionarmos play, não
precisamos necessariamente ouvi-los, então vou silenciar
o volume rapidamente Mas
verifique se você pode ver qual fio está sendo disparado. E o que devemos ver é que eu tive cerca de quatro ou
cinco cliques lá, enquanto obtive a
mesma reprodução de áudio, que está ficando muito mais próximo verdadeira randomização do
que do flip-flop entre A e B. Obviamente, você também gostaria de
fazer isso se tivesse várias ondas sonoras em cima disso em sua única
fila Então, se você tivesse cinco ou seis, não gostaria que fosse um,
dois, três, quatro, cinco, um,
dois, três, 45 e assim por diante. Você gostaria que ele escolhesse
aleatoriamente entre esses cinco ou seis efeitos sonoros Portanto, lembre-se sempre
de entrar e desmarcar a opção randomizar
sem substituição Feito isso, queremos fazer algo
semelhante
com as explosões. Então, vou clicar com o botão direito
na onda de explosão. Vamos criar uma única fila de
som para este. Vamos chamar isso de SC
underscore Explosion. Obviamente, não precisaremos de nenhuma randomização
entre este Temos apenas um único
arquivo, mas ainda podemos
usar coisas como inserir
um modulador novamente no meio um modulador novamente no Então, vou conectar outro modulador aqui
da mesma maneira e talvez fornecer algumas diferenças um pouco menos intensas aqui Então, talvez 0,7 a 1,3. E, novamente, podemos
voltar e refinar se isso for uma mudança
de tom demais Vou deixar o volume mínimo e
máximo como estão. E é apenas um ajuste muito
simples que vamos fazer dentro
da nossa fila de som Se você estiver usando mais um plano
de fundo de áudio, pode
haver outras
terminologias e recursos com os quais você pode brincar no lado direito e simplesmente
arrastá-los para o gráfico, reproduzir até a propriedade e ajustá-los conforme achar Para esta demonstração simples, ough, vou manter isso
como temos aqui. Então, vou
passar rapidamente e começar a fechar algumas das
janelas que eu não preciso, especialmente os efeitos de partículas, então vamos nos livrar deles E se começarmos
na base de jogo, eu já estou aqui, então
vou lidar com o efeito da
morte primeiro. Vou deixar o
comentário aqui, pois
provavelmente precisaremos de mais algumas
coisas um pouco mais tarde. Então, entre nosso sistema de partículas de
desova e a chamada da função de destruição do
ator, vou puxar
o pino de execução e procurar o som
reproduzido no local Então, esse é um
recurso muito bom novamente dentro do Unreal. Já incorporamos o áudio espacial
padrão. Assim, podemos fornecer
o ponto inicial de onde queremos que esse
áudio seja reproduzido. Assim, podemos tornar as coisas um
pouco mais verossímeis
se um avião sendo destruído na parte superior
esquerda da câmera, então teremos um efeito sonoro que
deve tocar um
pouco mais no
lado esquerdo do fone de ouvido Então, vamos usar a função
padrão aqui. Vamos usar a localização do
get act para descobrir onde o
avião que explodiu foi destruído E então usaremos o menu suspenso de som
aqui embaixo e escolheremos nosso SC, nossa dica sonora
que personalizamos a explosão de
sublinhado Agora, nós realmente não precisamos
promover isso porque, novamente, os dois
usarão os mesmos efeitos
sonoros de explosão, e ambos terão sua própria randomização
e coisas assim Agora, não vou
usá-lo aqui, mas também queria mostrar os recursos aos quais
temos acesso. Então, se usarmos o menu
suspenso neste nó, se você não quiser
brincar com sinais sonoros ou apenas quiser
usar o arquivo de ondas de regras, ainda
podemos entrar
e fazer coisas como volume, multiplicação de
tons Poderíamos lançar algo
como uma bóia aleatória, novamente, então já vimos isso
várias vezes ou idealmente, uma flutuação aleatória ao
alcance, como vimos antes E isso é muito semelhante
ao que configuramos
na sugestão sonora para
o multiplicador de tom Mas como temos uma
fila de som agradável e
personalizável com a qual trabalhar, vamos usá-la em vez
dos arquivos de ondas
sonoras padrão rurais Também podemos abordar muito mais coisas
detalhadas com coisas como configurações de
atenuação Então, isso é fornecer ao sistema de som de
três D, uma espécie de queda, uma faixa na qual o áudio
deve ficar mais alto e mais baixo, dependendo de onde é esporte Para isso, porém,
vou copiar
a funcionalidade
que temos aqui porque
queremos adicioná-la à
nossa função de disparo. Então, vamos apenas mover
o comentário. Vamos
voltar aqui e fazer mais
algumas coisas quando fizermos nossos passes finais nos efeitos, então isso ainda é relevante. Mas vamos pegar
esse controle de pressão em C. Vou entrar na função de
disparo. E depois que o projétil for
gerado, podemos simplesmente soltá-lo aqui A mesma coisa novamente,
queremos o local em que o
efeito sonoro do fogo deve ser reproduzido. E vamos
pegar nosso tiro aqui, e isso automaticamente reproduzirá um tiro agora, sempre que
algo É porque acho que se houver quatro ou cinco inimigos
na tela e todos
estiverem atirando
em rápida sucessão, talvez
queiramos
diminuir o volume deles Então, acho que o que vou
fazer é, em vez de ter funções de disparo
separadas
em cada classe, novamente,
usaremos a herança sempre que possível Vou promover
o modificador de volume e vou promovê-lo
para uma variável, e chamaremos isso de compensação de volume de
disparo Portanto, podemos padronizar isso
para um valor de um, o que já era. Então, vamos usar
como padrão tocar o volume total da sugestão sonora do
tiro Então, é claro, se configurarmos isso para randomizar um pouco
aqui com o modulador, o volume padrão pode
ser 0,9 em direção
a Em seguida,
substituiremos isso e multiplicaremos isso por um total
de um ou pelos inimigos, por exemplo O motivo pelo qual quero usar isso é que vamos clicar em compilar e salvar Eu vou entrar
na classe inimiga. Encontraremos esse valor
aqui nas propriedades. Vou dar a isso um deslocamento
de volume padrão de 0,5. Então,
teremos o
volume padrão para tiros inimigos. Portanto, mesmo que comecem a se
acumular um pouco, não
devem se tornar completamente insuportáveis e, como eu disse, superestimulantes Ok, então, um teste de jogo muito
rápido. Descobri que os tiros
provavelmente eram tão altos
ou talvez mais altos do que
as Então,
acho que o que vou fazer é definir
um volume mínimo, e isso é
potencialmente
baseado nos tipos de
sinais que encontrei. Provavelmente foram
apenas exportados, não com um bom volume
normalizado Então, talvez por padrão, na verdade, vamos levar
isso para 0,5 a talvez
0,7 ou talvez 0,4 a 0,7. E
veremos como isso soa. Ok, então depois de alguns ajustes, descobri que um
bom valor era 0,1 e 0,2 para o mínimo e um
máximo para o padrão, e então
vamos reduzir ainda mais o inimigo adicionando esse deslocamento de
volume aqui Então isso não é o fim
do mundo. Como eu disse. Os ativos são perfeitamente viáveis, mas essas são apenas coisas
úteis que você pode
receber ou encontrar ativos em
mercados e coisas assim,
e alguns podem ter
sido exportados com um volume completamente diferente Portanto, é útil saber que temos vários lugares onde podemos aplicar diferentes deslocamentos de
volume e
coisas assim Um projeto ou um jogo
de produção completo. É por isso que também é
muito importante
ter algo como
um menu de configurações com alguns
controles deslizantes de áudio realmente flexíveis para que as pessoas
possam optar por tornar seus efeitos sonoros mais
baixos ou mais altos do que música, a voz
e coisas assim E para o amor dos
ouvidos de todos, inclusive os meus, defina seu volume principal
padrão para algo em torno de 50%. Ninguém gosta de ligar o jogo
e ter seus
tímpanos destruídos em e ter seus
tímpanos destruídos 100% do volume principal
quando seu jogo está um nível
de
volume completamente diferente qualquer outra coisa que o sistema
possa estar jogando Portanto, o áudio pode realmente ser muito
importante e causar uma
primeira impressão muito boa ou ruim no seu jogo,
dependendo de como você o usa. Mas, novamente, isso é apenas outra
coisa que você vai querer ajustar
e usar Ouça o que você pensa sobre os tiros em seu sistema
versus a explosão Veja onde você pode querer
alterar os modificadores de volume, as
diferentes opções de espera
que eu
mostrei para tentar fazer com que
seu jogo soe bem mixado
e seja o mais interessante de
ouvir possível,
mesmo que tenhamos apenas
alguns
arquivos de áudio diferentes para
jogar que eu
mostrei para tentar fazer com que
seu jogo soe bem mixado e seja o mais interessante de
ouvir possível, mesmo que tenhamos apenas alguns
arquivos de áudio diferentes para Você também pode acessar sites
diferentes, HIO, freesound e coisas
assim para baixar alguns novos efeitos sonoros
e ver o que você pode adicionar ao projeto para realmente
começar a torná-lo seu A principal coisa que
você
está procurando é jogar
por alguns minutos. Alguma coisa começa
a ficar irritante depois da marca dos 32 minutos E se sim, você pode
simplesmente corrigir isso
reduzindo o
volume geral na fila de som Ou, se necessário, como eu disse, talvez
queiramos até mesmo
entrar e remover o tiro do inimigo ,
porque isso
acontecerá com muita frequência Nenhuma dessas são regras claras e
específicas que
devemos seguir. Como acontece com muitas outras
coisas, serão muitas
tentativas e erros para ver o que funciona e o que melhor
afeta seu resultado final. Com o
feedback de áudio concluído, o jogo agora está
presente, fornecendo feedback
visual e auditivo Em seguida,
passaremos para as animações de spawn, que são apenas um extra
opcional além
do brilho visual que já
começamos a
adicionar ao
26. 25 — SpawnAnimations: A camada final de polimento, vamos
dar uma grande introdução aos nossos navios. Faremos com que o jogador
e as naves inimigas
deslizem e girem para a posição em vez de simplesmente
surgirem Mais uma vez, uma animação
na classe base
que funcionará para todos os aviões com os quais
queremos trabalhar. Então, por esse motivo,
vamos
direto para nossa gaveta de
conteúdo, pasta de
esquemas, núcleo e
encontraremos a base do plano de sublinhado
da BP Queremos voltar
ao gráfico do evento principal
e, ao lado do início do jogo, clicaremos com o botão direito do mouse
e procuraremos um recurso útil aqui
chamado Adicionar cronograma Então, é essa opção
na parte inferior. Podemos dar um nome a isso.
É uma espécie de função que tem seu próprio gráfico embutido. Veremos isso
daqui a pouco, mas podemos dar esses nomes. Então, vamos chamar isso de
anime, como em animate in. Como acontece com qualquer outra coisa,
eles só serão ativados quando uma
execução os atingir. Vamos extrair
nosso pinhe de execução e queremos
colocar isso em prática desde o início Então, essa
será uma curva gráfica que podemos animar,
e só queremos ter certeza de
que ela sempre começa a ser reproduzida do quadro zero na
curva até o final Temos outras opções, como
jogar a partir de um determinado ponto, parar a animação, jogar
ao contrário ou qualquer outra coisa. Só queremos jogar essencialmente do quadro zero até o final. forma como isso funciona é
como uma atualização temporária, muito útil se você não precisa algo para animar constantemente Isso acionará cada
quadro enquanto a linha
do tempo estiver sendo reproduzida
antes de chegar ao fim E então,
enquanto estiver sendo acionado, ele chamará o pino de
atualização aqui E então, quando
terminar a animação, ele chamará o pino finalizado. Então, sabemos se e quando
ele ainda está sendo reproduzido, e também sabemos quando é atingido no final
da animação. Tudo isso vai
ser muito útil. Então, se
clicarmos duas vezes nesse nó amarelo aqui, começaremos a notar que muitos dos nós com os quais
trabalhamos têm cores
diferentes Esses azuis são as
funções que estamos criando, então você sempre vê que uma função
é indicada por Qualquer evento personalizado ou evento no gráfico como esse ainda é
essencialmente uma função, mas eles são indicados Temos coisas como
as variáveis verdes e agora temos uma função ligeiramente personalizada
baseada no tempo, nossa linha do tempo de animação,
que é amarela Quando os vemos com bastante frequência, podemos clicar duas vezes neles e teremos um
novo recurso aqui. Então, clique duas vezes nesse
nó e estaremos dentro da linha do tempo Há algumas coisas
que queremos fazer. Primeiro de tudo, precisamos de
uma faixa para trabalhar com uma curva de animação
para começar a criar. Então, se pressionarmos a faixa
positiva aqui, temos algumas opções diferentes, podemos criar uma curva flutuante, uma curva vetorial, uma
faixa de eventos ou
curvas de cores, essencialmente Só queremos um zero a um muito
bom, essencialmente um
valor normalizado que possamos rastrear Então, vamos criar
uma pista flutuante aqui. E algo que
é muito importante, podemos clicar com o botão direito do mouse e arrastar para mover o meio
do mouse até o Zoom innit, como muitas outras
navegações dentro do Mas uma
coisa muito importante, antes de começarmos a adicionar quadros-chave
ou pinos aqui, queremos definir a
duração da nossa animação Se começarmos a adicionar pinos agora, você pode ver que estamos passando
de um período de zero para 5 segundos. Então, vamos reduzir
esse comprimento até um, e isso significa que
estamos imediatamente trabalhando com uma linha do tempo de curva, que é o comprimento que
queremos que tenha Agora, a razão pela qual eu faço
isso, veremos isso um pouco mais quando
detalharmos as coisas, mas não estamos pensando nisso
como um momento. Não vamos fazer isso
em 1 segundo. Basicamente, podemos
pensar nisso como uma porcentagem. Isso seria 0%
da nossa animação e isso seria 100%
da nossa animação. Mostre
um pequeno truque útil que eu não vejo com muita frequência
um pouco mais tarde E é assim que
podemos realmente adaptar isso para ser uma animação de cinco
segundos,
uma animação de dez segundos, uma animação de
meio segundo,
o que quisermos que seja. Desde que tenhamos normalizado isso para um intervalo de zero a um
, podemos tratar isso
mais como uma porcentagem Agora, se ampliarmos
um pouco aqui, agora
tornamos a curva
um pouco menor, podemos segurar a tecla Shift e
clicar com o botão esquerdo e criar
esses quadros-chave aqui Então, se você já trabalhou com qualquer
outro software de animação, eles serão
bastante familiares para você. Esta será a nossa
vez de que isso aconteça e a força ou o valor naquele
momento. Se você está clicando
aleatoriamente como eu, na verdade só
precisamos de
dois pontos aqui Então, vou agarrar e
selecionar alguns desses pontos, esses quadros-chave, e
vou me livrar deles Primeiro quadro-chave, vou definir isso
para um tempo de zero e um valor de zero Então, neste momento, exatamente nenhuma animação aconteceu. E então, para o
segundo quadro-chave, vou
arrastar para selecionar este e defini-lo para um tempo
de um e um valor de um Então, este é o nosso 100%
da animação que
agora está 100% completo. Então você pode começar a ver como
estamos vendo isso como uma porcentagem em
vez de um valor específico. Outra coisa que
queremos fazer é
deixar isso bonito e
suave imediatamente Se fôssemos animar ao longo
dessa faixa, no momento, seria uma animação
muito plana, consistente e um tanto chata Então, se arrastarmos e selecionarmos
os dois, clicar com o botão
direito
do mouse em qualquer um dos quadros-chave e
definir
isso como Automático, isso nos proporcionará uma boa suavização na entrada e
na saída Agora você pode brincar
com eles, se quiser. Você pode exagerar
quando chega pela primeira vez, ou pode ser muito
lento quando chega pela primeira vez E esse é um dos benefícios mais
interessantes de trabalhar com
esses quadros-chave como esse: podemos
brincar com a animação para
torná-la mais estilizada,
mais caricatural, o que
você estiver procurando Mas acho que vou continuar
assim. A última coisa é que
essa faixa zero ou nova faixa zero é algo
que também podemos ajustar Então, vou clicar aqui. Vou pressionar F dois para renomear isso, e vou dar a isso
o nome de Alpha Porque quando começarmos a
realmente animar nossos aviões para voar, essa será essencialmente a hora extra do
Alpha que estamos
rastreando , em vez do valor rotacional
específico E isso
é que em muitos exemplos, trabalhando
com cronogramas, você pode ver pessoas
animando diretamente a localização ou rotação dos valores vetoriais
reais durante um período específico de tempo, e espero que você
veja até o final disso como isso pode ser bastante
inflexível, porque,
novamente, se animar algo
que leva exatamente 7 segundos, que leva exemplos, trabalhando
com cronogramas,
você pode ver pessoas
animando diretamente a localização
ou rotação dos valores vetoriais
reais
durante um período específico de tempo,
e espero que você
veja até o final
disso como isso pode ser bastante
inflexível, porque,
novamente, se animar algo
que leva exatamente 7 segundos, e você
Eu fiz isso em todos os XY e Z dos valores de localização
ou rotação, e então você decide
que, na verdade, isso é girar demais e precisa levar
metade do tempo Você precisaria entrar,
alterar o comprimento da faixa, mover todos os
quadros-chave, e isso pode se tornar um pouco
complicado e demorado Onde está isso? Podemos definir isso
apenas uma vez e, em vez disso, temos controle total
da animação em nosso código
real. É isso mesmo. Isso está
praticamente pronto. Portanto, temos nossa curva pronta para fornecer um
valor alfa ao longo do tempo. Então, se clicarmos em compilar
e
voltarmos ao nosso
gráfico de eventos aqui, tudo o que isso fez foi
simplesmente colocá-lo em uma guia dentro da
linha do tempo de animação que criamos Então, vamos voltar
ao gráfico de eventos. Então, para definir nossa animação primeiro lugar, a partir do
nosso pino de atualização, lembre-se daquela que
está constantemente em execução agora até que a
animação termine, queremos chamar a função set actor Location a partir daqui. Isso será o
resultado de um lp, novamente, então vamos usar
a função larping
que vimos antes Portanto, nossa interpolação linear
entre dois vetores, não a interseção dois
ou qualquer coisa extravagante, basta apontar A para o ponto B com um
alfa Então, você pode realmente ver que o
motivo pelo qual chamamos isso de Alpha é que podemos
conectá-los diretamente e já temos
parte da resposta aqui apenas com base nas convenções de
nomenclatura Então, só precisamos
calcular ou descobrir qual será o ponto A e
qual será o ponto B. Para dividir isso como um conceito, ponto A
será simplesmente o local de desova. Então,
de onde quer que comecemos , quando
aparecermos, será o ponto A. Então, queremos
chegar a um certo número de unidades à frente
desse ponto de desova, que será nosso ponto B, algo que confunde
bastante as pessoas quando
trabalham com animações ocultas e é
confuso porque
parece que está parece Mas quando você pensa sobre isso, o que estou prestes a mostrar seria na verdade, meio que confundir um pouco
a animação Então, o que algumas pessoas
fariam quando estivessem trabalhando
pela primeira vez com interpolações
lineares é
que sabemos que o ponto A é nosso ponto de
partida Assim, podemos clicar com o botão direito do mouse e pesquisar Obter localização do ator. Para muitas pessoas,
pode fazer sentido que passemos do nosso ponto de
partida para um ponto final E poderíamos dizer que o
ponto final, por exemplo, seria simplesmente
onde estamos agora mais uma unidade vetorial em uma
determinada direção Então, se pegarmos onde estamos
no ponto de partida
e projetarmos , digamos, 300 unidades à frente, é aí que
queremos terminar. Esse
seria essencialmente nosso ponto final. Agora, isso não funcionaria de qualquer maneira, mas apenas para colocar rapidamente um código para mostrar que,
poderíamos dizer algo como sabemos que X está
para frente, então poderíamos obter a localização x mais 300
unidades para frente no X. Parece
que
poderia ser nosso início e fim E eu queria abordar
isso e por que não
vamos usar isso,
exatamente porque
vejo isso em muitos projetos de
estudantes
e novos projetos de desenvolvimento,
porque, como mencionei, isso meio
que faz sentido. Temos nosso ponto de partida e nosso ponto final
com base nisso Mas o que as pessoas não estão
considerando quando estão fazendo isso é que isso não é disparado
apenas uma vez Acho que é aí que as pessoas
ficam um pouco confusas. Eu imagino que isso seja
demitido apenas uma vez e esse
valor permaneça o mesmo. Então, se começarmos em 000
e adicionarmos 300 a isso, esperaríamos ter
30000 como ponto final Mas o que realmente está acontecendo é cada quadro
está sendo chamado, e isso está sendo verificado novamente Então, se começarmos em
zero, zero, zero e depois movermos algumas unidades,
digamos que movemos cinco unidades. No próximo quadro, quando isso esfriar, estamos agora em 500 Então, isso significa que o endpoint será 30500 em vez disso. Então, esses dois valores se
movem continuamente. Vamos animar apenas
por
1 segundo ou por quanto tempo
for, de qualquer forma Isso significa que
chegaremos ao fim, então parece que as
animações estão acontecendo, mas sempre parecerão um
pouco erradas,
e talvez até um
pouco imprevisíveis porque esses dois valores
são constantemente verificados e
atualizados e aplicando um resultado de lp diferente no final do cálculo,
se isso fizer sentido Foi só para apresentar por que
precisaremos
nos dar um pouco de espaço, criar
algum espaço aqui. E o que queremos fazer é
garantir que esses valores sejam
armazenados e imutáveis Então, não é uma
coisa difícil, mas eu só queria destacar que isso
acontece com relativa frequência, e eu posso ver, eu acho,
por que as pessoas fariam isso. E é
algo que você deve observar sempre que tentar criar sua própria animação ou
personalizá-la posteriormente Lembre-se de que um loop
precisa de um início e um alvo constantes para ser
animado sem problemas entre eles Então, o que vamos fazer
em vez disso é pegar isso, então vou cortar o Controle X e colar a localização do
ator get. Vamos
promover isso como uma variável e chamaremos isso de
um local inicial. Então, claro, conecte isso, e então faremos uma coisa muito parecida aqui. E, como mencionei,
isso não funcionaria qualquer maneira porque estamos
apenas adicionando uma unidade. Na verdade, não estamos
levando em consideração a direção para
a qual o avião está olhando, então precisamos fazer um
pouco mais do que isso de qualquer maneira. Mas mesmo que
fizéssemos todo o processo, ainda assim não
funcionaria. Então, vamos
mover isso, pegar isso, então recortar e colar isso aqui. Ainda podemos fazer uso
de um monte disso. Agora, a primeira coisa
é lembrar que os inimigos também querem
usar isso e serão
atacados quando aparecerem Portanto, não queremos que
eles sejam
animados na tela como o jogador. Queremos que eles
sejam animados com
base na direção
para a qual estão voltados. Então, o que vamos fazer é
pesquisar o vetor direto do ator
G. Portanto, isso obterá
a direção em que o ator está sendo girado
ou voltado atualmente Lembre-se daquela flecha que
aplicamos ao projétil. Basicamente, verificarei qual direção a
flecha está voltada Em seguida, queremos multiplicar
isso por um valor. Então, vamos pegar
o vetor direto, que é uma direção,
não um valor, então isso
será algo como 11 e um ou 100
se estiver voltado para frente ou menos 100 se estiver voltado para
trás, por Vamos multiplicar a direção,
não
a posição real do vetor, é por isso
que
podemos multiplicar Vamos multiplicar
isso por um flutuador, então vamos
clicar com o botão direito do mouse no pino aqui, transformá-lo em um
flutuador, e
ainda podemos pegar esse valor de 300
unidades Então, queremos mover 300 unidades na direção para frente.
Podemos então fazer uso disso. Então, queremos pegar
esse valor e adicioná-lo a
outro vetor. E, de fato, vamos nos
livrar desse. Portanto, essas notas não
serão mais necessárias, apenas para manter as coisas
bem arrumadas, e vamos
arrumá-las um pouco E o que queremos levar
é que, para onde quer que
comecemos, queremos nossos XY e Z
da nossa posição inicial. Mais 300 unidades na direção
para frente. Então, multiplicando nosso avanço para
obter um negativo ou um positivo sobre se estamos voltados para frente ou
para trás e o X, vamos pegar isso
e dividir alguns Então, a primeira coisa para tornar
isso um pouco mais fácil ler é transformar
esse pino em uma variável
e nomear esse
local de destino. Podemos clicar com a tecla Alt e
clicar com o botão esquerdo para baixo. Vamos dividir o pino
da estrutura aqui. E agora temos todos
os nós de que precisamos. Podemos
arrumar isso um pouco. Na verdade, queremos que nosso primeiro
pino seja nosso local de partida Então, novamente, apenas por preferência
pessoal, vou controlar e arrastar o local inicial
e substituir este. Então, podemos pegar onde
começamos mais um deslocamento na direção em que estamos olhando pelo número X de unidades Isso
nos moverá 300 unidades no X, é o que estamos
vendo aqui porque X é quatro. Então, se pudéssemos
obter o vetor get actor up, e se o
conectássemos em vez disso, isso aplicaria um deslocamento
no eixo z simplesmente porque
Z está dentro do irreal X está para frente, Y está para o lado. Portanto, podemos obter diferentes posições
vetoriais com algumas
funções incorporadas aqui. Só queremos considerar seguir
em frente. E então não podemos
usar o valor total aqui porque queremos manter nossos Y e Z consistentes independentemente de onde estamos girando ou nos movendo aqui Então, vou pegar o local
inicial novamente, duplicar isso aqui embaixo,
dividir o pino da estrutura E podemos conectar o Y e o z
a esses valores aqui, é por isso que eu dividi
isso há pouco. E então, qualquer que seja esse valor,
então, o cálculo de
até onde queremos avançar em nossa direção local para frente, vamos dividir essa
estrutura também, e esse será o nosso valor
X que queremos. Então, lembre-se, isso é apenas
calcular o X de qualquer maneira, então podemos pegar esse valor X. Essa será a quantidade de
unidades para a qual queremos voar no valor
X ou futuro. E esse será nosso local de
destino. Então, vamos conectá-los. Talvez precisemos arrumar
as coisas e
movê-las um pouco,
mas está tudo bem Podemos simplesmente mover
isso para baixo e
voltar e resolver isso
um pouco mais tarde O principal é que agora podemos
voltar ao nosso loop. E, novamente, isso está deixando
as coisas claras e claras agora. Vamos dar a isso
nossa localização inicial e nossa localização de destino
como os argumentos A e B. Então, se entrarmos,
provavelmente poderíamos testar isso apenas para ter certeza de que algo está definitivamente acontecendo aqui. E podemos ver que o avião do
jogador está definitivamente deslizando um
pouco
para frente , assim como
o avião inimigo Então está deslizando para dentro e depois está
se movendo de um lado para o outro. Assim, podemos ver que a animação
inicial está funcionando da
mesma forma para o player, o
que significa que
provavelmente queremos começar
nosso player e iniciá-lo um
pouco mais para trás. Na verdade,
podemos simplesmente vir aqui. Outra coisa que você
talvez não conheça. E isso é muito
útil, pois podemos pegar nossa localização porque sabemos que é aqui que queremos chegar neste
ponto da tela e podemos digitar aqui -300 Então, se digitarmos -300, isso realmente funciona
como uma equação matemática, então isso nos dá -190 -300, e obtemos exatamente menos 490, que será nosso ponto de partida, e então voaremos e terminaremos exatamente onde
estávamos Então, isso realmente parece um
pouco mais interessante. Eu acho que isso parece muito legal. Então, isso é definitivamente
um bom começo. E você pode ver,
esperançosamente, como toda essa matemática está se
encaixando e funcionando E, novamente, fizemos
esse trabalho considerando o
vetor dianteiro do ator. Então, a forma como ele foi
girado, e só para recapitular por que isso é relevante, é porque, quando
geramos os inimigos, os giramos
180 graus para
coincidir com a direção de apontamento
de nossa classe de Então, eles estão avançando
em relação ao fato de apontar, o que significa que tudo está sendo
animado da maneira correta Então essa é a primeira
parte do quebra-cabeça. A segunda parte tornará isso
ainda mais interessante, fornecendo também um deslocamento de
rotação Então, depois de definir a localização do ator, queremos afetar apenas
o elemento visual da rotação, porque não
queremos mexer com o colisor de
esferas e mudar potencialmente a forma como
os atores Então, vamos
fazer disso uma
mudança visual em vez de uma posição ou mudança
real. Então, para fazer isso,
geralmente obtemos coisas como, vez disso,
usaremos a
malha estática. Vamos arrastar isso para o chão, vamos tirar isso
daqui e vamos
procurar uma rotação mundial definida. Algo muito parecido, mas agora estamos apenas afetando a malha. E isso é muito melhor
porque, de qualquer forma, não estamos fazendo nenhuma colisão ou nada nenhuma colisão ou nada
importante com a malha Isso está aqui apenas
para fazer coisas visuais, e isso é uma mudança visual Então, conectaremos
isso para que seja chamado imediatamente e faremos algo muito semelhante Vamos pegar
nosso Alpha e fazer um loop para o rotador Então, vamos partir daqui
e procurar o loop novamente, p rotator, e novamente, obter a mesma coisa, A
e B com um Alpha Isso é totalmente opcional.
Você pode promover o Alpha a uma variável apenas para
uso nessa função. Outra coisa que eu
quero apresentar,
porém, é que
poderíamos simplesmente fazer isso. Eu cliquei duas vezes no fio. E, novamente, só para manter
as coisas um pouco mais organizadas, vou conectar
os Alphas dessa maneira Como essas são
as únicas duas vezes que vamos usá-lo aqui, acho que talvez tornar
uma área variável apenas para esse evento
único de incêndio, talvez um pouco exagerado Então, vou apenas apresentar
o uso de nós de reenraizamento. Isso ainda o mantém
um pouco organizado e fácil de
visualizar e trabalhar E então, para o A&B, faremos algo muito
semelhante aqui novamente, mas obteremos
os valores de rotação Então, talvez você queira começar a arrumar algumas
das coisas aqui É aqui que, como
mencionei as sequências podem ser muito boas Então, um corte muito rápido aqui. Queremos potencialmente começar a monitorar o que estamos fazendo
para inicializar valores,
essencialmente, quando estamos definindo e fraturando valores
no início Isso normalmente é chamado
de inicialização. E acho que posso
separar isso
da nossa animação real da
linha do tempo Tão simples e simples que, novamente, esses fatores de referência
realmente não demoram muito. Se puxarmos
o pino de execução aqui e procurarmos por uma sequência, isso a
conectará automaticamente para. Então, na verdade, não estamos
mudando nada. Novamente, isso é apenas organizar a ordem em
que as coisas são tratadas Vou simplesmente soltar esses
nós aqui
e, em seguida, moverei
a animação para o fim. E o que
faremos é garantir
que todas as variáveis
estejam prontas primeiro
e, depois de rastrearmos
todas as variáveis que usaremos
na primeira, chamaremos
nossa animação para ser reproduzida Então, novamente, na verdade, tudo o
que
isso está fazendo é manter as coisas
um pouco mais organizadas, fáceis de ler e
trabalhar Isso significa que agora podemos começar
a remover alguns deles
porque
queremos todas essas verificações
baseadas em localização primeiro. Então, isso está mantendo nossa posição
inicial ainda. E depois disso, também
vamos querer começar nossa rotação inicial. Então, a partir daqui, podemos pesquisar rotação do mundo
G
na malha estática, da mesma
forma que fizemos anteriormente. Vou arrastar nossa malha estática,
usaremos a rotação mundial G. E, como fizemos
com os locais, vamos pegar esse valor e promovê-lo
para uma variável. E isso é
exatamente pelo mesmo motivo. Quando estamos usando isso
em uma animação, não
queremos que esse valor
mude com o tempo. No entanto, começamos nossa rotação quando
nascemos no mundo. Esse é o nosso ponto de partida,
e também teremos uma compensação permanente em relação a ele como nosso ponto
alvo permanente Agora, podemos fazer isso um
pouco mais facilmente. Não precisamos de um
alvo real para o B. Você pode promover uma variável
como alvo se quiser, mas isso é um
pouco mais simples. Então, para nossa rotação inicial, vamos simplesmente colocar a rotação
inicial em A, então é
daí que estamos girando. E então nosso alvo. Então B, podemos simplesmente dividir o pino da estrutura
aqui porque a única coisa que
queremos considerar é que estamos fazendo uma rotação de 720
graus Pelo menos foi o que eles
fizeram no projeto de exemplo. E, novamente, estamos apenas recriando isso de uma forma um pouco
mais organizada Então, o que podemos fazer
é arrastar nossa rotação inicial aqui,
dividir o pino da estrutura. Sabemos que queremos que o Y
e o z permaneçam os mesmos. Não queremos adicionar nenhuma rotação para
cima ou de cima para baixo. Não estamos girando
em torno de nós mesmos. Sabemos que estamos afirmando que
a malha estática está sempre começando em uma rotação de zero porque
não mudamos isso E mesmo com os
inimigos, estamos girando todo o ator em
vez de sua
malha estática, para começar Isso significa que
podemos, com muita segurança, adicionar uma rotação de 720 graus ao X, que está girando em torno de si mesmo Lembre-se do que estamos fazendo
para que tudo
gire dessa maneira. Estamos fazendo uma coisa muito
parecida aqui. Então, se clicarmos em compilar e proteger, podemos testar isso e,
novamente, isso deve funcionar Tão bom, fácil. Você pode ver que está
funcionando perfeitamente bem. Então é isso que queríamos
lá, uma rotação de 720 graus ou duas vezes
em torno de si mesma. Se você quisesse que fosse
apenas um único 360,
para que eles girem um
pouco mais devagar, podemos definitivamente
diminuí-lo,
para que seja apenas um rolo, ou você pode ficar um
pouco louco, talvez fazer com que ele faça cinco rotações 360
diferentes, e ele girará
algumas vezes Então você pode se divertir. Você pode brincar com
isso exatamente como quiser. Como eu disse, acho que
pelo projeto de referência, aquele que estamos
tentando recriar, acho que foi apenas um rolo de 720 graus
que eles fizeram Então é assim que podemos aplicar isso. Agradável e simples. Na verdade,
não precisamos um alvo específico porque é apenas a rotação inicial com um deslocamento de 720 graus para
fazer com que ela gire duas vezes Isso também preenche uma grande coisa que estávamos perdendo
há muito tempo, apesar de termos o
código pronto em nosso projeto E isso é que o jogador e os inimigos não deveriam
realmente se mover de um lado para o outro até que
tenham feito a animação
esporádica Novamente, isso é apenas para fins de paridade
com o projeto de exemplo. Se você jogar
a partir dos exemplos de conteúdo, verá que
não tem permissão
para controlar e mover os navios até que eles
terminem esta animação de introdução Então, podemos realmente
fazer uso disso. Já temos nosso
movimento ativado. Isso sempre foi
verificado, então simplesmente não temos
feito nada com isso. Então, agora podemos pegar isso
da nossa classe base. Podemos definir isso como
padrão como falso, então não permitiremos que o
movimento comece. Então, se entrarmos e
apertarmos play, agora estamos completamente
presos, assim o inimigo, que é mais ou
menos o que queríamos. E é aqui que
era importante apresentar o sistema
de animação para você. Porque lembre-se, eu disse que
isso está nos dizendo todas as informações
enquanto as animações que
ainda estão acontecendo
estão sendo chamadas aqui E então,
assim que as animações terminarem, isso será chamado Então, agora podemos puxar
a partir daqui ou podemos simplesmente arrastar o
movimento B ativado. Isso nos daria
um setter aqui, e poderíamos definir isso como verdadeiro somente quando a
animação intra estivesse concluída Então, agora
podemos entrar e testar, podemos jogar. Não
conseguiremos nos mover
até que a animação
termine. Então, novamente, é totalmente opcional, mas apenas tentando
aproximar isso da maior paridade possível com o projeto
Example É um recurso que eles implementaram, então pensei em
abordar isso aqui. Mas é basicamente isso.
Está funcionando tecnicamente Como com qualquer coisa, eu
queria mergulhar um pouco
mais fundo com você. Definitivamente, essa é uma opção 100%, mas acho que é uma
coisa
muito, muito poderosa de se saber sobre os cronogramas e uma maneira
de manipular velocidade de
reprodução de nossa animação sem entrar no Agora, uma coisa que
eu acho que quero fazer, apenas uma última coisa a ajustar, é pegar o nó aqui e fazer
um movimento um pouco mais exagerado Ele vai meio
que acelerar e depois diminuir com
a animação Portanto, isso é puramente visual, mas oferece uma boa
liberdade sobre a suavidade ou nitidez de algumas
das animações Então, eu não quero que isso ultrapasse. Se tivéssemos uma curva como essa, ela realmente
ultrapassaria o ponto alvo, que seria
por aqui. Então, os pontos-alvo aqui, ultrapassariam
esse ponto alvo
e, em seguida, seriam animados de
volta ao ponto alvo Então, isso pareceria um pouco estranho. Vamos dar uma
olhada rápida. Na verdade, ficaria melhor se eu clicar em Simular. Você pode ver que o inimigo estava muito além do ponto-alvo
e precisava se animar de volta Portanto, tome cuidado para não
fazer nada parecido, mas eu poderia torná-lo um
pouco mais nítido, para que entrássemos um
pouco mais rápido um pouco difícil de
ver porque há
esse tempo de carregamento, mas provavelmente está tudo
bem. Agora, o que eu
queria apresentar, porém, é que, como mencionei, uma coisa que vejo
muitos desenvolvedores fazerem é
tentar isso e pensar
: Ah, na verdade, 1
segundo é muito rápido. Eu quero que essa animação
leve 3 segundos. Então, você precisa se
levantar, ajustar seu comprimento, pegar seus quadros-chave, mover seus quadros-chave e
brincar com as curvas Você pode ver como isso
vai ficar muito complicado, se você tiver que continuar
indo e voltando Então, não vamos fazer isso. Se você estava apenas
acompanhando,
pressione Control algumas vezes e
retornaremos o comprimento da curva para, ou seja, o
comprimento total de volta para um. O que podemos fazer
em vez disso, e esse é aquele truque que eu acho
muito poderoso com cronogramas, é que podemos
voltar aqui e talvez logo após definirmos
a localização e a rotação Podemos pegar nossa
linha do tempo. As informações são na
verdade,
transformadas em um componente Então, se colocarmos esse componente na seção de
variáveis, podemos pegar nosso Anim nos detalhes da
linha do tempo e
colocá-lo Então, obteremos as
informações sobre Anim em. A partir daqui, podemos
puxar e encontrar algo chamado taxa de jogo definida. Então, podemos ver que essa
é a taxa de jogo rapidez essa
linha do tempo está sendo E então, se conectarmos isso
aqui, agora temos controle
total porque sabemos
que normalizamos isso,
então fizemos isso de 0 a 1 segundo Se aumentarmos a
taxa de jogo,
digamos que trabalharemos com
números redondos simples. Vamos dizer dois. Agora está sendo reproduzido
duas vezes mais rápido, então
levará meio segundo,
porque se estiver
reproduzindo um padrão de 1 segundo, essa é a duração. Se estiver jogando duas vezes mais
rápido, obviamente vai jogar
pela metade Então, toda essa
animação agora será feita em meio segundo. Então, basicamente,
devido ao carregamento,
nem vemos isso acontecer. Eu precisaria simular. E sim, é quase
impossível ver. Mas se definirmos isso
para algo como 0,5, isso agora vai
levar o dobro do tempo, então vai levar 2 segundos. Então, temos uma animação boa, longa e suave agora, 2
segundos para eles entrarem. Então, agora temos, com algumas matemáticas
realmente básicas, controle total
sobre quanto tempo isso leva Podemos reduzir isso para
algo muito, muito lento, 0.1 ainda está fazendo
a mesma curva. Ele ainda está fazendo
a mesma animação, mas agora está levando
um tempo extra com base no que você faz com
a taxa de reprodução aqui. Espero que você possa ver o valor disso,
como mencionei Significa apenas que nunca
precisaremos
voltar à nossa linha do tempo Nunca mais precisaremos ajustar a curva porque
normalizamos isso para E se quisermos aumentar ou diminuir o tempo de reprodução
, podemos simplesmente pegar
esse valor aqui E acho que o que eu
poderia fazer, acho que 1 segundo provavelmente foi
um pouco rápido demais, então eu poderia definir isso para
algo como 0,75 Podemos clicar em
compilar e salvar, verificar novamente. Acho que parece
muito bom e suave, então estou feliz com isso. Mas, novamente, você pode definitivamente brincar, ajustar os valores E esse é o objetivo
geral desses tópicos, pois não estou fornecendo você um resultado
específico predefinido Estou tentando mostrar
todas as maneiras
diferentes de expor
e extrapolar
alguns dos valores e variáveis com os quais estamos trabalhando e realmente
tornar o projeto Então, se você quiser que eles sejam realmente rápidos e girem três vezes, você tem
controle total sobre isso com as variáveis aqui embaixo Você tem o
dramaturgo. E, novamente, provavelmente
também é um
bom momento para começar a
considerar a limpeza
do seu projeto Agora temos muitas variáveis. Então, talvez queiramos começar a
colocá-los em categorias. Temos alguns números mágicos, então também podemos começar a promover coisas
assim para uma variável. Poderíamos promovê-la para
outra variável, chamá-la de algo como graus de
introdução ou algo parecido. Tentando
deixar isso um pouco claro. É a animação de introdução e não especificamente a
rotação que queremos terminar, mas o número de
graus em que ela está rolando E aqui, poderíamos ter a taxa de reprodução da
animação, então vamos
promovê-la para variável também. Então, isso é bom porque
o principal, como eu sempre menciono
com variáveis, mesmo que não estejamos fazendo nada
específico com elas, é ótimo porque
não precisamos nos aprofundar em nosso código Sempre queremos evitar a
necessidade de entrar e
mergulhar em
partes codificadas de nossa lógica Em vez disso, se quiséssemos
tentar algo rapidamente, poderíamos simplesmente pegar
a base do avião agora. Podemos clicar em compilar,
garantir que tenha sido atualizado. Podemos pegar todas as variáveis e descobrir aqui
que podemos ajustar a taxa de jogo de qualquer maneira
e qualquer um dos valores com os quais
gostaríamos de
ver algumas mudanças rapidamente Como mencionei, o mesmo acontece com C plus plus, e isso
acontece em azul. Você acaba com
muitas variáveis, então talvez queira
começar a colocar as coisas em boas categorias lógicas
ou algo parecido, mas isso seria
algo para você fazer entre os tópicos. Outra coisa para você
entre os tópicos, uma pequena experimentação
aqui, porque
acabamos de dar uma olhada
rápida nas animações Definitivamente, recomendo
brincar com as coisas. Veja se você consegue fazer com que isso
seja reproduzido ao contrário depois de já ter sido reproduzido uma vez. Faça algo como
usar eventos personalizados. Lembre-se de como podemos criar
nossos próprios eventos personalizados, como podemos
chamá-los de qualquer lugar. Definitivamente, poderíamos conectar
algo para chamar reverso. Então, novamente, tentando evitar coisas como quando
isso terminar, você verá muitos
exemplos de código em segundo plano
e com esse tipo horrível
de lógica de loop aqui e com esse tipo horrível
de lógica de loop Seria muito melhor
ver algo como o evento personalizado que você criou, ter este chamado em código Então, se você quiser jogar ao contrário, algo
muito simples. Eu disse:
experimente você mesmo, mas acabei de mostrar
as respostas reais. Mas faça coisas
assim. Brinque com as diferentes propriedades e
recursos fornecidos por eles. Talvez faça com que ele pare no meio do caminho, reverta a partir de um ponto diferente, em jogo com curvas
diferentes, talvez ultrapasse propositalmente ou adicione quadros-chave
diferentes à animação
da curva
e veja o que acontece em e veja Talvez até mesmo adicione um pouco de escala. Assim, você pode fazer com que
pareça realmente caricatural com eles começando
em uma escala muito pequena, surgindo fazendo algum tipo de escala de animação
stretch de squash
e terminando em sua escala e terminando Comece a se
divertir e
brincar com as diferentes
opções disponíveis para você. Mas essas são as
animações de spawn completas. As naves agora entram
com estilo e, a seguir, falaremos
sobre o tremor da câmera e nossos efeitos de tela.
27. 26 — CameraShakeKnockback: não está pronto. Ainda há mais detalhes que podemos
adicionar a este projeto. Analisaremos as colisões
e
os tremores da câmera, garantindo que cada golpe
pareça importante Analisaremos a
retração um pouco mais tarde. Isso é um pouco mais prático do que
a trepidação da câmera. Começaremos aqui. Então, para começar,
vamos até nossa gaveta de conteúdo e nos
certificar de que temos nossa estrutura de
pastas configurada E dentro da pasta principal de
Blueprints, vamos criar
uma nova pasta aqui, chamaremos apenas de uma trepidação de câmera Podemos adicionar alguns tipos diferentes vibração
da câmera ao nosso projeto. Portanto, podemos ter algumas intenções
para as explosões, e talvez
outras mais suaves
para os projéteis
disparados ou simplesmente Novamente, depende
totalmente de você, dependendo quanto impacto você
deseja causar ao jogador. Para criar uma vibração de câmera, na verdade
precisamos de uma classe personalizada, que seja muito boa e
fácil. Nós clicamos com o botão direito. Podemos ir para nossa aula
de plantas aqui. Não tenho certeza de onde
está nas categorias,
mas, simplesmente, podemos
pesquisar a vibração da câmera. Você pode ver que, como o Epic New é
algo muito popular de
se adicionar a muitos jogos, eles realmente criaram
algumas classes personalizadas para trabalharmos. Queremos essa aqui,
a base de vibração da câmera. Temos algumas opções antigas e uma versão personalizada, mas
vamos trabalhar com versão básica rudimentar, clicar em Selecionar e
chamaremos isso de
BP Underscore BP Vamos clicar duas vezes para abrir isso
e, na verdade, não precisamos do gráfico de
eventos em
segundo plano aqui. Então, vou fechar
isso rapidamente porque uma maneira
muito simples de voltar à visualização somente de
dados em visualização somente de
dados em alguns Blueprints é
fechá-los e clicar duas vezes
para reabri-los E tudo o que realmente
precisamos ver são as propriedades de vibração da
nossa câmera aqui. Não
programaremos nada, então podemos simplesmente trabalhar com as
propriedades predefinidas fornecidas A principal coisa que queremos
mudar é que temos o
padrão de vibração da raiz definido como nenhum. Vamos deixar isso lá
embaixo e procurar por Perlin. Isso está fornecendo uma
boa randomização usando alguns padrões de ruído
Perlin pré-gerados Se você se lembra desses atalhos que mencionei há muitos tópicos, é
aqui que coisas
como segurar a tecla Shift e soltar as setas
aqui podem ser Então, se clicarmos
novamente com a tecla Shift pressionada, isso desdobrará
todas as categorias E se quisermos dobrar
tudo isso de volta, podemos segurar a tecla Shift e
clicar neles novamente. E, novamente, isso
os afasta muito bem. Então, como há tantas propriedades diferentes que
queremos acessar, vou
dobrar tudo, para que
possamos
examiná-las em ordem e descobrir o que, para começar, temos o multiplicador de amplitude
e frequência de localização Vou deixá-los de uma só
vez. Isso pega toda
a animação gerada e adiciona
um multiplicador
à amplitude e
frequência no X, no Y e no z
para a rotação, localização e campo de visão Isso é útil se quisermos
fazer algumas mudanças realmente grandes, mas geralmente queremos
trabalhar por ponto. Portanto, devido ao pequeno impacto que
estamos causando no momento, talvez toda vez que um
projétil atinja algo, queiramos que a câmera se mova um
pouco para frente apenas para mostrar que algum
impacto foi recebido Então, sabemos que
para frente é o X, então podemos pegar isso
e começar a adicionar alguma amplitude
à localização X. Se adicionarmos um valor de 200 aqui, isso é uma amplitude, um
tipo de força
que é aplicada. E então a frequência
é quantos solavancos para frente e para trás
isso Então, se mantivermos isso como
um, será como um único golpe toda
vez que um projétil atingir Você deve evitar adicionar
muita frequência em muitos casos, porque é
isso que fará com que as pessoas se sintam um pouco enjoadas Isso tornará um
pouco mais difícil ler e avaliar o que
está acontecendo na tela. Mas, novamente, tudo isso pode se resumir à preferência
pessoal, tipo de projeto e ao estilo
geral que você usava. Vou deixar isso
como um só para a frequência, e tendo isso em mente, podemos passar um pouco mais rápido para os outros eixos aqui Então, eu quero que isso
oscile de um lado para o outro um pouco mais, mas
com menos intensidade Então, vou definir isso para
40 e dez para a frequência. Novamente, dez pode ser
muita oscilação lateral,
mas ao vender isso
para algo maior, podemos voltar e refinar mais tarde, se
isso for Para a rotação,
vou deixar tudo isso como padrão. Muitas vezes,
não queremos girar a câmera,
o que é quase
mais do que qualquer outra coisa, que quase
certamente causará algum tipo de distúrbio no
feedback visual Você definitivamente sentirá algum
enjôo A menos que você tenha um
bom motivo para usá-lo e saiba
o que está fazendo. Então, vou deixar a
rotação completamente intocada. Semelhante ao campo de visão, você pode brincar
com eles se quiser, mas não quero
ajustá-los demais. O último detalhe aqui é a
mistura durante a noite,
quanto tempo eles levam
para atingir o pico
e quanto tempo leva para e quanto tempo leva passar do pico
para
não serem animados e, em seguida, Então, vou fazer
isso durar 3 segundos. Será um impacto
relativamente pequeno, mas durará por
um período razoável de tempo. Então, tivemos que compilar e salvar. Essa é basicamente a nossa configuração de classe de vibração de
câmera. Agora, com a configuração da
propriedade principal aqui, enquanto estamos fazendo isso, podemos também criar
algumas opções diferentes para descartar e
testar as coisas. Então, vou reduzir a vibração da
nossa câmera, pressionar control, na verdade,
para duplicar isso, e vou criar
uma chamada média Vou duplicar esse
e chamá-lo de grande. Então, talvez possamos ter
diferentes tipos de impactos, especialmente em coisas
como as explosões Eu provavelmente gostaria de um impacto um pouco diferente, mas muito maior porque, de qualquer forma, isso não acontece com
muita frequência, e então podemos alterar ou iterar entre os impactos pequenos e médios por
diferentes motivos Por um preço médio, eu vou
entrar aqui. aumentar
a amplitude para
algo como 500, talvez aumente a
amplitude no Y para 90, 15 na frequência. Novamente, sempre podemos
voltar e alterá-los se algum
deles for demais. Acabei de perceber
, na verdade, pensando em como eu
queria configurar isso. Em câmera shake small,
acho que queremos que a duração seja de
0,3, não de 3 segundos. Com duração de 3 segundos. Se você me
imaginar falando agora
são cerca de 3 segundos. A tela
teria oscilado durante toda a frase, que é um pouco demais. Então, vamos
compilar isso, reduzir
isso para 0,3 porque
não queremos superestimular
as pessoas visualmente . Então, podemos
fazer a mesma coisa aqui. Vamos definir isso para
0,3. Talvez possamos fazer isso de 0,4 porque
há mais tremores acontecendo. Pode haver motivos para que ele permaneça
por mais um pouco Então, vamos definir isso para 0,4.
A mesma coisa para grandes. Queremos que este realmente
tenha um grande impacto,
porque haverá a sensação de que está
bem perto da câmera
quando algo realmente explode, esses grandes
efeitos de partículas estão sendo Então, este
faz sentido , pode ser um
pouco mais forte. Então, na verdade,
vou mudar o multiplicador
geral aqui para
realmente dar um impulso a isso Então, vamos configurar isso para cinco
e, em seguida, a amplitude, eu vou configurar isso para A amplitude Y,
coloque isso em 160. Vou deixar
a frequência às dez. Não queremos muito que isso ande de um
lado para o outro. Acho que o prazo, novamente, talvez seja mais ou
menos definido para 0,5 segundos ou apenas dê a
eles pequenos incrementos, para que todos fiquem
visivelmente diferentes quando estamos fazendo nossa
reprodução Então, novamente,
não há certo ou errado. Posso ter atingido valores
muito altos, talvez até altos demais, mas sempre podemos
refiná-los e trazê-los de volta, dizendo que
definitivamente são altos demais. Eu disse 900, mas em até 9.000. Seria quase impossível ver
o que estava acontecendo, então vamos nos certificar
de diminuir o tom. Não diga isso muito alto. Portanto, não temos três
intensidades para testar e só precisamos implementar
isso em nosso código Tão bonito e simples, é um sistema
pré-construído pronto para nós. Vou voltar para a base do avião BP
Underscore. Vou mantê-los abertos caso
eu queira voltar e ajustar os valores
a qualquer momento Dentro da base de aviões da BP, uma das
mais óbvias a serem usadas primeiro seria a função de
morte Então, temos nossa função handle
Death. Ainda temos o que fazer aqui, se você
precisar encontrá-lo dessa forma. Então, eu tenho meu
comentário a fazer, e esse é o efeito final que
eu sabia que queria
voltar e implementar. Então, podemos retirar o pino
de execução aqui. Procuraremos
uma função chamada Play World camera shake.
Você pode ver isso aqui. Isso é muito semelhante
aos nossos três sinais D, ou
seja, nossos sinais direcionais e
até mesmo nosso sistema de partículas Então,
novamente, quando você começa a aprender como fazer um dos diferentes recursos do
Unreal, você também
entende um pouco como fazer as outras coisas,
se isso fizer sentido Então, temos aqui, por
exemplo, o epicentro, que é o local a partir do qual o
shake começa a tocar Então, de forma simples e simples,
vamos duplicar isso, obter
a localização do ator
e conectá-la Portanto, a vibração da câmera
deve começar a
partir da qual a nave Aber
acabou de explodir, e então ela meio
que rasgará a luz em direção à câmera, é
o
tipo geral de Fazemos isso com base em um raio, então o raio interno é onde isso será mais
forte Então, se a câmera estiver
ao lado do avião que explode, ela obterá toda a
força do avião que treme a câmera Então, vamos definir isso para algo
como 2.000 unidades de raio. E então, o raio externo
é onde qualquer coisa fora dessa zona provavelmente não será afetada pela vibração da câmera
ou, se estiver muito
próxima, poderá ocorrer o tipo final
de oscilação final E acho que vamos definir
isso para
algo em torno de 5.000 e, novamente, você pode brincar
com eles se estiver
acontecendo muito
ou muito intenso, você pode mudar o raio
e brincar com isso Como eu disse, para
as explosões, quando as naves reais estiverem explodindo, vamos
soltá-las
e
procurar o
sublinhado da BP, Cam Shake Lidge,
então esse será o tremor da nossa Cam Shake Lidge,
então esse será o tremor da Podemos clicar em compilar e salvar, e podemos apenas testar este
porque definitivamente temos a funcionalidade pronta para Ok, então foi isso que eu quis dizer quando algumas delas podem ser
um pouco intensas demais Então, isso vai
ser fácil de corrigir. Acho que o
rádio deve estar bom porque a câmera está
apenas verificando duas vezes. Se a partida do jogador for 130 no z e a câmera tiver
2.400 unidades no Z,
isso significa que, de qualquer forma, estamos
um pouco fora do raio interno de qualquer uma
das explosões Portanto, devemos ter
uma
trepidação
um pouco reduzida da câmera. O que podemos fazer. Acho que
talvez eu tenha ido direto para o multiplicador um
pouco alto demais. Mas, como mencionei,
essa é, na verdade uma abordagem muito comum para
esse tipo de coisa: dobrar, triplicar ou quadruplicar o que você acha que um
valor razoável pode ser e depois revisá-lo depois
de testá-lo Isso evita que você faça muitas alterações incrementais
muito pequenas que geralmente podem
levar ainda mais tempo Então, parece um
pouco melhor, talvez 1,5, para que possamos
fazer uma substituição maior, mas manter as
configurações gerais aqui iguais E eu acho que está
tudo bem. Então, não vou passar muito tempo refinando isso Isso agora pode ser assistido. Eu posso ver e
continuar jogando isso com Too Perturbed, então
vou deixar isso como está Então essa é a nossa grande vibração de
câmera e, novamente, você pode refiná-la
e
alterá-la completamente para se adequar ao seu
projeto conforme desejar Então chegamos à
questão dos nossos projéteis. Devemos fazer isso
tremer toda vez um projétil é disparado ou toda
vez que um projétil atinge algo ou Isso seria essencialmente um tremor
constante, que poderia ser
um tanto nauseante Então, acho que nesse
tipo de projeto, uma abordagem melhor
pode ser criar algo que
notifique o jogador de que
ele foi atingido, pois
dessa forma estamos aprimorando esse visual, mas na verdade o implementando
na jogabilidade Portanto, uma das
coisas mais irritantes para qualquer jogador de jogos com combate
envolvido é ser atingido, mas não perceber que
sofreu dano ou ser capaz de diferenciá-lo
do dano bronzeado do inimigo Então, isso meio que resolve dois problemas diferentes
porque, no momento, recebemos um pequeno
feedback se formos atingidos porque temos
picos em nossa nave Mas não está muito claro
se estamos perdendo danos ou saúde até
sermos destruídos. Então, isso pode ser um bom
tipo de solução para isso. Isso comunica que o
jogador está sofrendo dano. Isso não mostra que o
inimigo está sofrendo danos, mas ele está prestes
a explodir de qualquer maneira Portanto, não é tão
importante porque eles não têm muita
saúde pela qual passar. E ainda estamos dando esse feedback visual de
que as partículas estão impactando o avião inimigo Então, isso vai
ficar meio claro. Uma boa maneira simples de fazer
isso, então, com isso em mente, é ir
para
nossa aula de projéteis Queremos fazer
tudo
relacionado a projéteis na classe de projéteis Se você ainda não está
aqui, acontece
que eu estou ao lado dos
meus comentários para fazer, então vamos fazer
isso para fazer comentários novamente. E, na verdade,
vou ser um
pouco preguiçoso, como
fiz no passado Eu vou para a aula de avião. Vou pegar
todo esse código,
para obter a localização do ator
e a câmera do Playworld Pressione control em S para copiar isso. Enquanto estou aqui, também posso me
livrar desse comentário. Agora, na verdade, fizemos
toda a nossa lista de tarefas. Temos todos os efeitos
diferentes que vamos implementar,
então vou me livrar deles. E então voltaremos para a base do projétil, colocada no play
world camera shake, moveremos as coisas um
pouquinho E a lógica é muito parecida. Então, queremos fazer a
mesma coisa novamente. Queremos obter o local que o impacto acabou de acontecer e vamos
jogar a partir daí, no
mesmo raio, porque
ainda queremos que o mesmo tipo
de câmera caia Mas tudo o que vamos
fazer é talvez
verificar se o pequeno impacto é
grande o suficiente para começar, e talvez queiramos
mudar isso para médio. E isso é outra coisa.
Se você acha que isso não é impacto suficiente, tente alterá-lo. Então, cada golpe
dá uma sacudida, mas talvez nas naves inimigas, seja apenas uma pequena
sacudida, e na nave
do jogador,
seja uma sacudida média. Novamente, depende totalmente de você. Agora temos aulas diferentes. Você pode brincar com
isso e ver o que funciona. acho que, para o meu projeto,
vou deixá-lo apenas para indicar que os jogadores
estão sofrendo danos. Agora, há uma coisa para a qual precisamos abrir um
pouco de espaço,
e eu quero, novamente,
mostrar a vocês o tipo de maneira pela qual eu vi pessoas decifrarem seus códigos
acidentalmente Então, sabemos que
temos uma condição aqui. Só queremos que isso aconteça
se estivermos atingindo
a nave do jogador. Então, o que você pode fazer é
jogar um galho aqui, então vamos
fazer uma verificação do galho E queremos verificar. Já sabemos que estamos rastreando o
que estamos atingindo, então podemos pegar nosso ator
sobreposto Não acho que nada disso seja um conceito novo para você. Então, vamos duplicar isso,
então eu vou pegar meu ator de sobreposição,
certificando-me de que estou segurando aquele Pressione o controle,
na verdade, para duplicar. E queremos verificar se a
coisa que estamos sobrepondo, sabemos que não é o proprietário, já
superamos esse Mas se for igual a, e já
vimos isso antes, podemos usar o get PlayerPawn Então, se for igual
ao que está atualmente rastreado
como PlayerPawn, somente se isso for verdade,
queremos jogar o Então, nós apenas aumentamos um pouco
isso. E você provavelmente já
viu que esse não é exatamente o maior
problema ou problema a ser resolvido. Alguns de vocês já
devem ter visto, mas se isso não for verdade, se for falso, se
for outra coisa, estamos bloqueando
essa chamada de função aqui. Então, lembre-se de que isso é
algo com o qual você só precisa se familiarizar com
a ordem de operação, o controle de fluxo do seu código. Em C plus escrito, é muito mais fácil porque
usaremos declarações
FL que podemos simplesmente retirar de dentro do corpo
da função. Então, é muito mais
fácil acompanhar isso. No Blueprints, é muito fácil interromper
acidentalmente o resto
da funcionalidade quando
uma única
verificação de ramificação é feita Então, eu só queria
mencionar que, se você está seguindo esse fluxo que está apenas atualizando e melhorando seu
código ou adicionando recursos, é muito fácil acidentalmente, sempre que o inimigo for atingido agora, não nos
destruiríamos Então, algo que poderíamos
fazer em vez disso é, novamente, resolver tudo isso
com o uso de uma sequência. Então, se eu seguir em frente, e isso é apenas
para tentar enfatizar
a importância de
pensar na limpeza do código, não apenas para perder tempo e fazer com que o código fique
bonito no Blueprints, mas também porque isso literalmente facilita a leitura e a
manutenção e garante
que você não esteja
cometendo erros realmente
fáceis de cometer realmente
fáceis de cometer Então, se incluirmos nossa sequência
aqui e novamente, queremos
pensar nisso como
uma linha específica
de funcionalidade,
que, no nosso caso, é aplicar danos, e eu posso ficar tentado a fazer tudo o que não
está relacionado ao dano, tudo o que está relacionado
à reprodução de um efeito Vamos jogar
na então. Então, estou apenas pressionando Control X. E vamos
conectá-los Então, vamos
aplicar o dano primeiro. E então, se o dano for aplicado, reproduziremos
nosso efeito de partícula e
reproduziremos nosso tremor de câmera, mas apenas para o jogador E então vamos
fazer a última coisa. Então, novamente, isso nos dá uma
boa ordem de operação. Podemos ver a ordem exata na qual nossas funções
serão chamadas. E, como
mencionei anteriormente, quando analisamos as sequências, o que tornaria
isso um pouco mais claro é se você
fizesse esses Então, essa pode ser a linha de danos. Essa pode ser a linha de efeitos, e essa pode ser a linha de limpeza ou
algo parecido. E você pode se lembrar disso nos comentários Então, novamente, apenas uma mudança muito
rápida
e simples, e agora sabemos que, independentemente de isso
ser acionado ou não, definitivamente
sempre
destruiremos nosso ator porque,
uma vez verificado ,
se for chamado,
ele
voltará para a próxima parte
da sequência e voltará. Se isso não for chamado,
ele ainda
voltará para a próxima parte da sequência e depois
voltará para baixo. Então, o importante é que isso seja
chamado de qualquer maneira. Então, agora podemos entrar e
testar, e verificar novamente. Isso não está acontecendo
com os inimigos. Então essa foi a explosão.
Então, a outra coisa é que, se os projéteis
estivessem se atingindo, isso poderia ter causado o tremor da câmera quando
os projéteis também
se atingissem Então, agora eu
vou me deixar levar por
mais nada acontecendo. Lá vamos nós. Então você pode ver se eu não estou morrendo
ao mesmo tempo. Você pode ver que talvez seja um pouco
difícil ser atingido, mas você pode ver a câmera tremer, o
que é importante. Como mencionei,
isso pode ser muito sutil. Se for esse o caso, tudo
bem, porque
temos nosso shake médio
que podemos testar. Se realmente quiséssemos
deixar claro
que os jogadores estão sendo
atingidos. Lá vamos nós. Então, isso dá uma indicação muito
maior de ser atingido. Mais uma vez, pessoalmente, acho que o pequeno
está perfeitamente bem. Talvez queiramos adicionar um pouco mais de
força,
mas manter a frequência
a mesma ou algo assim, mas só para
avisar que eles
perderam a saúde, acho
que está claro o suficiente. A próxima etapa será abordar coisas como materiais e criar um material intermitente que
cause danos à saúde ou algo assim, se você realmente
quiser visualizar Mas acho que isso
já é um grande avanço relação ao que tínhamos antes
, porque está apenas tornando as coisas um
pouco mais visuais e um
pouco mais claras O fato é que vamos
adicionar rapidamente uma simples reviravolta quando aviões colidirem
uns Para este, queremos
lidar com isso apenas
na classe de jogadores, porque essa é a única que está fazendo uma pseudofísica Então, vou fechar
todas as outras guias. Acho que terminamos com
os tremores da câmera e vamos entrar no player de avião de
sublinhado da BP E dentro daqui,
o que queremos
fazer é
pegar aquela esfera. Vamos
até a
seção de colisão no painel de detalhes e
vincularemos a função on component hit aqui, como
fizemos no passado E vou manter isso
muito bom e simples. De qualquer forma, acho que
é
o mesmo projeto de exemplo, que podemos ricochetear
nos inimigos e nas paredes Então, sempre que
atingimos algo, não precisamos
verificar o que é. Vamos apenas pegar
nossa velocidade de movimento atual e
multiplicá-la por um valor negativo com
um pouco mais Faz com que o jogo pareça
divertido e dinâmico. E o mais importante, novamente, basta dar ao jogador o
feedback de que você está realmente tocando em outro objeto
no mundo que tem
alguma permanência Então, vamos obter a velocidade
atual, como mencionei. Vamos multiplicar isso por um valor negativo mais um pouco porque não queremos
simplesmente invertê-lo. Queremos adicionar uma pequena
repulsa forte. Então, digamos que -1,5. E seja o que
for, vamos então ajustar
a
velocidade atual de volta para aquela. Obviamente, isso está
sendo explicado no larping de qualquer Então, a interpolação larping, que está acontecendo com nossa função
geral de movimento, tentará pegar nossa nova velocidade de movimento
e, em seguida, suavizá-la de
volta à velocidade normal que suavizá-la de
volta à velocidade normal deveria estar indo e na
direção em que estamos Então, isso não vai parecer
muito desagradável, eu acho. Outra coisa que
poderíamos fazer aqui, embora estivéssemos fazendo muitos tremores de câmera, de
qualquer forma, pensando nisso E, novamente, completamente opcional, mas é algo que
vou tentar. Eu vou entrar na base
do projétil. Vou copiar o código
aqui, a vibração mundial da câmera, colar isso aqui, e
talvez façamos uso da vibração média da câmera,
então vamos deixar isso abaixo. Mesmo raio, mesmo Apicentro, e podemos simplesmente entrar e apertar
play Não, definitivamente é muito pesado,
eu só estava pensando
que poderíamos tremer
um pouco quando
o salto acontecesse um pouco quando
o salto acontecesse Vamos tentar fazer isso com os inimigos. Tem
muita coisa acontecendo lá. Então, novamente, tentativa e erro, isso pode ter funcionado. Talvez
eu tenha parecido muito legal, mas não funcionou. Talvez possamos fazer
uma pequena sacudida. A principal coisa que queremos é
garantir que ricocheteemos contra
os inimigos também
ricocheteemos contra
os inimigos. Então,
vamos verificar novamente. Tão bem pulando na parede. Quicando no inimigo.
Acho que os inimigos estão sofrendo muito
dano com nosso tremor. Eles deveriam saber
que foi um golpe, não
é? Tudo bem. É o jogador que
morre após dois golpes. Então, sim,
tudo bem com o diabo. E então, se você está se perguntando por que isso não afeta
os projéteis momento, ainda podemos ser atingidos por projéteis, mas não
estamos quicando Estamos apenas
pulando nas paredes
e nos inimigos, o que eu
acho muito legal A razão para isso é
voltar à nossa configuração de colisão. Então, espero que isso ajude toda
a estrutura de colisão a
fazer mais sentido também Portanto, lembre-se de que nossa esfera
no jogador está configurada para bater. Portanto, ele está apenas
verificando colisões físicas com outros objetos físicos Então, isso é fazer uma verificação de
sucesso aqui dentro de nosso
jogador e de nossos inimigos. O projétil, embora
pareça relativamente semelhante, meio que o mesmo, isso é fazer um tipo diferente
de verificação, lembre-se Isso é definido como um colisor de
sobreposição. É por isso que é
útil pensar em como você vai configurar
seus diferentes aceleradores Isso significa que você pode
obscurecer completamente os diferentes tipos de configuração de colisão para reagir e responder às diferentes
contrapartes de maneiras Isso significa que não
precisamos nos
preocupar com os projéteis,
causando qualquer empurrão ou tipo
de empurrão
físico para de empurrão
físico Eles estão
literalmente voando pelo espaço. Eles não estão
fazendo nenhuma física. Eles não estão
colidindo fisicamente com as coisas. Eles estão apenas verificando se há mais
alguma coisa
no mesmo espaço. E se outra coisa
acabar no mesmo espaço,
tudo o que ela está fazendo é
tentar causar dano, tentar produzir alguns efeitos
e depois se destruir É por isso que podemos
escapar impunes. E, novamente, é claro,
os limites de nível são configurados com a
mesma colisão, então eles são configurados para bloquear os inimigos e
o jogador Então é isso. O
projeto está polido. Acho que agora parece muito mais interessante
interagir com isso. Ele fornece uma
experiência
um pouco mais animada e interessante para interagir Novamente, muito disso
se resumirá ao refinamento. Não espero que você
saia do projeto, pois já dei
essas etapas até agora Se você não gosta nem um pouco da vibração da
câmera, ou acha que
pode fazer isso um
pouco mais, tudo bem Adicione, remova e altere
todas essas propriedades
conforme achar melhor. E isso é apenas
algo para você testar e experimentar entre os tópicos e realmente começar a trabalhar
com o projeto. E crie novas
classes de vibração da câmera se você puder ver um caso de uso de
algo que treme com mais frequência
ou menos frequência, mas com mais
amplitude, por exemplo O principal é que
cada impacto seja
adequado ao feedback que o jogo está tentando enfatizar. E é isso que fará com seus projetos deixem de parecer um
tipo de jogo iniciante muito amador para algo que tenha um
pouco mais de reflexão, cuidado e atenção
aplicados a todos
os diferentes elementos com os o jogador
interagirá Outra coisa que você pode tentar
é experimentar a onda em vez
da pérola no ruído enquanto a câmera treme e qualquer um dos outros tópicos que
eu meio que mencionei, mas não teremos tempo de nos
aprofundar em cada ressalva de todos os diferentes processos Feito isso, porém,
temos nossa sacudida, recua. O peso e o impacto
do campo estão ficando
bem reais agora, que deixa o fim da
criação de uma interface de usuário para lidar com todo
o ciclo do jogo. No momento, os jogadores
ficam meio que presos em um vazio infinito se
forem destruídos, e obviamente não
queremos que seja esse o caso
28. 27 — UI: Ok, então estamos
no tópico final. Essa será
a tela de fim de jogo, a interface do usuário, fornecendo um sistema de reinicialização
e uma saída adequada. Idealmente, teríamos
alguns botões para pressionar. Mas vamos manter
essa interface de usuário agradável e simples. Você termina. Você pode pressionar o botão I para reiniciar e depois voltar ao jogo. Em um projeto maior, talvez
você queira adicionar uma tela de menu ou
algo parecido. Mas com isso, você terá um jogo
completo e jogável. A primeira coisa que
queremos analisar é o conceito de widgets Portanto, o UnrelEngine lida com sistemas de
menus e
sobreposições de interface de usuário, pressionamentos de botões
e coisas assim por meio de algo
chamado
classe Então, dentro da nossa estrutura de
pastas, vou criar
uma nova pasta, e vou chamá-la de widgets ou UI Muitas vezes, você verá
isso como um desses dois quando estiver examinando os projetos de
outras pessoas. Dentro da minha pasta Widgets, queremos clicar com o botão direito do mouse aqui Vamos
para a Interface do usuário. Podemos ver aqui que
temos a opção um blueprint
de widget Portanto, ainda existem classes de
blueprint, mas isso só
nos permite colocar uma espécie de interface
visual com
algum código vinculado a ela Selecionaremos essa
opção aqui e criaremos um widget de usuário padrão Em seguida, clicaremos em Selecionar e daremos a ele o nome de WBP
para Widget Blueprint Vamos clicar duas vezes para abrir isso, e você verá que o
layout é um pouco diferente. A primeira coisa é observar que
no lado direito, canto superior direito,
temos duas guias diferentes Temos a guia de designer,
que é onde estamos agora. Isso fornece um layout
visual e um
sistema de tela muito bom para arrastar e soltar elementos diferentes para
configurar a forma como isso
será exibido na tela. Em seguida, temos o gráfico, que é nosso editor de diagramas padrão, muito semelhante ao que você viu antes, com apenas
algumas pequenas nuances Ainda no elemento
designer aqui, vamos para
o lado esquerdo e queremos algo
chamado sobreposição
dessas diferentes categorias. Você pode ver que existem muitas
categorias diferentes, então vou apenas
pesquisar por sobreposição E isso é essencialmente
um painel para
colocarmos todas as outras coisas
importantes. Então, vamos inserir isso
, e você pode ver aqui que esta é a nossa
sobreposição na tela Só queremos ter certeza de que
este é um painel de 19 por 20. Então, podemos arrastar isso
e colocar isso. Eu só preciso me dar
um pouco mais de espaço. Podemos soltar isso e
ver que meio que se encaixa clicando nos limites aqui, e isso
se encaixará Portanto, temos um painel
padrão de 19 por 20. Agora, eles serão
configurados para serem dimensionados e alterados com base na tela em
que estão sendo colocados. Mas vamos usar o padrão, supondo que estejamos em uma tela de 19 por 20, e possamos trabalhar com base nessa premissa Em seguida, também podemos
adicionar um bom tipo
de visual a isso. Então, podemos pesquisar
algo chamado painel de desfoque ou desfoque de fundo, e
vamos simplesmente colocar isso aqui Podemos ver que a
hierarquia aqui, a sobreposição, é onde tudo meio que será colocado, e então o desfoque de fundo
é filho da Podemos ver se aumentamos o zoom. O desfoque de
fundo é
um pouco pequeno Acharemos
um pouco difícil
ver se pressionaríamos
Play e mostraríamos isso. Então, o que queremos fazer é,
no lado direito, alinhar isso
à nossa sobreposição Então, se pedirmos para
ocupar, preencher todo o espaço horizontalmente
e preencher todo o espaço verticalmente, você pode
ver que agora corresponde ao tamanho do componente pai,
que é
a Para a intensidade do
desfoque, vou pegar esse valor aqui
no painel de detalhes e atribuir a ele uma intensidade de
desfoque de 15, e podemos ver que isso adicionou
um leve desfoque ao nosso painel, que acho que ficará muito bonito,
meio moderno e proporcionará meio moderno e proporcionará um pouco de Em seguida, queremos
ver como podemos formatar o texto que queremos
mostrar na tela. Então, vamos mostrar
algo assim, apenas um simples texto
dizendo fim de jogo
e, em seguida, uma dica
de ferramenta sobre como reiniciar. Uma boa maneira fácil de gerenciar
vários elementos em uma única área em um menu
seria usar algo como uma
compra horizontal, se você quisesse que as coisas se
estendessem horizontalmente pelo
widget ou uma Nesse caso,
vamos ficar na vertical. Portanto, se procurarmos
uma caixa vertical, podemos colocá-la e garantir
que seja
uma consequência da sobreposição e
não do desfoque do fundo Para o alinhamento
deste, você pode ver que está
ocupando a caixa inteira Em vez disso, vamos
definir isso como linha central
para as configurações horizontal e
vertical aqui. Está perfeitamente
bem. Podemos fazer essa escala para os elementos internos um pouco mais tarde. Os elementos, como mencionei, serão muito,
muito simples para isso. Vamos apenas dar a
isso um elemento de texto, então vamos
pesquisar um texto e soltar nosso primeiro
elemento de texto na caixa vertical. E você pode ver que
realmente saiu da caixa vertical para
caber
no Para o
texto inicial, vou
configurar isso para dizer GameOver Então, com o texto selecionado, queremos encontrar nossa opção de
texto aqui. Você pode ver que no momento está
dizendo bloco de texto, e vou
mudar isso para fim de jogo. Altere o tamanho da fonte. Então, no momento, se
colocarmos nossas
propriedades de fonte aqui, o tamanho é 24,
e acho que um tamanho de cerca de 50
seria ideal para este. Podemos mudar o tipo de letra. Roboto bold geralmente parece
um pouco desagradável. Podemos simplesmente mudá-lo para normal ou até mesmo a luz pode
ficar bem bonita. Parece um pouco mais limpo. Isso agora
não parece muito impactante. Talvez queiramos alterar
o tamanho da fonte para algo como 60 para que pareça e soe um
pouco melhor. Agora, com esse texto
selecionado, podemos pressionar. Então, vamos pegar
isso aqui
no lado esquerdo ou
duplicar nosso texto Portanto, controle, de fato,
para duplicar. E você pode ver
que, como está dentro dessa caixa vertical, agora está
se certificando de que
ela esteja alinhada verticalmente E se continuarmos adicionando elementos de
texto, teremos esse bom alinhamento
em uma ordem vertical Portanto,
isso torna um pouco mais fácil gerenciar e trabalhar com vários elementos quando
você deseja que eles estejam aproximadamente alinhados uns com os
outros no mesmo lugar. Agora, para este, vou
pegar o novo elemento de texto ou alterar o texto para
dizer pressione R para reiniciar. Provavelmente não é o game
over tela mais
interessante , mas
transmite a ideia. Vamos mudar um pouco o
tamanho disso. Não precisa ser muito
impactante quando o jogo termina. Então, vamos dar a isso
um tamanho de fonte de 30. Também poderíamos dar a eles
um pouco de preenchimento. Então, se eu pegar o GameOver, em
primeiro lugar, no painel de
detalhes à direita, podemos dar a ele um
título padrão de, digamos, dez, para que fique um pouco
mais complicado E podemos fazer a mesma coisa
pressionando R para reiniciar. Também vamos dar um
pouco de limite a isso. E o principal é que queremos que
isso seja alinhado ao centro. Assim, podemos pegar o alinhamento
horizontal e garantir que
ambos estejam alinhados ao centro Então, eles estão meio que colocados
no meio da caixa
vertical, bem arrumados, e não
precisávamos trabalhar muito Outra coisa que você pode
querer fazer é mudar um pouco as cores visuais. Para que pudéssemos terminar o jogo. jogadores que terminam o jogo
normalmente são representados com vermelho, laranja ou
algo parecido, então podemos mudar
a cor aqui para uma cor um pouco mais
negativa, fazendo com que ela se destaque
da entrada aqui Parece um
pouco mais interessante porque temos
mais coisas acontecendo. algumas passagens
mais sofisticadas Talvez você queira
fazer algumas passagens
mais sofisticadas:
você pode usar suas
próprias fontes com muita
facilidade para desenrolar
e, em seguida, basta alterar a fonte
que deseja usar
para torná-la um
pouco mais personalizada Brinque com coisas como
a ousadia, o tamanho da fonte. Você pode até adicionar
coisas como contornos se quiser
enfatizar certas partes Então, se eu apenas ampliar
um pouco. Eu poderia adicionar um
contorno de dois pixels ao redor e obteríamos um contorno elementos do nosso menu aqui Então, o que quer que você queira
fazer para tornar isso um pouco mais
interessante, como eu disse, vamos
manter isso
simples e simples apenas para mostrar
que o jogo acabou e dar ao jogador
uma dica sobre o que ele pode fazer a seguir. Então, vamos
voltar brevemente
ao sistema de entrada porque agora precisamos que algo seja
acionado quando essa interface de usuário
for exibida na tela. Então, se voltarmos ao
nosso sistema de entrada, basta recapitular o que temos Já temos nossa chave de reinicialização. Agora, como mencionei, em um jogo
completo em que você tem um
sistema de menu
mais complexo e coisas assim. Você pode ter diferentes classes de contexto de
mapeamento de entrada. Nesse caso, limitamos
tudo a uma única jogabilidade, e acho que está tudo
bem porque não temos nenhum uso sobreposto, então se você quisesse
usar, por exemplo, o botão Voltar em um gamepad, então B no gamepad, para ser uma entrada como pular, mas você também queria
que
fosse o botão de reinício, talvez você
queira compartilhar isso . Portanto, se você estivesse em um menu, B seria mapeado para reiniciar Assim, você teria seu contexto de mapeamento de
menu. E então, quando você está no
jogo e era pular, você teria seu contexto de mapeamento de
jogabilidade. Nesse caso, acho que apenas usar este
seria perfeitamente adequado. Então, vamos
voltar ao nosso GameOver e só queremos fazer aquela encadernação que
fizemos anteriormente Então é aqui que entra o
lado do código do nosso menu, e é aqui que parte da flexibilidade
muito interessante
do sistema de entrada aprimorado torna coisas assim muito
mais fáceis do que costumavam ser. Definitivamente, era possível
com o sistema antigo, mas isso é
definitivamente um avanço. Navegaremos até
o gráfico aqui, e eles são bastante semelhantes
aos que vimos antes. Portanto, temos uma
marca de evento e, nesse caso, não
faremos
nada em nosso menu, então podemos nos
livrar disso. Portanto, a construção do evento é essencialmente a
mesma do início do jogo. Isso acontecerá
assim que o jogo começar e o menu
surgir Então, quando mostrarmos o
menu na tela
, serão cinco uma vez. Pré-construção, você precisa ter
um pouco de cuidado. Isso é útil para alterações no
editor. Portanto, poderíamos codificar
coisas para que
pudéssemos receber atualizações ao vivo do editor, mas você precisa ter cuidado
aqui, pois se estiver referenciando outras classes ou fazendo coisas fora
do menu, isso pode causar problemas se
você ainda não estiver no modo de jogo Então, para evitar confusão, vamos nos
livrar dessa, e vamos pensar nisso
como nosso objetivo em Começar a jogar, o que queremos fazer ou
construir um evento é voltar ao controle do
jogador e fazer
exatamente o que fizemos anteriormente. Queremos encontrar o subsistema aprimorado do player local de
entrada Este aqui com o ícone de função
roxo rosado logo E, novamente, da mesma forma que
fizemos antes, vamos adicionar
o contexto de mapeamento. Então, várias classes podem ter
o mesmo contexto de mapeamento, então vamos ter
o contexto de mapeamento agora em nossa classe de jogador, que está manipulando a entrada
para se movimentar e disparar Podemos adicionar esse mesmo
contexto de mapeamento ao nosso menu. Então, quando isso for gerado, ele também rastreará os pressionamentos de botão
relevantes Agora, nesse caso, tudo bem porque o pressionamento relevante do
botão será apenas
uma reinicialização do
sublinhado IA Então, podemos clicar com o botão
direito aqui. Vamos procurar por IA underscore restart Queremos o evento novamente,
então, quando algo acontece, obtemos o arquivo pin de execução
de quando ele é pressionado. Nós simplesmente queremos recarregar o nível em que estamos atualmente
e estamos apenas
reiniciando o jogo Nós só temos um nível, então
isso é bom e simples. Há uma função que
podemos usar para fazer isso, um recurso embutido no Unreal Podemos usar o nome do nível get
current. Então, essa função aqui,
conecte-a para começar. Então, novamente, quando
pressionado uma vez, isso retornará o nome
do nível em que
estamos atualmente,
que, lembre-se, é chamado
apenas de principal. Então, poderíamos fazer isso
codificado e simplesmente digitar o nível principal do nível
que estamos prestes a recarregar Mas caso você
comece a adicionar mais níveis ou alterar
o nome, essa é,
novamente, uma maneira agradável, dinâmica e reutilizável de
implementar Então, uma vez que
tenhamos isso, vamos extrair daqui, e vamos
pesquisar o nível de carga da função, e vamos
procurar a função aberta. Pode ver a opção aqui,
abrir nível por nome. Agora, obtemos duas variáveis ligeiramente
diferentes, então temos o
nome do nível atual retornado como uma string e temos o nível
de carga retornado que deve ser inserido
como uma variável de nome. Perfeitamente bem. Novamente,
podemos simplesmente conectá-los. Ambos são um tipo
de texto, essencialmente, e o irreal fará
essa conversão para nós Então, isso
pegará o nome atual do
nível em que estamos principais e abrirá o
nível com o mesmo nome. Então, estamos apenas
reiniciando nossa direita, o outro problema que
acabei de perceber aqui é que não temos
como sair do jogo Algo que eu
realmente estou tentando ajudar aqui é não fazer
com que pareça um
jogo completo para iniciantes ao final desse processo Uma coisa que descobri
ao testar e demonstrar jogos de
novos desenvolvedores é que você geralmente fica preso
no jogo deles e precisa pressionar F para
fechar o painel Portanto, enquanto
analisamos a entrada, também
podemos nos
livrar desse problema O que
vou fazer é duplicar a reinicialização do
sublinhado do IA Vou renomear
este para sair. Dentro do
sublinhado principal do IMC, queremos apenas
adicionar um novo Então, sabemos que restart é
um booleano, uma entrada binária. Portanto, também já saímos do set
como booleano digital, o que é perfeito Então, no IMC Underscore main, vamos adicionar
um novo Vamos abrir essa
opção e selecionar o botão sair. Portanto, para testar no editor, isso é um pouco
complicado porque, por padrão, escape é mapeado para
finalizar a reprodução Então, se
estivéssemos jogando e testando, não conseguiríamos testar. Sem desativar nosso
sistema de menu ou nosso botão rápido. Então, eu vou dar isso.
Mas se fôssemos empacotar isso e entregá-lo
a outra pessoa. Eu quero a chave de escape apenas
para fechar o projeto. Não haverá menus, não
haverá pop-ups apenas uma maneira rápida de
fechar o projeto,
então, pelo menos, eu não fico preso depois de construir
o projeto. Para testar o editor, o que eu geralmente faço é usar outra encadernação
e configurá-la
para
algo realmente aleatório que, e configurá-la
para
algo realmente aleatório que outra forma,
eu não estaria
pressionando na minha jogabilidade. Então, eu posso definir isso
como a chave de exclusão. E isso significa
que o que eu posso fazer é voltar para minha classe de jogador. Então, vou entrar no núcleo
do jogador de avião. E, novamente, estamos nos
afastando um
pouco das formas ideais de
configurar isso agora. Em um projeto real, você provavelmente
faria isso dentro de um controlador de player
ou em sistemas de menu diferentes, mas não estamos nos
aprofundando na criação de sistemas de menu completos. Então, vamos colocar isso em nosso sistema de entrada aqui. Então, temos nosso
gráfico de entrada. Ainda estamos mantendo as coisas bem
arrumadas, pelo menos Isso ainda está dentro do
nosso sublinhado principal do IMC. Isso significa que todas as nossas novas ligações
ainda estão sendo E o que podemos fazer é fazer com que o sublinhado do IA seja encerrado. E quando esse botão é pressionado
, queremos o evento novamente. E quando esse botão é pressionado, então iniciado, queremos apenas
chamar a
função embutida, que é sair. Jogo tão rápido. E
isso fechará
automaticamente a
instância do jogo para você. Então, se clicarmos em compilar e salvar, podemos testar isso imediatamente Lembre-se de que no modo play, se eu pressionar Escape, ele
teria fechado de qualquer maneira. Então, vou pressionar
a tecla delete e a reprodução acabou de Então, isso funcionará para
nossa versão empacotada, bem
como para nossa versão de
editor aqui Portanto, não precisamos fazer mais
nada aqui. E eu só queria apresentar a
você a funcionalidade rápida,
porque, como mencionei, é muito fácil ignorá-la, mas é muito, muito
simples de implementar E é apenas uma
daquelas coisas que faz seu tipo inicial de sentimento
e avaliação de um jogo que você está jogando
dê um passo adiante e faça
você se sentir como se estivesse jogando um jogo feito por alguém com um pouco
mais de experiência fim, queremos que
essa interface de usuário apareça quando o jogador morre. Sabemos exatamente quando isso
acontece porque temos nossa função de lidar com a morte
dentro da classe do jogador. Então, com isso,
vamos encontrar nossa função de lidar com a morte. Queremos ir para Override, e queremos
encontrar Dyna Queremos ter certeza de
que ainda estamos chamando todas essas coisas importantes para
pais, para que nosso efeito e tudo
mais estejam sendo tratados Mas pouco antes que
isso aconteça, ou talvez sim, pouco antes de isso
acontecer, porque estamos chamando Destroy
na versão principal, queremos aparecer em
nossa interface de usuário E podemos fazer isso de forma
muito simples, então vamos extrair
daqui e encontrar uma função chamada Create Widget Então, essa é uma função para criar um dos nossos widgets de blueprint Podemos inserir isso
aqui e queremos encontrar nosso jogo de sublinhados do WBP. Agora, novamente, vou
fazer uma pequena observação
sobre isso
só porque você ficaria surpreso com
quantas pessoas esquecem a próxima etapa importante. Parece que isso deveria funcionar. Mas se eu entrar rapidamente e permitir que meu avião seja destruído, chamaremos essa função, forneceremos a ela o widget
certo, mas não
o veremos na tela Então, novamente, coisa muito comum. Mesmo que
pareça que isso é tudo o que
precisamos fazer. Na verdade, há uma etapa extra. Queremos retirar
esse pino de retorno. Então, isso é criado
em segundo plano. Há um widget de fim de jogo que meio que permanece na
memória Queremos pegar essa
referência e memória e dizer
adicionar ao ponto de vista Uma função especial chamada
Need to Make aqui, e depois vamos
conectar tudo isso. E agora, isso vai
realmente funcionar. Então, se entrarmos e
apertarmos play novamente, faça com que meus aviões sejam
destruídos e pronto. Então isso criou esse menu, mas também o adicionou
ao ponto de vista Se eu pressionar R, teremos
essa vinculação no menu, então agora também temos uma
reinicialização. Assim, podemos entrar e
reiniciar o jogo com
muita facilidade agora. Vamos acabar
com a mesma coisa. E se eu pressionar Delete,
algo que eu esqueci lá. Eu ia dizer que, se eu
pressionar Delete, posso sair. Não posso porque os
jogadores foram destruídos. E lembre-se, nossa obrigação
de desistir está no player. Então, talvez queiramos
fazer um pouco de duplicação. Vamos
encerrar
nosso sublinhado IA e a função de encerramento do
jogo aqui Não vamos
removê-lo aqui. Queremos isso nos dois lugares.
Vamos voltar ao fim do jogo, só vamos
colar isso aqui. Então, quando o
jogador é destruído, ele não existe mais. Obviamente, não podemos
sair do jogo. Então, em vez disso, vamos mover
essa funcionalidade para
o
widget GameOver Então, é perfeitamente normal fazer isso. Apenas certifique-se de que
o jogador ainda morra. E agora, se eu pressionar
delete, podemos fechar o jogo. Então, a mesma funcionalidade,
sempre precisamos considerar que, se algo
foi completamente removido do jogo, completamente removido da memória, precisamos garantir que todas as
funções relevantes ainda estejam
disponíveis em outro lugar. E, novamente, se você descobrir, como quando eu estava vendo isso, sinto como se tivéssemos bastante espaço
na tela. Então, acho que o que eu poderia fazer são apenas alguns pequenos ajustes para
talvez fazer com que isso seja realmente grande, o
dobro do tamanho do nosso jogo E então dobre o tamanho
da nossa ponta de ferramenta aqui. Portanto, não é nada importante, mas
é só voltar, basta preencher um
tipo geral de preenchimento e fazer com que tudo pareça o melhor
possível, tentando apresentar o
jogo da melhor maneira possível. Então, sim, provavelmente há um tipo de estilo
geral
muito melhor. Pressione para reiniciar, tudo está funcionando. Tão perfeito. Acho que, para um projeto iniciante, um tipo muito simples de remake
de algo que existe, mas tentar
expandir e melhorar, especialmente a
base de código sempre que possível, mas também o feedback geral, o preenchimento
e os visuais,
será um bom tipo de
ponto de aprendizado e um passo
na direção certa para Mas isso é
basicamente um resumo disso. Então, mais algumas coisas
para você aprender
nesses pontos de aprendizado. Você pode jogar, atirar em
inimigos, ser atingido, morrer, tela de fim de
jogo
aparece e você pode fazer tudo de novo.
Tudo parece muito bom. Temos uma espécie
de interface de
usuário simples, de aparência
moderna e semidesfocada usuário simples, de aparência
moderna Você pode pressionar escape ou excluir e fechar o
jogo de qualquer lugar. Então, novamente, não estamos
fazendo com que pareça um projeto completo de novato em que você está preso e
precisa alterar o F quatro do projeto de fim de
semana de alguém Então, espero que seja
uma boa melhoria
em relação ao que você também pode
ter visto Portanto, temos um loop de jogo
completo. Podemos jogar, morrer,
reiniciar e sair. Então, ao longo de
todo esse tempo, passamos de um
projeto vazio para um jogo completo, movimento com
independência de estrutura, projéteis, materiais
dinâmicos,
inimigos com herança
e uma breve visão e uma breve Temos geradores
com randomização, garantindo que eles tenham sido
criados de forma genérica,
mas genéricos de uma
forma boa, pois podemos criar a classe uma vez e usá-la
para Examinei partículas, áudio, trepidação
da câmera,
retrocesso e agora a interface Então, espero que essa seja
uma boa base. Você pode construir sobre isso. Como mencionei,
seria ótimo se você adicionasse alguns inimigos únicos, tentasse dar a eles diferentes padrões de
movimento, padrões de armas
diferentes, talvez os acelerasse e os
tornasse inimigos kamikaze
com projéteis conhecidos O que quer que você esteja sentindo
sobre suas etapas extras para tornar este projeto único. Traga alguns recursos novos e compartilhe seu progresso e
atualizações com outras pessoas. Também poderia adicionar coisas
como pontuação, que seria muito fácil de fazer por meio da função de
controle compartilhado de morte Sabemos exatamente quando
os inimigos estão morrendo, então você pode
aproveitar isso e criar algum tipo de sistema de pontuação Então, realmente torne este
projeto seu. Pegue referências
de outros jogos, veja os exemplos de conteúdo
e eu definitivamente recomendo
que, neste momento dê
uma olhada
nos exemplos de conteúdo. Dê uma olhada no mapa de
entrada do blueprint e veja exatamente
de onde esse projeto foi inspirado e compare o código que você tem com
o código desse projeto E, novamente, isso não é
para julgar, mas apenas para ver
que sempre há maneiras
diferentes de
abordar um único problema. E veja qual é a sua
opinião sobre o que
temos em relação ao projeto
original. Mas o importante
é que agora você criou um jogo, e
isso não é nada. Isso é uma conquista, ainda mais se você
está dando esses passos extras e realmente sente que está começando a entender pelo menos um pouco do que pode fazer
dentro do Unreal Algumas dessas coisas exigirão um
pouco de repetição. Talvez você precise voltar
e tentar novamente, mas ser capaz de ajustar e implementar esses
recursos sozinho é, na verdade, o
primeiro grande obstáculo de aprendizado que eu acho que muitas
pessoas enfrentam. Então, obrigado por
acompanhar com seriedade. Se você chegou até aqui,
eu realmente
agradeço por dedicar seu tempo a
algo que ajudei a criar Mas eu vou e continuo fazendo coisas. Esse é
o ponto principal aqui.