Estado de Corrida
public abstract class State
{
public bool isStateFinished;
public abstract void StartState();
public virtual void UpdateState()
{
}
public abstract void EndState();
public virtual void FinishState()
{
isStateFinished = true;
}
}
Alterações e Adições
Variável isStateFinished:
Variável booleana que indica se o estado finalizou sua execução.
Método FinishState:
Novo método virtual que define isStateFinished como true.
Por ser virtual, permite que classes derivadas sobrescrevam este método caso precisem executar ações adicionais ao finalizar um estado.
Por que essas alterações foram feitas
As alterações introduzem a variável isStateFinished para rastrear a conclusão do estado e o método FinishState para padronizar o sinal de término do estado, permitindo que classes derivadas adicionem lógica personalizada ao finalizar o estado.
Estado de Corrida
public class RunState : State
{
Rigidbody2D rb;
Animator animator;
Transform player;
float speed;
Vector2 scale;
Vector2 velocity;
public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
{
this.animator = animator;
player = p;
this.speed = speed;
this.rb = rb;
scale = rb.transform.localScale;
velocity = new Vector2();
}
public override void StartState()
{
isStateFinished = false;
animator.SetBool("run", true);
}
public override void UpdateState(float DeltaTime)
{
scale.x = rb.position.x > player.position.x ? -1 : 1;
rb.transform.localScale = scale;
velocity.x = scale.x * speed;
rb.velocity = velocity;
}
public override void EndState()
{
animator.SetBool("run", false);
}
}
Vamos analisar a classe RunState, que herda da classe State. Esta classe é responsável por gerenciar o comportamento de corrida do inimigo. O foco será nas adições e alterações feitas nesta classe.
Construtor:
public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed);
Este construtor inicializa o RunState com os componentes necessários: um Rigidbody2D para movimentação, um Animator para animações, um Transform para rastrear o jogador e uma speed para definir a velocidade de corrida do inimigo;
Método StartState:
public override void StartState();
Este método define isStateFinished como false e ativa a animação de corrida ao definir o parâmetro booleano "run" no animator como true.
Método UpdateState:
public override void UpdateState(float DeltaTime);
Este método atualiza a posição e orientação do inimigo com base na posição do jogador;
Ajusta a escala do inimigo para que ele fique voltado para o jogador, calcula a velocidade de acordo com o valor de speed e aplica essa velocidade ao Rigidbody2D.
Método EndState:
public override void EndState()
Este método interrompe a animação de corrida ao definir o parâmetro booleano "run" no animator como false.
Funcionamento para o Inimigo
-
Movimentação e Animação: Utilizando
Rigidbody2DeAnimator, oRunStategarante que o inimigo se mova suavemente e apresente animações correspondentes. Isso torna o comportamento visual e fisicamente realista; -
Rastreamento da Posição do Jogador: O transform
playerpermite que o inimigo sempre se mova em direção ao jogador, o que é essencial para comportamentos de perseguição ou fuga; -
Controle de Direção: Ajustar o
scale.xcom base na posição do jogador garante que o inimigo fique voltado corretamente para o jogador enquanto corre, aumentando o realismo; -
Atualizações Dinâmicas de Estado: O método
UpdateStateé chamado a cada frame para ajustar continuamente o movimento e a direção do inimigo com base na posição do jogador, tornando o inimigo responsivo e dinâmico.
Inicialização do Inimigo
private void Start()
{
idle = new IdleState(animator);
runState = new RunState(GetComponent<Rigidbody2D>(), animator, player, speed);
stateManager = new StateManager(idle);
FarAwayTransition = new Transition(() =>
{
return (ThresholdDistance < Vector2.Distance(transform.position, player.position));
}, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));
toIdleTransition = new Transition(() =>
{
return stateManager.GetCurrentState().isStateFinished;
}, new StatePourcentage(idle, 100));
finishRunning = new Transition(() =>
{
return (ThresholdDistance >= Vector2.Distance(transform.position, player.position));
}, new StatePourcentage(idle, 100));
stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);
}
Explicação
Inicialização de Estado:
As variáveis idle e runState são inicializadas com seus respectivos estados. A variável idle é uma instância de IdleState com o animator passado como parâmetro, enquanto runState é uma instância de RunState que inclui um Rigidbody2D, um Animator, um Transform para o jogador e um valor de velocidade.
Inicialização do StateManager:
stateManager = new StateManager(idle);
O StateManager é inicializado com o estado idle como estado inicial.
Definições de Transição:
-
FarAwayTransition:
FarAwayTransition = new Transition(() => { return (ThresholdDistance < Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));; Esta transição verifica se o jogador está mais distante queThresholdDistance; -
toIdleTransition:
toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100));Esta transição verifica se o estado atual foi finalizado. Se verdadeiro, transita para o estadoidlecom 100% de probabilidade. -
finishRunning:
finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100));Esta transição verifica se o jogador está mais próximo queThresholdDistance. Se verdadeiro, transita para o estadoidlecom 100% de probabilidade.
Adicionando Transições ao StateManager:
stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);
Essas linhas adicionam as transições definidas ao stateManager.
Por Que Fizemos Desta Forma
Mudanças Dinâmicas de Estado:
As transições permitem que o inimigo altere seu comportamento dinamicamente com base na posição do jogador e no status de conclusão do estado atual, tornando o inimigo mais responsivo e interativo dentro do ambiente do jogo.
Transições Condicionais:
O uso de condições (como verificação de distância ou conclusão de estado) garante que as transições de estado ocorram de maneira lógica e apropriada, aumentando o realismo da jogabilidade.
Transições Baseadas em Probabilidade:
O uso de StatePourcentage permite transições baseadas em probabilidade, adicionando um elemento de imprevisibilidade e variedade ao comportamento do inimigo.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
Pergunte-me perguntas sobre este assunto
Resumir este capítulo
Mostrar exemplos do mundo real
Awesome!
Completion rate improved to 3.33
Estado de Corrida
Deslize para mostrar o menu
public abstract class State
{
public bool isStateFinished;
public abstract void StartState();
public virtual void UpdateState()
{
}
public abstract void EndState();
public virtual void FinishState()
{
isStateFinished = true;
}
}
Alterações e Adições
Variável isStateFinished:
Variável booleana que indica se o estado finalizou sua execução.
Método FinishState:
Novo método virtual que define isStateFinished como true.
Por ser virtual, permite que classes derivadas sobrescrevam este método caso precisem executar ações adicionais ao finalizar um estado.
Por que essas alterações foram feitas
As alterações introduzem a variável isStateFinished para rastrear a conclusão do estado e o método FinishState para padronizar o sinal de término do estado, permitindo que classes derivadas adicionem lógica personalizada ao finalizar o estado.
Estado de Corrida
public class RunState : State
{
Rigidbody2D rb;
Animator animator;
Transform player;
float speed;
Vector2 scale;
Vector2 velocity;
public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
{
this.animator = animator;
player = p;
this.speed = speed;
this.rb = rb;
scale = rb.transform.localScale;
velocity = new Vector2();
}
public override void StartState()
{
isStateFinished = false;
animator.SetBool("run", true);
}
public override void UpdateState(float DeltaTime)
{
scale.x = rb.position.x > player.position.x ? -1 : 1;
rb.transform.localScale = scale;
velocity.x = scale.x * speed;
rb.velocity = velocity;
}
public override void EndState()
{
animator.SetBool("run", false);
}
}
Vamos analisar a classe RunState, que herda da classe State. Esta classe é responsável por gerenciar o comportamento de corrida do inimigo. O foco será nas adições e alterações feitas nesta classe.
Construtor:
public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed);
Este construtor inicializa o RunState com os componentes necessários: um Rigidbody2D para movimentação, um Animator para animações, um Transform para rastrear o jogador e uma speed para definir a velocidade de corrida do inimigo;
Método StartState:
public override void StartState();
Este método define isStateFinished como false e ativa a animação de corrida ao definir o parâmetro booleano "run" no animator como true.
Método UpdateState:
public override void UpdateState(float DeltaTime);
Este método atualiza a posição e orientação do inimigo com base na posição do jogador;
Ajusta a escala do inimigo para que ele fique voltado para o jogador, calcula a velocidade de acordo com o valor de speed e aplica essa velocidade ao Rigidbody2D.
Método EndState:
public override void EndState()
Este método interrompe a animação de corrida ao definir o parâmetro booleano "run" no animator como false.
Funcionamento para o Inimigo
-
Movimentação e Animação: Utilizando
Rigidbody2DeAnimator, oRunStategarante que o inimigo se mova suavemente e apresente animações correspondentes. Isso torna o comportamento visual e fisicamente realista; -
Rastreamento da Posição do Jogador: O transform
playerpermite que o inimigo sempre se mova em direção ao jogador, o que é essencial para comportamentos de perseguição ou fuga; -
Controle de Direção: Ajustar o
scale.xcom base na posição do jogador garante que o inimigo fique voltado corretamente para o jogador enquanto corre, aumentando o realismo; -
Atualizações Dinâmicas de Estado: O método
UpdateStateé chamado a cada frame para ajustar continuamente o movimento e a direção do inimigo com base na posição do jogador, tornando o inimigo responsivo e dinâmico.
Inicialização do Inimigo
private void Start()
{
idle = new IdleState(animator);
runState = new RunState(GetComponent<Rigidbody2D>(), animator, player, speed);
stateManager = new StateManager(idle);
FarAwayTransition = new Transition(() =>
{
return (ThresholdDistance < Vector2.Distance(transform.position, player.position));
}, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));
toIdleTransition = new Transition(() =>
{
return stateManager.GetCurrentState().isStateFinished;
}, new StatePourcentage(idle, 100));
finishRunning = new Transition(() =>
{
return (ThresholdDistance >= Vector2.Distance(transform.position, player.position));
}, new StatePourcentage(idle, 100));
stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);
}
Explicação
Inicialização de Estado:
As variáveis idle e runState são inicializadas com seus respectivos estados. A variável idle é uma instância de IdleState com o animator passado como parâmetro, enquanto runState é uma instância de RunState que inclui um Rigidbody2D, um Animator, um Transform para o jogador e um valor de velocidade.
Inicialização do StateManager:
stateManager = new StateManager(idle);
O StateManager é inicializado com o estado idle como estado inicial.
Definições de Transição:
-
FarAwayTransition:
FarAwayTransition = new Transition(() => { return (ThresholdDistance < Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));; Esta transição verifica se o jogador está mais distante queThresholdDistance; -
toIdleTransition:
toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100));Esta transição verifica se o estado atual foi finalizado. Se verdadeiro, transita para o estadoidlecom 100% de probabilidade. -
finishRunning:
finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100));Esta transição verifica se o jogador está mais próximo queThresholdDistance. Se verdadeiro, transita para o estadoidlecom 100% de probabilidade.
Adicionando Transições ao StateManager:
stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);
Essas linhas adicionam as transições definidas ao stateManager.
Por Que Fizemos Desta Forma
Mudanças Dinâmicas de Estado:
As transições permitem que o inimigo altere seu comportamento dinamicamente com base na posição do jogador e no status de conclusão do estado atual, tornando o inimigo mais responsivo e interativo dentro do ambiente do jogo.
Transições Condicionais:
O uso de condições (como verificação de distância ou conclusão de estado) garante que as transições de estado ocorram de maneira lógica e apropriada, aumentando o realismo da jogabilidade.
Transições Baseadas em Probabilidade:
O uso de StatePourcentage permite transições baseadas em probabilidade, adicionando um elemento de imprevisibilidade e variedade ao comportamento do inimigo.
Obrigado pelo seu feedback!