Behaivor Tree
Em este passo iremos implementar os elementos necessários para controles de movimentação do NPC.
1. Objetos de controle
Devemos usar as classes Blueprints:
-
BP_NPC_Controller do tipo
AIController
; -
BH_NPC do tipo
Behaivor Tree
; -
BB_NPC do tipo
Blackboard
;
A estrutura de controle das classes é a seguinte: O Character tem como controlador o AIController
que executa a árvore Behaivor Tree
a qual utiliza o Blackboard
para a armazenamento de variáveis.
2. Blackboard
BlackBoard permite que você armazene informações em chaves que podem ser usadas pela Árvore de Comportamento.
Para criar o objeto utilize Menu de Contexto
> Artificial Intelligence
> Blackboard
.
Variável | Descrição |
---|---|
SelfActor | Key type : Object e Base Class : Actor que representa o próprio ator; |
EnemyActor | Key type : Object e Base Class : Actor para referenciar o jogador; |
HasLineOfSight | Variável Bool para sinalizar quando o jogador é avistado; |
PatrolLocation | Variável Vector para armazenar a posição do ponto de patrulhamento. |
3. Behavior Tree
Consiste em três painéis: o gráfico da Behavaior Tree
, onde você exibe visualmente as ramificações e os nós que definem seus comportamentos, o painel Details
, onde as propriedades de seus nós podem ser definidas e o Blackboard
, que mostra as Chaves do Blackboard
e suas respectivas valores atuais quando o jogo está rodando e é útil para depuração.
O número ao lado do nó indica a ordem de operação. As árvores de comportamento são executadas da esquerda para a direita e de cima para baixo, portanto, a organização dos nós é importante. As ações mais importantes para a IA geralmente devem ser colocadas à esquerda, enquanto as ações menos importantes (ou comportamentos alternativos) são colocadas à direita. As ramificações filhas são executadas da mesma maneira e, se qualquer ramificação filha falhar, a ramificação inteira interromperá a execução e fará o backup da árvore. Por exemplo, se o Chase Player
falhar, ele retornará ao AI Root
antes de passar para o Patrol
.
Além de usar as Tarefas integradas, você pode criar e atribuir suas Tarefas personalizadas com lógica adicional que você pode personalizar e definir. Esta Tarefa será usada para alterar a velocidade de movimento da IA para que ela corra atrás do Jogador. Ao criar uma nova Tarefa, um novo Blueprint será criado e aberto automaticamente.
GetRandomReachablePointInRadius
- Localiza um ponto alcançável aleatório no espaço navegável restrito ao Raio em torno da Origem.
Set Blackboard Value
- Altera o valor das variáveis no BlackBoard passado como parâmetro.
Configurando a árvore de comportamento:
-
Adicionando o nó de controle
sequence
; -
Adicionar variáveis no
Blackboard
para que possam ser compartilhadas pelas task e services;
Implementante a task LocalizaJogador.
-
Tarefas (tasks) são similares a funções que iniciam e finalizam com comandos específicos;
-
Podem ser adicionados parâmetros do tipo Blackboard value para comunicação entre tarefas.
Na lógica utilizamos Get Player Pawn para obter o objeto Pawn instanciado do jogador e logo em seguida o vetor de retorno da função Get Actor Location para que possamos atualizar a variável passada como parâmetro;
3.1. Vídeo Implementando a árvore de comportamento
3.1.1. Andando aleatoriamente
Neste passo iremos adicionar a lógica para que o NPC caminhe para pontos aleatórios.
1. Antes de adicionar a lógica vamos desconectar o nó da árvore LocalizaJogador;
2. No Blackboard
da árvore adicionamos a variável do tipo vetor LocalizacaoPonto, usaremos a variável para armazenar as coordenadas do novo ponto de destino;
3. Localizar um ponto qualquer (randômico) no mapa a partir da posição do jogador;
Utilizaremos a função GetRandomPointInNavigableRadius com o valor de Radius igual a 1500
4. Mover-se até o ponto;
5. Aguardar 2 segundos;
3.2. Vídeo implementando o movimento aleatório
4. Adicionando percepção de visão
Para este passo devemos adicionar componentes no personagem BB_NPC e implementar lógica de detecção do jogador.
-
No
Blackboard
da árvore adicionamos a variável do tipo boolean VendoJogador, usaremos a variável para “avisar” quando o jogador for percebido; -
Configurando a classe BP_NPC
-
No personagem BP_NPC adicionaremos o componente
AIPerception
; -
No componente
AIPerception
será adicionado e configurado o elementoAISight Config
; Este elemento adiciona os parâmetros que definem os ângulos e distâncias dos “sentidos” do NPC, bem como os objetos detectáveis (Inimigos, Neutros e Amigos); -
Adicionamos a lógica para receber e apresentar na tela quando um estimulo é disparado
Sucessfully Sensed
. -
Atualizaremos a variável VendoJogador do
Blackboard
;
-
-
Configurando a classe BP_NPC_Controller, repita os passos anteriores. Adicionar a lógica nesta classe permite distribuir a lógica entre as classes associadas, por exemplo várias classes de personagens.
Esta configuração vai ser utilizada no projeto atual.
4.1. Vídeo implementando a percepção ou visão do NPC
4.1.1. Adicionando as condições de percepção na árvore
Neste passo vamos adicionar obstáculos no ambiente e configurar a árvore combinando os nós perseguindo jogador e andando aleatoriamente.
-
Adicionaremos obstáculos no ambiente para obstruir a visão
-
Iremos adicionar os Decorators :
- Não Está vendo jogador - controlando a subárvore com a seguinte configuração:
-
Observer aborts = Both Para que todas os nõs subjacentes sejam interrompidos;
-
Key Query = Is Not Set Para somente executar a subárvore quando a variável VendoJogador for verdadeira.
- Está vendo jogador - controlando a subárvore para perseguir o jogador
-
Observer aborts = None - Sem parâmetro de controle de interrupção ;
-
Key Query = Is Set.
-
Será criada a task PersegueJogador para substituir Move To;
4.2. Vídeo implementando a percepção na árvore de comportamento
4.2.1. Adicionando o loop da percepção na árvore
Neste passo vamos adicionar um decorator loop para implementar um laço de repetição dos nós.
- No nó com o
decorator
Está vendo o jogador adicionaremos odecorator
Loop para reexecutar os elementos.
4.3. Vídeo implementando a percepção e o loop na árvore de comportamento
5. Organizando os nós
Neste passo vamos renomear os nós para algo que faça sentido.
-
Nó Patrulhando
-
Nó Persegue Jogador
-
Adicionar o
Decorator
Colldown
para que adicionar um tempo de espera quando uma. tarefa retornar false. O decorator loop deve ser removido. -
Adicionar a tarefa Persegue Jogador removendo Move To.
5.1. Vídeo organizando os nós
6. Mudando velocidade do NPC
Neste passo iremos criar um serviço que altera a velocidade do NPC;
-
Criar um serviço MudandoVelocidade;
-
Na classe NPC criar a variável Pawn_NPC para que possamos ter acesso aos componentes e variáveis do NPC;
6.1. Vídeo mudando a velocidade do NPC
7. Patrulhamento com ponto de controle 01
Nos próximos passos devemos implementar o patrulhamento utilizando pontos de controle.
-
Começaremos implementando a classe BP_Caminho do tipo Actor Blueprint;
-
Adicionaremos a variável PontoCaminho do tipo vector e deverá ser um array para servir de marcação dos pontos. A variável deve ter os atributos Instance Editable e Show 3D Widget igual a true ;
-
No classe BB_NPC adicionaremos uma variável Caminho do tipo BP_Caminho assim possibilitamos acesso do NPC ao caminho.
7.1. Vídeo implementando patrulhamento e controle 1
7.1.1. Tarefa para pegar um ponto de patrulhamento
Neste passo vamos implementar uma tarefa para pegar o ponto de controle dentro do objeto caminho associado ao NPC.
-
Obtém o ator associado ao NPC Caminho e logo em seguida um vetor de marcação PontoCaminho.
-
Insere a nova tarefa em uma subárvore e em sequencia adicionamos a tarefa MoveTo com o parâmetro PontoDestino atualizado.
7.2. Vídeo implementando a tarefa para pegar um ponto de patrulhamento
7.2.1. Tarefa para pegar o próximo ponto de controle
Neste passo vamos implementar a tarefa para pegar o próximo ponto de controle.
-
Calculo de ponto atual + 1;
-
Caso o resultado anterior seja maior que o número de pontos associados ao caminho, verificamos se a variável RepeteCaminho (Variável boolean do NPC) é verdadeira para atribuir o valor 0 marcando o início dos pontos ou finalizamos a tarefa.
7.3. Vídeo implementando a tarefa para pegar o próximo ponto de patrulhamento
8. Adicionando Enum para armazenar os estados do NPC
Neste passo vamos adicionar a variável EstadoNPC do tipo Enum com a finalidade de armazenar diversos estados do NPC, como por exemplo:
-
Patrulhando;
-
Procurando;
-
Perseguindo;
Logo em seguida vamos fazer o seguinte:
-
Adicionar uma variável EstadoNPC no
Blackboard
-
Implementar uma tarefa MudaEstadoNPC
8.1. Implementando tarefa para mudança de estado
Neste passo vamos implementar uma tarefa para alterar a variável EstadoNPC modificando o estado do NPC.
8.2. Vídeo implementando tarefa para mudança de estado
9. Testando a árvore com pontos de controle e perseguição
Neste passo iremos organizar a árvore e testar o projeto.
-
Blackboard Based Condition
selecione o valorBoth
emObservers aborts
; -
Cooldown adicione o valor 0.2 em Cool Down Time
9.1. Vídeo testando a árvore com pontos de controle e perseguição
10. Alerta de distância do jogador
Neste passo iremos implementar um aviso de alerta de proximidade de jogador.
-
Tarefa DistanciaJogador calcula a distancia do NPC e o jogador;
-
Variável DistanciaDeAtaque;
-
Variável Distancia com o valor 500 para servir como parâmetro de distâncias.