Para criar um mundo complexo, você precisará adicionar mais agentes e também
adicionar outros inventários.
Atualmente, os inventários que criamos estão vivendo com um agente específico (neste caso, é apenas
o Baker).
Então, ele está acompanhando a quantidade de farinha existente no mundo e a quantidade de pão
existente no mundo, mas para que ele possa realmente pegar o pão do moinho, ele precisa saber se
há farinha no moinho e, portanto, o a própria fábrica precisa ter seu próprio estoque.
Aqui você pode ver o que eu criei é uma pequena simulação que agora inclui um Fazendeiro que está entregando trigo
ao moinho e o Padeiro (quando ele fica sem farinha e não há farinha no moinho) fica parado e
espera pelo Agricultor para encher o moinho e depois voltará ao seu trabalho.
Então, vamos recriar isso.
Primeiro de tudo, eu vou parar de tocar. Vou pegar meu fazendeiro que tenho e desligá-lo para que
não faça parte da equação
no momento, mas o que você precisará fazer é criar uma fazenda ou um piquete que acabei de fazer
um
pouco quadrado e eu abri a porta (que é o ponto onde a ação ocorrerá) para a colheita, um pouco mais tarde.
Também tirei os colisores dessas coisas, para que o agente não tivesse problemas
e ele pudesse entrar no meio do pasto.
Portanto, a primeira coisa que você precisa fazer é fazer um inventário para o moinho de vento.
Peguei o moinho de vento e acabei de adicionar o inventário que já estava usando para o
Baker.
Portanto, o script de inventário foi arrastado e solto no moinho de vento, mas não antes de algumas pequenas
alterações.
Vamos dar uma olhada.
Portanto, aqui, eu apenas a ampliei adicionando um 'drawOffset' e um 'nome', para que isso apenas afete o sistema da GUI, para
que, quando desenhe na tela, use o deslocamento para onde o o inventário é posicionado e também insere
o nome, para que você saiba de quem é o inventário e
isso será exibido no moinho de vento. Portanto, se você fizer essas alterações e apenas salvá-las,
volte para o Unity, em seguida, no Windmill, adicione esse script e o Draw Offset que eu tenho é 100 e
o nome é Windmill.
Agora isso significa que você precisará definir isso para o seu Baker.
Portanto, se você for ao Baker e encontrar o script Inventory, basta colocar o nome de Baker e o Draw Offset pode
ser 0, para que, ao pressionar Play, você obtenha o Baker no topo e o Windmill na parte
inferior e você pode acompanhar o conteúdo de cada um desses inventários.
O script que precisa saber sobre
o inventário do moinho de
vento é Worker, então clique no script Worker C # e, na parte superior, passaremos pelo inventário do moinho
de vento.
Adicione isso e, em seguida, os níveis de farinha no moinho de vento serão usados no Estado Mundial para injetar se
'hasStock' é verdadeiro ou não e você pode ver aqui
que estamos obtendo moinho de vento. nível de farinha maior que 4, o
que dirá ao Baker que há sacas suficientes (são 5 sacas, pelo menos, para que possam ser recolhidas lá).
É tudo o que você precisa adicionar à classe Worker.
Então salve isso.
A outra coisa que você quer saber sobre esse nível de farinha é a sua ação PickupFlour.
Então, além disso, você também deseja passar pelo inventário do moinho de vento aqui
e,
em seguida, para coletar farinha, agora temos outra pré-condição. Então, adicionePrecondition ("hasStock", true) para que, quando isso
for verdade, possamos pegar nossa farinha.
Então, só faremos isso quando houver estoque no
Moinho de Vento e a farinha acabar. Então, são as nossas 2 primeiras condições iniciais.
Agora, quando finalmente executarmos o PickupFlour, lembre-se de que deseja adicionar o nível de farinha ao seu próprio inventário,
para que o Baker esteja carregando a farinha e o moinho de vento esteja perdendo a farinha,
portanto, é necessário retirá-la do Nível do moinho de vento para inventário.
Então, depois de fazer isso, salve tudo isso e, ao pressionar Play, você
poderá assistir a isso em ação.
O padeiro vai assar o pão, vai ficar sem farinha, vai pegar um
pouco de farinha (o que levará todos os sacos de farinha do moinho de vento
que você pode ver no inventário),
ele vai volte e assa mais 3 pães e então ele terá o suficiente para uma entrega e ele a
entregará
e, uma vez entregue, ele ficará sem pão, ficará sem farinha, o moinho ficará
sem farinha, há
não há farinha em
lugar nenhum, então ele não pode fazer nada e todos os seus planos vão falhar.
Ele vai sentar e esperar nos mercados até que eles consigam um pouco de farinha no moinho
de
vento, para que possamos fazer isso um pouco sorrateiramente. Se selecionarmos o moinho de vento na hierarquia (ainda estamos jogando) e passarmos para o
nível de farinha e vamos entregar 10 lotes de farinha ... e agora você pode ver: lá vai ele.
Então, agora queremos adicionar outro agente (um agente do agricultor) que possa retirar o trigo do Paddock e entregá-lo ao moinho
de vento, para que, quando o moinho de vento ficar sem farinha, o padeiro possa obter um pouco mais.
Então, para criar um novo agente Farmer, dupliquei o Baker e o deixei verde e troquei
o chapéu, para que parecesse diferente. Em seguida, você deseja retirar todos os scripts relacionados
ao Baker, deixar o agente GOAP, o Farmer não precisa de seu próprio inventário (na verdade, não está acompanhando tudo, é
apenas pegar o trigo e levá-lo ao moinho de vento) .
Mais tarde, se você quiser tornar isso mais complicado, sinta-se à vontade.
Vamos adicionar um script Farmer, que é o script de condução do agente GOAP, como o script
Worker no Baker e 2 ações (1 Harvest e 1 DeliverWheat).
Vamos dar uma olhada no script Farmer primeiro.
Você deseja duplicar o script Worker e renomeá-lo para Farmer.
Então, no topo, temos o Farmer e todo o resto é o mesmo. O GetWorldState, não há nada lá porque ele
não precisa fazer nada e, em
seguida, o trabalho no CreateGoalState é 'doJob', mas esse 'doJob' para esse agente é baseado nas ações que estarão no
agente, então ele não é vai assar pão e pegar farinha.
O restante do código é exatamente o mesmo do script Worker que está no outro agente.
Então, eles são as únicas coisas lá.
As 2 ações que estamos adicionando ...
Em primeiro lugar, temos uma ação 'Colheita' (que está indo para a fazenda e colhendo o
trigo), então é chamada Colheita. cs, classe é colheita.
O topo é o mesmo ... o construtor,
é claro, é chamado de colheita.
Agora o Harvest não possui nenhuma condição prévia, portanto, você pode executar uma ação sem a condição prévia
e também pode executar uma ação sem nenhum efeito.
Agora, nada precisa acontecer para o agricultor colher.
Convém configurar algum tipo de ciclo diurno e noturno no seu jogo, para que o Fazendeiro apenas
colha durante o dia e, em seguida, coloque isso nas condições mundiais que estão surgindo no código do
Fazendeiro, mas,
neste caso, há Nada como isso.
Portanto, o efeito da colheita é que você terá trigo, então 'hasWheat'
está definido como True. Agora, no restante desta
ação, não há realmente nada acontecendo.
Portanto, é apenas o padrão.
Não está atualizando nenhum inventário no método 'perform' ou algo assim.
Ok, então essa é a colheita.
Agora, o outro que temos sobre o agricultor é o DeliverWheat, que é levar o trigo ao moinho
de farinha.
É um pouco diferente.
Abra isso e você verá que temos um 'inventário público' sendo passado para ele e
esse é o inventário do moinho de vento. Isso é para que possamos atualizar o inventário do moinho de vento quando essa ação for concluída.
Então, chama-se DeliverWheat, seu construtor é DeliverWheat, sua pré-condição é 'hasWheat' é True, que é definido
como True quando fazemos a colheita e então o
Effect é ("doJob", true) e é isso
que está causando toda essa pequena cadeia executar
porque 'doJob' é o principal objetivo do Agricultor e o 'nome' aqui (que eu não mudei) também
deve ser 'DeliverWheat'.
É isso que você obtém ao copiar e colar todas as suas ações.
Agora o resto do código é praticamente o mesmo ... descendo ... aqui.
A única coisa que você verá é que, quando executarmos esta tarefa de DeliverWheat, atualizaremos o nível de
farinha no inventário em 1 saco.
Este inventário não é o inventário do fazendeiro.
Ele não tem um.
É o inventário do moinho de vento. Ok, então salve-os, então vamos
ao Farmer e você deseja anexar esses 2 scripts (essas 2 ações) e o script Farmer
também.
Ambas as ações (Harvest e DeliverWheat) precisarão de locais, portanto, o script Harvest
acontecerá na Farm Door (que é nossa Fazenda / Paddock) e o DeliverWheat acontecerá na Windmill
Door, onde largamos isso fora.
Agora você verá na ação DeliverWheat, também abrimos esse 'inventário público', para que possamos passar o inventário do
moinho de vento para ele, para que você possa simplesmente arrastar e soltar o moinho de vento nesse local
e pegar o inventário do moinho de vento que esse script agora pode atualizar.
Agora vamos executá-lo e o que veremos são os dois agentes trabalhando em direção a seus próprios objetivos.
Ok, assim como o Fazendeiro entrega, você verá que o moinho de vento sobe 1 toda vez e o agente apenas pega 5 sacolas,
que agora as levam de volta para assar um pouco de pão e ele vai entregar um pouco de pão.
Agora, ele não será capaz de voltar ao moinho de vento até que haja cinco sacos para pegar, então
ele está meio que preso no limbo até assar pão porque não tem farinha e não há no
moinho de vento.
Quando esse inventário do Moinho de Vento atingir 5 farinha (o que acontecerá agora), ele fará com que o padeiro cumpra seus
objetivos e ele partirá, pegará um pouco de farinha e poderá começar a trabalhar no pão.
Ok, para que você possa ver como isso pode ficar muito complexo, muito rapidamente e como você pode ter
sistemas de inventário que pertencem apenas aos próprios agentes, para que eles possam acompanhar
o que têm, mas também existem coisas no mundo que também precisam de
inventários, para que você possa mover os produtos. O que é realmente importante é que, se você pegar
algo de um inventário, adicioná-lo a outro e certificar-se de deduzi-lo do
valor do inventário anterior, caso contrário, seus números sairão do controle e isso pode ser um
problema. boa ideia, se você realmente configurar uma planilha ou algo para acompanhar todas essas coisas
que estão circulando ou mesmo tiver variáveis globais em algum tipo de 'arquivo de contagem de inventário', para manter os
valores reais que deseja adicionando e diminuindo, para que você só precise alterá-los em um
lugar no seu código.
Certo.
Portanto, esse é o
sistema GOAP e espero que tenha inspirado você com muita criatividade para criar diferentes tipos de jogos de
simulação como esse, mas também usando o GOAP para RPGs e First Person Shooters. Portanto, se você leu o link da literatura de pesquisa
que enviei a você no início, verá que isso foi usado pela primeira
vez em jogos do tipo FPS, mas é muito adaptável.