Na última palestra, configuramos o sistema GOAP básico com um agente simples e agora vamos adicionar algumas ações.
Portanto, crie um novo arquivo C
# chamado 'BakeBread' e trarei um que já escrevi antes e veremos o que está lá.
Então, se abrirmos ...
todas as ações que você escreve terão esse mesmo formato.
Agora, todos são módulos separados e individuais por si mesmos, portanto não há vinculação.
Lembre-se: o que os
une são suas condições prévias e seus efeitos correspondentes.
Agora, isso se chama BakeBread e é um GoapAction, portanto, ele herdará
nossas coisas que estão nesse conjunto GoapAction.
A primeira coisa que faremos é definir 'concluído' como Falso, para que este seja um valor booleano
que mantemos, para saber quando terminarmos nossa tarefa. As tarefas também levam
tempo, portanto, acompanharemos o startTime da tarefa, inicializaremos com 0 e definiremos uma workDuration
(por quanto tempo a tarefa leva). É público, para que você possa configurá-lo no Inspetor.
Então, eu tenho isso por 2 segundos e você pode alterá-lo como quiser.
Em seguida, temos nosso construtor público para essa classe, que é onde adicionamos nossas pré-condições e nossos efeitos.
Portanto, essas são provavelmente as coisas mais importantes em todo esse sistema, porque elas
precisam se combinar, em
outras ações, para que elas possam se conectar. Agora você pode ver aqui que nossa pré-condição
para o BakeBread é que 'hasFlour' é True e nosso addEffect (depois de assar o pão)
vai dizer que 'doJob' é True.
Então 'doJob' é verdadeiro em nosso objetivo que estabelecemos, aqui no Worker, que está aqui em cima ... ISSO está combinando ISSO.
Então, isso fará com que o objetivo seja encadeado de volta para ESTE, para que ele possa executá-lo e, se 'hasFlour'
for, de fato, True, então ele começará a executar essa ação específica, caso contrário, será encadeado de volta à lista
, se houver outras ações, para ver
se ele pode continuar satisfazendo-as em algum momento. Agora, neste caso, nós temos farinha
(porque lembre-se
de ter dado ao nosso agente 5 sacos de farinha) e, de volta ao sistema
Worker aqui, estamos injetando o hasFlour, que fornecerá um True porque a farinha é maior que 1.
Certo.
Portanto, o nome aqui é apenas para fins de depuração, para que possamos imprimi-lo se precisarmos (no console) para ver
o que está acontecendo.
Certo, toda ação precisa de um 'reset', para que, quando essa ação for executada novamente, comece com novos
valores.
Portanto, startTime obviamente volta para 0
e 'concluído' volta para False e existem alguns outros métodos necessários: o retorno
de 'concluído' (isDone, para dizer "Terminamos ou não? "), temos outro chamado 'requireInRange' e esta é uma função
que você pode definir como False se permitir que seu agente execute uma tarefa quando ele não
estiver realmente no local em que precisa.
Então, estamos dizendo que "Sim, você precisa estar no local designado para executar sua tarefa (ou esta tarefa
em particular).
Você tem outra opção para pré-condições mais processuais, para poder verificar se outras coisas
no ambiente também são Verdadeiras ou Falsas, antes de o agente executar qualquer uma dessas ações.
Então, no momento, não temos nenhum.
Estamos apenas assando pão,
simplesmente, mas você pode verificar algo como "Talvez você precise de 10 pães antes de
entregá-los à padaria. "ou" Você pode não conseguir assar
se estiver inundando ou chovendo, dependendo do clima. ", todo tipo de
coisa que não se encaixa na cadeia de ações que você colocaria
aqui.
Em seguida, temos o nosso método 'perform', que é interrompido enquanto a tarefa está ocorrendo; portanto, ele inicializa o startTime
e também tenho alguns
Debugs aqui, para que você possa vê-los no console ao iniciar um determinado trabalho
e
quando terminar esse trabalho, portanto, isso ocorre apenas pelo tempo necessário para executar
essa tarefa.
Para cada ação, isso será praticamente o
mesmo, mas você poderá executar coisas diferentes com base na ação em que está.
Essa é a ação do
BakeBread; portanto, no final da ação do BakeBread, estou dizendo que nosso nível de farinha no nosso
inventário diminuirá em 2 (porque lembre-se de que são necessários 2 sacos de farinha para fazer um pedaço de pão) e
depois nós nos livramos de 2 sacos de farinha e, em seguida, adicionamos 1 pedaço de pão ao nosso
inventário, e dizemos que 'concluído'
é Verdadeiro, que concluirá esta tarefa porque será devolvida ao sistema aqui em cima.
Portanto, esse é o código inteiro para o nosso BakeBread.
Então salve isso ... volte para a Unity ... você deseja adicionar esse código ao seu agente.
Portanto, essa é uma ação, você arrasta e solta no agente e
agora pode criar quantas ações quiser e continua arrastando
e soltando-as no agente e o agente saberá sobre essas ações.
Agora, a única coisa que você precisa definir no momento é o Alvo para o BakeBread.
Onde você quer assar pão?
Vamos assá-lo na padaria, por isso encontramos o nosso marcador de padaria (que é a minha 'porta'
da padaria) e vou arrastar e soltar ISSO como o alvo para assar.
Está bem.
Agora você está pronto para executá-lo, então vou mudar para o console para poder ver o que está acontecendo ... basta esclarecer isso e vamos
pressionar Play.
Então, ele será movido para o local em que pode executar a ação BakeBread e, quando chegar lá, começará a
assar pão e você poderá ver isso no console. Quando terminar, você verá
que seu inventário e sua farinha diminuirão 2 a cada vez.
Agora isso aconteceu
muito rapidamente, mas se você voltar e olhar pelo console, há muita coisa lá.
Vamos fazer uma pausa, porque agora ele não consegue encontrar nenhum plano, continuará com o 'Plano com falha'.
Podemos encontrar onde o cozimento aconteceu ... aqui vamos nós.
Então, estamos nos mudando para cá.
Então, nos mudamos para o BakeBread ...
estamos começando o BakeBread ... BakeBread terminado ... mudou-se para BakeBread ... iniciando o BakeBread ... terminou o BakeBread.
Então, nós fizemos 2 pães e depois diz NÃO PLANO e
é porque ficamos sem farinha. Portanto, resta apenas 1 lote de farinha e
temos 2 pães de pão.
Agora não há como obter mais farinha neste momento.
Portanto, o plano para fazer seu trabalho falhou.
Ele não pode continuar enquanto o processa.
Então, o que podemos fazer agora é adicionar outra ação que o ajude a obter um pouco de farinha, para que ele possa continuar assando.
Certo, pare de jogar isso
e, no projeto, você criará um novo arquivo C # chamado
'PickupFlour' e será parecido com este aqui.
Então PickupFlour ...
se for mais fácil para você, faça uma cópia completa da ação BakeBread e, em seguida, coloque-a no script PickupFlour
e, em seguida, certifique-se de alterar o nome aqui ...
e no construtor ...
então LÁ e também o PickupFlour também. Todo o resto pode permanecer exatamente igual, porque
está apenas processando a ação.
Agora, a Pré-condição e o Efeito para o PickupFlour é que vamos pedir ao agente que pegue a farinha quando ficarmos
sem farinha.
Então, quando 'hasFlour for False' é quando essa ação deve ocorrer e o
efeito depois disso é que hasFlour será igual a True.
Portanto, este efeito aqui está definindo hasFlour como True, o que permitirá que a ação BakeBread seja executada.
Então essa é a ligação que acontecerá lá.
Agora, mais abaixo em nosso 'executar', onde precisamos configurar como o inventário vai mudar, é que, depois que terminarmos de pegar a farinha,
poderemos pegar o nível de farinha em nosso inventário. Nesse caso, estou dizendo que, quando ele
for
ao moinho para pegar a farinha, ele poderá transportar 5 lotes de farinha e, portanto,
adicionaremos 5 ao inventário, o que permitirá que ele continue e criando mais
pão por um tempo.
Certo.
Então, quando você tiver tudo isso lá, salve isso, volte para o Unity e esse script novamente
poderá ser jogado (PickupFlour) no agente.
Lembre-se de que precisamos definir nosso destino de destino para pegar a farinha e, nesse caso,
diremos que está na porta do moinho de vento.
Então, usaremos a Porta do Moinho de Vento como nosso Alvo para pegar a farinha.
Agora, quando pressionamos Play, podemos assistir a farinha diminuir (então, diminuiremos 2 com cada pedaço de pão produzido) e
então saberemos quando restar 1 lote de farinha e 2 pães, ele terá que
ir e pegue no moinho e aqui você pode vê-lo brincando para pegar a
farinha.
Agora, se tudo estiver um pouco lento demais para você, lembre-se de clicar no seu agente BAker, ir ao
seu Nav Mesh Agent e alterar a velocidade dele.
Portanto, se definirmos para 15, o que deve acelerar um pouco as coisas, não aumentará o
tempo necessário para concluir as tarefas, apenas aumentará
o tempo que leva para ele ir entre os lugares, para que você possa ver acontecendo um pouco
mais rápido.
Agora podemos ver que ele está voltando ... recebendo a farinha ... a farinha em seu inventário
aumentará para 6 porque você tinha 1, ele adicionou 5 e depois usará essa farinha e
fará mais pão; quando ele acabar, ele voltará e conseguirá.
Agora você pode criar uma cadeia bastante complexa de todos os diferentes eventos que deseja que ocorram em
qualquer comportamento em
particular, mas apenas com alguns você pode obter coisas bastante complexas, como você pode ver aqui.
Tudo bem, então isso está configurando sua pequena cadeia e,
nesse caso, é como uma cadeia de suprimentos.
Na próxima palestra, o que faremos com que ele entregue o pão (quando tiver o suficiente)
aos mercados.