Escolhendo uma sequência de animações para um NPC - use uma árvore de comportamento?


8

Estou implementando um NPC para percorrer um espaço virtual, especificamente um gato. Eu tenho uma série de clipes curtos de animação (3-5 segundos). Meu primeiro instinto foi escolher uma animação aleatória quando a última terminou, mas percebi que ela não pareceria realista, pois mudaria de comportamento com muita frequência, mesmo que a próxima animação seja limitada a possibilidades fisicamente contingentes.

Minha solução pretendida é algo como uma árvore de comportamento ( http://www.gamasutra.com/blogs/ChrisSimpson/20140717/221339/Behavior_trees_for_AI_How_they_work.php ), em que cada animação tem uma lista ponderada das próximas animações. Ou seja, se o gato está andando, ele tem 80% de chance de continuar andando, 20% de sentar, 0% de dormir. Basicamente, usando um modelo markov para obter o próximo passo apropriado.

No entanto, não tenho idéia se essa é uma boa solução, nem sei como vou gerar o mapeamento da animação atual para a próxima animação potencial + probabilidade. 30 animações * 30 próximas animações = 900 ponderações. Isso é muito para calcular manualmente.

Às vezes, o gato reage se atingir um obstáculo, mas o problema do problema é escolher uma sequência realista de animações sem selecioná-las com antecedência. Na árvore, também haveria outras informações, como proximidade com uma pessoa, localização na sala, tempo desde a última vez que comi etc.


2
Eu nunca fiz esse tipo de coisa, mas uma abordagem mais simples seria suficiente? ou seja, agrupe suas animações em "comportamentos" como: caçar, brincar, descansar, seres humanos irritantes, etc. Então você provavelmente poderia fugir sem esse modelo de markov e ter apenas probs simples. dentro de grupos e probs para alternar grupos com base na hora / eventos externos.
— 27516 Mat

Respostas:


3

Geralmente você precisa dividir a lógica dos gatos das animações.

Agora, primeiro você precisa escrever a lógica dos gatos. Uma boa abordagem que encontrei é dividir a lógica em camadas.

Necessidades

O gato pode ter algum estado com alguns motivos / necessidades (comer, dormir etc.) que crescem lentamente ao longo do tempo e diminuem ao fazê-lo (pense nos Sims). Você pode escolher a tarefa atual que atenda à maior necessidade usando a lógica difusa, se desejar.

Tarefas

Agora, a cada momento, o gato tem uma tarefa (encontrar comida, encontrar cama para dormir, espaço para correr, etc. ficar inativo também é uma tarefa). Essas tarefas dizem ao gato para onde ir e o que deseja fazer.

Ações

Agora há a terceira camada - ações. Cada objetivo tem uma fila de ações a serem executadas (levantar-se, caminhar, agachar-se, comer etc.). Cada ação é responsável por sua execução. Por exemplo, a ação de andar deve verificar se há obstáculos e entregar o gato do ponto A ao ponto B, possivelmente contendo e executando sub-ações (pular obstáculos, agachar-se embaixo dos móveis e etc.).

Animações

Agora, quando o gato tiver necessidades, uma tarefa e uma ação, você poderá escolher a animação certa para essa ação. Conhecendo a animação atual e a próxima, você poderá fazer a transição de uma para outra. Por exemplo, se a tarefa diz que o gato deve deitar depois de caminhar até o travesseiro, as animações são colocadas em fila - ande, pare, sente e coloque.

O enfileiramento de animações pode ser feito de maneira eficaz se você os mapear em um gráfico como nós e conectar os nós entre animações transicionáveis ​​(por exemplo, é possível andar para sentar, mas pular para mastigar - não). Em seguida, você pode enfileirar animações de cada uma delas usando A * neste gráfico.

Exemplo: o gato precisa descansar e comer. Deixe a tarefa "Descansar" encontrar um lugar para descansar, passear com o gato, deitar e descansar. Deixe a tarefa "Descansar" verificar as condições de vez em quando, se o ambiente ficar desconfortável - deixe a tarefa terminar. Verifique o que o gato quer agora mais, se ainda quiser descansar - repita a parte anterior. Quando o gato estiver descansado - escolha uma nova tarefa.


2

Eu acho que o que você está procurando é a máquina de estados finitos ou FSM. Em suma, é uma maneira de mudar o comportamento dos NPC: s de acordo com seu estado atual.

EDITAR:

É como uma árvore de comportamento, mas condensada em alguns "estados" de grupos aos quais o NPC retorna. Uma árvore de comportamento permite muito mais flexibilidade do comportamento, mas também precisa de mais dados para ponderar as probabilidades (uma maneira inteligente de automatizá-lo é com tags, como scriptin sugere em sua resposta). Ao usar estados, você decide um determinado conjunto de ações e probabilidades para essas ações no estado. Para alterar efetivamente, a ação atual pode ser enviesada com talvez 80% para manter a mesma ação. Se a ação for alterada, diferentes probabilidades serão usadas para selecionar a nova ação.

No seu caso, os estados podem ser (um pouco simplificados):

  • Sonolento: Durma 80%, Sente-se 15%, Ande 5%
  • Angry: Rugido (os gatos rugem?) 40%, Silvo 40%, Corra 20%
  • Com fome: Coma 40%, Caça 40%, Corra 10%
  • Playfull: Jogue 60%, Corra 20%, Salte 10%
  • Marcado: Ocultar 50%, Corra 50%

Cada estado pode ter probabilidades diferentes de mudar de estado, por exemplo, o estado de raiva ou cicatrização talvez não dure muito. Os diferentes estados também podem ter regras diferentes para o que é legal (mudar de "sonolento" para "brincalhão" pode ser ilegal, mas os gatos parecem não se importar com isso). Eventos diferentes podem acionar a alteração do estado.

Dê uma olhada ao pesquisar na Web por FSM e AI e você pode ver como ele funciona. Pode parecer complicado ao explicar, mas é realmente simples.


Você acabou de descrever uma solução proposta na pergunta, com um nome diferente.
— scriptin

Árvores de comportamento são muito mais complexos do que máquinas de estado, a implementação ea necessidade de configuração de peso é muito mais fácil
— Fredrik Lundvall

Eu entendi aquilo. Mas o algoritmo descrito na pergunta é exatamente o que você descreveu. (Acho que o OP está descrevendo um FSM em vez de uma árvore de comportamento.) Além disso, você não está abordando o problema de muitas permutações de estados, o que parece ser a principal preocupação da questão.
— Script #

Você está certo sobre a minha resposta não foi realmente resolver o problema. Eu queria apontá-lo na direção certa. Por causa das permutações não sendo realmente um problema com máquinas de estado
— Fredrik Lundvall

Essa informação adicional pode ser muito útil. Talvez você possa editar sua resposta para elaborar essas diferenças entre FSM e BT?
— Script #

1

Você pode usar a marcação:

  • Pode haver marcas de movimento como "deitado", "sentado", "em pé", "andando" e "correndo". Em seguida, você pode eliminar combinações irreais de tags, por exemplo, "postura" -> "execução" (deve haver "posição de pé" no meio).

  • Outras tags podem descrever atividades: "dormir", "comer", "caçar" etc. Mais uma vez, "dormir" -> "caçar" é impossível sem estados intermediários.

  • Como animações como "em pé" são transitórias, pode ser uma boa ideia ter tags separadas para o início e o final de cada animação. Por exemplo, "levantar-se" pode ser uma transição de "sentado" para "ficar" etc.

Portanto, para cada animação, você pode ter algumas tags:

  • Descrevem a posição / movimento inicial e final
  • Pelo menos um que descreve uma atividade. Além disso, como as atividades também têm transições, você também pode ter tags inicial e final aqui

Com esses, você pode filtrar apenas as combinações possíveis, definindo restrições como " A->Bsó é possível se final_movement_tag(A) == initial_movement_tag(B)", o que resultará em um número muito menor. Com essas combinações possíveis, você pode fazer o que descreveu - adicionar probabilidades. A adição de probabilidades pode ser baseada em tags de atividade, pois permanecer em uma mesma atividade é mais provável do que alterar atividades.

Portanto, com as tags, é possível automatizar a criação de todas as transições na sua árvore FSM / comportamento e ajustá-las mais tarde, se você não estiver satisfeito com algumas combinações.


1

Se você deseja manter as ricas possibilidades das árvores de comportamento, pode adicionar um novo tipo de nó seletor composto: o nó seletor Markov.

Você precisaria implementar o nó do seletor Markov. Ele selecionará um de seus nós filhos aleatoriamente, dependendo do nó (filho) que teve sucesso (ou falhou) anteriormente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.