Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende Transición de Estado | Comportamiento del Enemigo
Juego de Lucha en Unity

bookTransición 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;
    }
}

En estas imágenes, observamos una clase Transition y una clase StatePourcentage. Estas clases trabajan en conjunto para gestionar las transiciones entre diferentes estados basándose en ciertas condiciones y probabilidades. A continuación, se explica de manera sencilla qué realiza este código:

Explicación

Clase StatePourcentage

Definición de la clase: La línea public class StatePourcentage define una clase llamada StatePourcentage. Esta clase almacena información sobre un estado y el porcentaje de probabilidad de transición a ese estado.

Variables miembro:

public State state; almacena una referencia a un estado. public float percentage; almacena el porcentaje de probabilidad de transición a este estado.

Constructor:

public StatePourcentage(State state, float percentage) es un método constructor. Recibe un State y un float como parámetros y los asigna a las variables miembro.

Clase Transition

Definición de la clase: La línea public class Transition define una clase llamada Transition. Esta clase gestiona la lógica para la transición entre estados basada en una condición y porcentajes.

Variables miembro: Func<bool> condition; es un delegado que almacena una función de condición. Esta función retorna un valor booleano que indica si se cumple la condición de transición.

List<StatePourcentage> availableStates; es una lista que almacena múltiples objetos StatePourcentage, representando los posibles estados a los que se puede transicionar y sus respectivas probabilidades.

Constructor: public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage) es un método constructor. Recibe una función de condición y un arreglo de objetos StatePourcentage como parámetros. Inicializa la variable miembro condition con la función de condición proporcionada y crea una nueva lista para availableStates, agregando cada objeto StatePourcentage del arreglo a esta lista.

Método GetState: public State GetState() es un método que determina a qué estado se debe transicionar basado en una selección aleatoria y los porcentajes definidos. Genera un número aleatorio entre 0 y 100 e itera a través de los estados disponibles, acumulando sus porcentajes hasta encontrar el estado que corresponde con el número aleatorio.

Método IsConditionMet: public bool IsConditionMet() es un método que verifica si se cumple la condición de transición llamando a la función de condición. Retorna el resultado de la función de condición.

Funcionamiento para Nuestro Enemigo

Configuración de transiciones: Se definen transiciones entre estados, especificando las condiciones bajo las cuales ocurren estas transiciones y las probabilidades de transición a cada estado.

Determinación del siguiente estado: Cuando se activa una transición, el método GetState() selecciona aleatoriamente el siguiente estado según las probabilidades definidas. Esto añade un elemento de imprevisibilidad al comportamiento del enemigo, haciéndolo más dinámico y desafiante.

Verificación de condiciones: El método IsConditionMet() se utiliza para comprobar si se cumplen las condiciones para una transición. Si la condición es verdadera, la transición puede ocurrir y el método GetState() determina el siguiente estado.

Gestor 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;
            }
        }
    }
}

Cambios y Adiciones

Diccionario de Transiciones de Estado: Dictionary<State, List<Transition>> stateTransitions; es un diccionario que almacena listas de transiciones para cada estado. Cada estado está asociado con una lista de posibles transiciones que pueden ser verificadas al actualizar el estado.

Constructor: stateTransitions = new Dictionary<State, List<Transition>>(); inicializa el diccionario stateTransitions en el constructor, asegurando que esté listo para almacenar transiciones para diferentes estados.

Método AddStateTransition: public void AddStateTransition(State state, Transition transition) es un método que añade una transición a la lista de transiciones para un estado dado. Si el estado aún no tiene una entrada en el diccionario, se crea una nueva entrada con una lista vacía de transiciones. Luego, la transición se añade a la lista de transiciones para el estado especificado.

Método UpdateStates: El método UpdateStates ha sido actualizado para primero verificar las transiciones obteniendo la lista de transiciones para el estado actual después de actualizarlo con currentState.UpdateState(deltaTime);. Luego evalúa cada transición en la lista para comprobar si se cumple la condición de transición usando transition.IsConditionMet(). Si se cumple una condición de transición, cambia el estado usando ChangeState(transition.GetState()); y rompe el ciclo para evitar múltiples cambios de estado en una sola actualización.

Razón de Estos Cambios

La adición del diccionario stateTransitions y el método AddStateTransition permite que el StateManager gestione múltiples transiciones potenciales para cada estado, aumentando la flexibilidad y complejidad de la máquina de estados. Al verificar dinámicamente las transiciones dentro del método UpdateStates, el StateManager permite que el enemigo responda a diferentes eventos y condiciones en tiempo real. El método actualizado asegura que el estado actual se actualice primero, seguido de la comprobación de posibles transiciones, lo que garantiza la correcta ejecución de la lógica del estado antes de tomar decisiones de transición.

Al implementar estos cambios, el StateManager se vuelve más capaz de manejar comportamientos complejos y variados, haciendo que las acciones del enemigo sean más dinámicas y receptivas al entorno del juego.

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 4

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Awesome!

Completion rate improved to 3.33

bookTransición de Estado

Desliza para mostrar el menú

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;
    }
}

En estas imágenes, observamos una clase Transition y una clase StatePourcentage. Estas clases trabajan en conjunto para gestionar las transiciones entre diferentes estados basándose en ciertas condiciones y probabilidades. A continuación, se explica de manera sencilla qué realiza este código:

Explicación

Clase StatePourcentage

Definición de la clase: La línea public class StatePourcentage define una clase llamada StatePourcentage. Esta clase almacena información sobre un estado y el porcentaje de probabilidad de transición a ese estado.

Variables miembro:

public State state; almacena una referencia a un estado. public float percentage; almacena el porcentaje de probabilidad de transición a este estado.

Constructor:

public StatePourcentage(State state, float percentage) es un método constructor. Recibe un State y un float como parámetros y los asigna a las variables miembro.

Clase Transition

Definición de la clase: La línea public class Transition define una clase llamada Transition. Esta clase gestiona la lógica para la transición entre estados basada en una condición y porcentajes.

Variables miembro: Func<bool> condition; es un delegado que almacena una función de condición. Esta función retorna un valor booleano que indica si se cumple la condición de transición.

List<StatePourcentage> availableStates; es una lista que almacena múltiples objetos StatePourcentage, representando los posibles estados a los que se puede transicionar y sus respectivas probabilidades.

Constructor: public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage) es un método constructor. Recibe una función de condición y un arreglo de objetos StatePourcentage como parámetros. Inicializa la variable miembro condition con la función de condición proporcionada y crea una nueva lista para availableStates, agregando cada objeto StatePourcentage del arreglo a esta lista.

Método GetState: public State GetState() es un método que determina a qué estado se debe transicionar basado en una selección aleatoria y los porcentajes definidos. Genera un número aleatorio entre 0 y 100 e itera a través de los estados disponibles, acumulando sus porcentajes hasta encontrar el estado que corresponde con el número aleatorio.

Método IsConditionMet: public bool IsConditionMet() es un método que verifica si se cumple la condición de transición llamando a la función de condición. Retorna el resultado de la función de condición.

Funcionamiento para Nuestro Enemigo

Configuración de transiciones: Se definen transiciones entre estados, especificando las condiciones bajo las cuales ocurren estas transiciones y las probabilidades de transición a cada estado.

Determinación del siguiente estado: Cuando se activa una transición, el método GetState() selecciona aleatoriamente el siguiente estado según las probabilidades definidas. Esto añade un elemento de imprevisibilidad al comportamiento del enemigo, haciéndolo más dinámico y desafiante.

Verificación de condiciones: El método IsConditionMet() se utiliza para comprobar si se cumplen las condiciones para una transición. Si la condición es verdadera, la transición puede ocurrir y el método GetState() determina el siguiente estado.

Gestor 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;
            }
        }
    }
}

Cambios y Adiciones

Diccionario de Transiciones de Estado: Dictionary<State, List<Transition>> stateTransitions; es un diccionario que almacena listas de transiciones para cada estado. Cada estado está asociado con una lista de posibles transiciones que pueden ser verificadas al actualizar el estado.

Constructor: stateTransitions = new Dictionary<State, List<Transition>>(); inicializa el diccionario stateTransitions en el constructor, asegurando que esté listo para almacenar transiciones para diferentes estados.

Método AddStateTransition: public void AddStateTransition(State state, Transition transition) es un método que añade una transición a la lista de transiciones para un estado dado. Si el estado aún no tiene una entrada en el diccionario, se crea una nueva entrada con una lista vacía de transiciones. Luego, la transición se añade a la lista de transiciones para el estado especificado.

Método UpdateStates: El método UpdateStates ha sido actualizado para primero verificar las transiciones obteniendo la lista de transiciones para el estado actual después de actualizarlo con currentState.UpdateState(deltaTime);. Luego evalúa cada transición en la lista para comprobar si se cumple la condición de transición usando transition.IsConditionMet(). Si se cumple una condición de transición, cambia el estado usando ChangeState(transition.GetState()); y rompe el ciclo para evitar múltiples cambios de estado en una sola actualización.

Razón de Estos Cambios

La adición del diccionario stateTransitions y el método AddStateTransition permite que el StateManager gestione múltiples transiciones potenciales para cada estado, aumentando la flexibilidad y complejidad de la máquina de estados. Al verificar dinámicamente las transiciones dentro del método UpdateStates, el StateManager permite que el enemigo responda a diferentes eventos y condiciones en tiempo real. El método actualizado asegura que el estado actual se actualice primero, seguido de la comprobación de posibles transiciones, lo que garantiza la correcta ejecución de la lógica del estado antes de tomar decisiones de transición.

Al implementar estos cambios, el StateManager se vuelve más capaz de manejar comportamientos complejos y variados, haciendo que las acciones del enemigo sean más dinámicas y receptivas al entorno del juego.

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 3. Capítulo 4
some-alt