Transição de Estado
public class Transition{Func<bool> condition;List<StatePourcentage> availableStates;public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage){this.condition = condition;availableStates = new List<StatePourcentage>();for (int i = 0; i < statePourcentage.Length; i++){availableStates.Add(statePourcentage[i]);}}public State GetState(){float percentage = UnityEngine.Random.Range(0, 100);float currentPercentage = 0;foreach (var statePer in availableStates){currentPercentage += statePer.percentage;if (percentage <= currentPercentage){return statePer.state;}}return null;}public bool IsConditionMet(){return condition();}}
public class StatePourcentage{public State state;public float percentage;public StatePourcentage(State state, float percentage){this.state = state;this.percentage = percentage;}}
Nestas imagens, vemos uma classe Transition
e uma classe StatePourcentage
. Essas classes trabalham juntas para lidar com transições entre diferentes estados com base em certas condições e probabilidades. Vamos explicar o que esse código faz em termos simples:
Explicação
Classe StatePourcentage
Definição da Classe:
A linha public class StatePourcentage
define uma classe chamada StatePourcentage
. Esta classe mantém informações sobre um estado e a chance percentual de transição para esse estado.
Variáveis Membro:
public State state;
mantém uma referência a um estado.
public float percentage;
mantém a chance percentual de transição para este estado.
Construtor:
public StatePourcentage(State state, float percentage)
é um método construtor. Ele recebe um State
e um float
como parâmetros e os atribui às variáveis membro.
Classe Transition
Definição da Classe:
A linha public class Transition
define uma classe chamada Transition
. Esta classe lida com a lógica de transição entre estados com base em uma condição e percentuais.
Variáveis Membro:
Func<bool> condition;
é um delegado que mantém uma função de condição. Esta função retorna um booleano indicando se a condição de transição foi atendida.
List<StatePourcentage> availableStates;
é uma lista que mantém múltiplos objetos StatePourcentage
, representando estados potenciais para transição e suas respectivas probabilidades.
Construtor:
public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage)
é um método construtor. Ele recebe uma função de condição e um array de objetos StatePourcentage
como parâmetros. Ele inicializa a variável membro condition
com a função de condição fornecida e cria uma nova lista para availableStates
, adicionando cada objeto StatePourcentage
do array a esta lista.
Método GetState:
public State GetState()
é um método que determina para qual estado transitar com base em uma seleção aleatória e nos percentuais fornecidos. Ele gera um número aleatório entre 0 e 100 e itera pelos estados disponíveis, acumulando seus percentuais até encontrar o estado que corresponde ao número aleatório.
Método IsConditionMet:
public bool IsConditionMet()
é um método que verifica se a condição de transição foi atendida chamando a função de condição. Ele retorna o resultado da função de condição.
Como Funciona para Nosso Inimigo
Configuração de Transição: Definimos transições entre estados, especificando as condições sob as quais essas transições ocorrem e as probabilidades de transição para cada estado.
Determinando o Próximo Estado: Quando uma transição é acionada, o método GetState()
seleciona aleatoriamente o próximo estado com base nas probabilidades definidas. Isso adiciona um elemento de imprevisibilidade ao comportamento do inimigo, tornando-o mais dinâmico e desafiador.
Verificando Condições: O método IsConditionMet()
é usado para verificar se as condições para uma transição foram atendidas. Se a condição for verdadeira, a transição pode ocorrer, e o método GetState()
determina o próximo estado.
Gerenciador de Estados
public class StateManager{State currentState;Dictionary<State, List<Transition>> stateTransitions;public StateManager(State startingState){currentState = startingState;currentState.StartState();stateTransitions = new Dictionary<State, List<Transition>>();}public void AddStateTransition(State state, Transition transition){if (!stateTransitions.ContainsKey(state)){stateTransitions.Add(state, new List<Transition>());}stateTransitions[state].Add(transition);}public void ChangeState(State newState){currentState.EndState();currentState = newState;currentState.StartState();}public void UpdateStates(float deltaTime){currentState.UpdateState(deltaTime);List<Transition> stateTransitionsList = stateTransitions[currentState];if (stateTransitionsList == null || stateTransitionsList.Count == 0) return;foreach (var transition in stateTransitionsList){if (transition.IsConditionMet())
Alterações e Adições
Dicionário de Transições de Estado: Dictionary<State, List<Transition>> stateTransitions;
é um dicionário que mantém listas de transições para cada estado. Cada estado está associado a uma lista de possíveis transições que podem ser verificadas ao atualizar o estado.
Construtor: stateTransitions = new Dictionary<State, List<Transition>>();
inicializa o dicionário stateTransitions
no construtor, garantindo que esteja pronto para armazenar transições para diferentes estados.
Método AddStateTransition: public void AddStateTransition(State state, Transition transition)
é um método que adiciona uma transição à lista de transições para um determinado estado. Se o estado ainda não tiver uma entrada no dicionário, uma nova entrada é criada com uma lista vazia de transições. A transição é então adicionada à lista de transições para o estado especificado.
Método UpdateStates: O método UpdateStates
foi atualizado para primeiro verificar as transições recuperando a lista de transições para o estado atual após atualizá-lo com currentState.UpdateState(deltaTime);
. Em seguida, avalia cada transição na lista para verificar se a condição de transição é atendida usando transition.IsConditionMet()
. Se uma condição de transição for atendida, ele muda o estado usando ChangeState(transition.GetState());
e interrompe o loop para evitar múltiplas mudanças de estado em uma única atualização.
Por Que Essas Alterações Foram Feitas
A adição do dicionário stateTransitions
e do método AddStateTransition
permite que o StateManager
gerencie múltiplas transições potenciais para cada estado, aumentando a flexibilidade e complexidade da máquina de estados. Ao verificar dinamicamente as transições dentro do método UpdateStates
, o StateManager
permite que o inimigo responda a diferentes eventos e condições em tempo real. O método atualizado garante que o estado atual seja atualizado primeiro, seguido pela verificação de possíveis transições, o que assegura a execução adequada da lógica de estado antes de tomar decisões de transição.
Ao implementar essas mudanças, o StateManager
se torna mais capaz de lidar com comportamentos complexos e variados, tornando as ações do inimigo mais dinâmicas e responsivas ao ambiente do jogo.
Obrigado pelo seu feedback!