Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Transição de Estado | Comportamento do Inimigo
Jogo de Luta no Unity

bookTransiçã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 gerenciar transições entre diferentes estados com base em determinadas condições e probabilidades. A seguir, uma explicação simplificada do que este código faz:

Explicação

Classe StatePourcentage

Definição da Classe: A linha public class StatePourcentage define uma classe chamada StatePourcentage. Esta classe armazena informações sobre um estado e a porcentagem de chance de transição para esse estado.

Variáveis Membro:

public State state; armazena uma referência para um estado. public float percentage; armazena a porcentagem de chance 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 gerencia a lógica de transição entre estados com base em uma condição e porcentagens.

Variáveis Membro: Func<bool> condition; é um delegate que armazena 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 armazena 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. 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 essa lista.

Método GetState: public State GetState() é um método que determina para qual estado transicionar com base em uma seleção aleatória e nas porcentagens fornecidas. Ele gera um número aleatório entre 0 e 100 e itera pelos estados disponíveis, acumulando suas porcentagens 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.

Funcionamento para o 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.

Determinação do 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.

Verificação de Condições: O método IsConditionMet() é utilizado 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())
            {
                ChangeState(transition.GetState());
                break;
            }
        }
    }
}

Alterações e Adições

Dicionário de Transições de Estado: Dictionary<State, List<Transition>> stateTransitions; é um dicionário que armazena 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 ele 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 de um determinado estado. Se o estado ainda não possui 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 foi atendida usando transition.IsConditionMet(). Se uma condição de transição for atendida, o estado é alterado usando ChangeState(transition.GetState()); e o loop é interrompido para evitar múltiplas mudanças de estado em uma única atualização.

Motivo das Alterações

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 a complexidade da máquina de estados. Ao verificar dinamicamente as transições dentro do método UpdateStates, o StateManager possibilita 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 das possíveis transições, assegurando a execução adequada da lógica do estado antes de tomar decisões de transição.

Ao implementar essas alterações, o StateManager torna-se mais capaz de lidar com comportamentos complexos e variados, tornando as ações do inimigo mais dinâmicas e responsivas ao ambiente do jogo.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 3. Capítulo 4

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Awesome!

Completion rate improved to 3.33

bookTransição de Estado

Deslize para mostrar o menu

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 gerenciar transições entre diferentes estados com base em determinadas condições e probabilidades. A seguir, uma explicação simplificada do que este código faz:

Explicação

Classe StatePourcentage

Definição da Classe: A linha public class StatePourcentage define uma classe chamada StatePourcentage. Esta classe armazena informações sobre um estado e a porcentagem de chance de transição para esse estado.

Variáveis Membro:

public State state; armazena uma referência para um estado. public float percentage; armazena a porcentagem de chance 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 gerencia a lógica de transição entre estados com base em uma condição e porcentagens.

Variáveis Membro: Func<bool> condition; é um delegate que armazena 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 armazena 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. 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 essa lista.

Método GetState: public State GetState() é um método que determina para qual estado transicionar com base em uma seleção aleatória e nas porcentagens fornecidas. Ele gera um número aleatório entre 0 e 100 e itera pelos estados disponíveis, acumulando suas porcentagens 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.

Funcionamento para o 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.

Determinação do 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.

Verificação de Condições: O método IsConditionMet() é utilizado 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())
            {
                ChangeState(transition.GetState());
                break;
            }
        }
    }
}

Alterações e Adições

Dicionário de Transições de Estado: Dictionary<State, List<Transition>> stateTransitions; é um dicionário que armazena 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 ele 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 de um determinado estado. Se o estado ainda não possui 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 foi atendida usando transition.IsConditionMet(). Se uma condição de transição for atendida, o estado é alterado usando ChangeState(transition.GetState()); e o loop é interrompido para evitar múltiplas mudanças de estado em uma única atualização.

Motivo das Alterações

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 a complexidade da máquina de estados. Ao verificar dinamicamente as transições dentro do método UpdateStates, o StateManager possibilita 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 das possíveis transições, assegurando a execução adequada da lógica do estado antes de tomar decisões de transição.

Ao implementar essas alterações, o StateManager torna-se mais capaz de lidar com comportamentos complexos e variados, tornando as ações do inimigo mais dinâmicas e responsivas ao ambiente do jogo.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 3. Capítulo 4
some-alt