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.

estrela do Mar
fonte
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.

Kromster
fonte
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.

Fredrik Lundvall
fonte
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.

scriptin
fonte
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.

Kasper van den Berg
fonte