Entrar
Últimos assuntos
» player não consegue andarpor lovn7 Qui 21 Nov 2024, 13:33
» É possível fazer istó no game maker
por William Lima Qui 21 Nov 2024, 10:56
» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por Lua Sáb 16 Nov 2024, 20:22
» (Resolvido) Cenario longo x Texture Pages
por josuedemoraes Sáb 16 Nov 2024, 15:31
» Kids' band
por Adilson Lucindo Santos Sex 15 Nov 2024, 12:23
» (RESOLVIDO) Engasgos-Troca de Sprites/animações
por josuedemoraes Ter 12 Nov 2024, 01:49
» Block Room - DEMO
por Joton Qua 06 Nov 2024, 22:58
» Game Infinito vertical (subindo)
por macmilam Sáb 26 Out 2024, 12:36
» Retorno da GMBR!!!
por Dancity Ter 22 Out 2024, 16:36
» Máquina de estados
por aminaro Qui 10 Out 2024, 13:33
» como faço pra um objeto colidir com o outro e diminuir a vida do player ?
por josuedemoraes Qui 03 Out 2024, 16:51
» RESOLVIDO: Colisão com objetos moveis
por josuedemoraes Qua 02 Out 2024, 20:28
» Crypt of the Blood Moon
por divin sphere Qua 11 Set 2024, 18:18
» como fazer um objeto seguir?
por divin sphere Dom 18 Ago 2024, 18:08
» Procuro de alguém para Modelar/Texturizar/Animar objetos 3D
por un00brn Dom 11 Ago 2024, 11:10
» Destruição de cenário (estilo DD Tank)
por CoronelZeg Sex 09 Ago 2024, 17:16
» RESOLVIDO-Como destruir uma instancia especifica de um objeto
por josuedemoraes Ter 23 Jul 2024, 00:40
» Automatizar a coleta de id
por GabrielXavier Seg 22 Jul 2024, 18:01
» Preciso de ajuda para concluir um pequeno projeto
por lmoura Qui 27 Jun 2024, 15:45
» ANGULO ACOMPANHAR O OBJETO
por Klinton Rodrigues Qui 27 Jun 2024, 08:34
» Musica reinicia quando sala reinicia
por GabrielXavier Ter 18 Jun 2024, 07:28
» como fazer uma copia de gd
por generico_cube Sex 14 Jun 2024, 15:48
» Square Adventure
por guilherme551 Ter 11 Jun 2024, 09:54
» como posso definir limite de uma variavel
por GabrielXavier Sex 07 Jun 2024, 14:14
» [Resolvido] Dúvida, colisão única de objeto
por vdm842 Sex 24 maio 2024, 09:50
Máquina de estado/State Machine no Unity
4 participantes
GMBR :: Ensine & Aprenda :: Exemplos :: Exemplos em geral
Página 1 de 1
Máquina de estado/State Machine no Unity
Como parte do pessoal aqui também tem interesse no Unity, resolvi postar essa máquina de estado que fiz para meu jogo e estou utilizando ela, ela está redondinha, faz tempo que to usando ela nesse projeto e não vi qualquer problema com ela.
State Machine / Máquina de estado com:
- Controle de estados centralizado da aplicação
- Estado por string
- Estados tem Create/Update e End
-Mudanças de estados podem ocorrer de um estado a outro, ou de qualquer estado
Classe: StateMachine.cs
Considerações sobre a implementação:
- Criei uma função pra poder voltar a um estado anterior: usei por um tempo depois decidi não usar mais, isso é fácil de gerar problemas porque tu não tem certeza de qual é o estado anterior (tu pode pensar que é um, mas se ocorreu algum anystate, vira outro logicamente). Eu não uso mais.
- Funções para pegar o estado atual dela não deveriam ser usadas em seu código, somente pra debug ou algo assim, porque é importante que tudo que envolve o estado, seja controlado dentro dela. Editado: Fazer o GET do estado atual para a IA seria aceitável.
Não sei quantos tem interesse, então postarei aqui sendo breve, mas qualquer pergunta de como funciona, por que usar algo assim, de implementação, ou outra coisa, sinta-se a vontade pra comentar
State Machine / Máquina de estado com:
- Controle de estados centralizado da aplicação
- Estado por string
- Estados tem Create/Update e End
-Mudanças de estados podem ocorrer de um estado a outro, ou de qualquer estado
Classe: StateMachine.cs
- Código:
using System;
using System.Collections.Generic;
using System.Linq;
/// Author: TGM, 2020
public class StateMachine
{
public string currentState { get; private set; }
public string previousState { get; private set; }
private Dictionary<string, StateActions> states;
private List<StateChanges> changesAnyState;
public const string PreviousState = "_previous";
public StateMachine(string state) {
currentState = state;
states = new Dictionary<string, StateActions>();
changesAnyState = new List<StateChanges>();
}
public bool IsCurrent(string[] states) => states != null && (states).Contains(currentState);
public void AddState(string name, Action create = null, Action update = null, Action end = null)
{
StateActions state = new StateActions(create, update, end);
states.Add(name, state);
}
public void AddChange(string from, string to, Func<bool> when, string[] exceptFrom = null)
{
StateActions stateFrom = states[from];
if (stateFrom == null) throw new Exception($"Invalid state(s): from: {from}, to: {to}");
stateFrom.changes.Add(new StateChanges(to, when, exceptFrom));
}
public void AddChangeAnyState(string to, Func<bool> when, string[] exceptFrom = null)
{
StateActions stateTo = states[to];
if (stateTo == null) throw new Exception($"Invalid to state: {to}");
changesAnyState.Add(new StateChanges(to, when, exceptFrom));
}
public void Update()
{
StateActions state = states[currentState];
state.update?.Invoke();
foreach (StateChanges change in state.changes)
{
bool changed = Change(change);
if (changed) break;
};
foreach (StateChanges anyChange in changesAnyState)
{
Change(anyChange);
}
}
private bool Change(StateChanges change)
{
if (change.when() && !(IsCurrent(change.exceptFrom)))
{
if (change.to != PreviousState)
{
previousState = currentState;
currentState = change.to;
} else
{
string oldState = currentState;
currentState = previousState;
previousState = oldState;
}
states[previousState].end?.Invoke();
states[currentState].create?.Invoke();
return true;
};
return false;
}
}
internal class StateActions
{
public Action create;
public Action update;
public Action end;
public List<StateChanges> changes;
public StateActions(Action create, Action update, Action end)
{
this.create = create;
this.update = update;
this.end = end;
changes = new List<StateChanges>();
}
}
internal class StateChanges
{
internal string to;
internal Func<bool> when;
internal string[] exceptFrom;
public StateChanges(string to, Func<bool> when, string[] exceptFrom)
{
this.to = to;
this.when = when;
this.exceptFrom = exceptFrom;
}
}
Considerações sobre a implementação:
- Criei uma função pra poder voltar a um estado anterior: usei por um tempo depois decidi não usar mais, isso é fácil de gerar problemas porque tu não tem certeza de qual é o estado anterior (tu pode pensar que é um, mas se ocorreu algum anystate, vira outro logicamente). Eu não uso mais.
- Funções para pegar o estado atual dela não deveriam ser usadas em seu código, somente pra debug ou algo assim, porque é importante que tudo que envolve o estado, seja controlado dentro dela. Editado: Fazer o GET do estado atual para a IA seria aceitável.
Não sei quantos tem interesse, então postarei aqui sendo breve, mas qualquer pergunta de como funciona, por que usar algo assim, de implementação, ou outra coisa, sinta-se a vontade pra comentar
Última edição por theguitarmester em Qui 02 Jul 2020, 21:37, editado 2 vez(es)
Re: Máquina de estado/State Machine no Unity
Cara, vou estudar isso! Obrigado por postar!
polosam- Games Ranking :
Notas recebidas : A + B
Data de inscrição : 20/12/2010
Reputação : 120
Número de Mensagens : 749
Prêmios :
x 0 x 0 x 0
x 1 x 1 x 0
x 0 x 0 x 0
Plataformas :- Game Maker 8.0 ou 8.1
- Game Maker Studio 1.4
Re: Máquina de estado/State Machine no Unity
Muito bom @theguitarmeister, máquinas de estado são muito importante, eu uso muito e não depende de linguagem, é um algoritmo muito importante para programação de jogos e pra quem usa o Unity pode se basear na sua implementação. Show!
Re: Máquina de estado/State Machine no Unity
@Polosam, Boa!
@Vinians, sim, bah, sem ela eu nem conseguiria continuar mexendo no jogo, cada funcionalidade a mais que tu coloca, sem máquina de estado vira um caos!
Bah, fiz esse post e disse que não precisava pegar o estado da máquina de estado por fora... aí agora eu to tendo que usar huehueheuheu
Mas é pra algo específico: Inteligência Artificial....
O inimigo e o player no meu jogos, eles são bem parecidos, é a mesma mecânica deles, e o player funciona com inputs do teclado que eu transformo em código, por exemplo: se tu apertar o botão esquerdo do mouse, tu vai setar uma variável de input como true, algo como 'inputAttack = 1', e a máquina de estado só vê esses inputs. Da mesma forma o inimigo vai funcionar (as versões atuais tem mais coisas além de input, tá misturado), só por input. A questão é que nós (pessoas) ativamos os inputs através de coisas que vemos visualmente, mas uma IA não vai agir pelo visual (poderia até fazer assim, mas não sei se acabaria o jogo até 2022 hue), então ela tem que ter uma forma melhor de 'enxergar' aonde estão as coisas, e qual o estado dela. Por isso a máquina de estado que criei pra IA, vai ter acesso ao estado da máquina de estado que cuida do comportamento de um Character/guerreiro hehe;
Ah, com isso eu decidi mudar o jeito do GET do estado, deixando ele pela variável com o método publico (mas SET privado).
Atualizei o código no post.
Outra coisa interessante seria usar ENUM para os nomes dos estados. Eu decidi não usar apenas para a implementação no momento ter ficado mais simples de mudanças rápidas, mas provavelmente em algum momento eu os colocarei.
@Vinians, sim, bah, sem ela eu nem conseguiria continuar mexendo no jogo, cada funcionalidade a mais que tu coloca, sem máquina de estado vira um caos!
Bah, fiz esse post e disse que não precisava pegar o estado da máquina de estado por fora... aí agora eu to tendo que usar huehueheuheu
Mas é pra algo específico: Inteligência Artificial....
O inimigo e o player no meu jogos, eles são bem parecidos, é a mesma mecânica deles, e o player funciona com inputs do teclado que eu transformo em código, por exemplo: se tu apertar o botão esquerdo do mouse, tu vai setar uma variável de input como true, algo como 'inputAttack = 1', e a máquina de estado só vê esses inputs. Da mesma forma o inimigo vai funcionar (as versões atuais tem mais coisas além de input, tá misturado), só por input. A questão é que nós (pessoas) ativamos os inputs através de coisas que vemos visualmente, mas uma IA não vai agir pelo visual (poderia até fazer assim, mas não sei se acabaria o jogo até 2022 hue), então ela tem que ter uma forma melhor de 'enxergar' aonde estão as coisas, e qual o estado dela. Por isso a máquina de estado que criei pra IA, vai ter acesso ao estado da máquina de estado que cuida do comportamento de um Character/guerreiro hehe;
Ah, com isso eu decidi mudar o jeito do GET do estado, deixando ele pela variável com o método publico (mas SET privado).
Atualizei o código no post.
Outra coisa interessante seria usar ENUM para os nomes dos estados. Eu decidi não usar apenas para a implementação no momento ter ficado mais simples de mudanças rápidas, mas provavelmente em algum momento eu os colocarei.
Re: Máquina de estado/State Machine no Unity
Cara, isso é fantastico, sempre penso isso ai, tipo o que um personagem do jogo "vê", tipo como se ele tivesse vida as vezes eu analiso assim também, pense que o doido fosse somente eu hahahah, tipo "tron" :-)A questão é que nós (pessoas) ativamos os inputs através de coisas que vemos visualmente, mas uma IA não vai agir pelo visual (poderia até fazer assim, mas não sei se acabaria o jogo até 2022 hue), então ela tem que ter uma forma melhor de 'enxergar' aonde estão as coisas, e qual o estado dela.
Re: Máquina de estado/State Machine no Unity
@Vinians haha
Poisé, pra uma 'IA' de Mário da vida, em geral os bichos não tem praticamente interação com o Player, eles existindo ou não, a movimentação deles seriam as mesmas (tirando alguns inimigos como o 'jogador de beisebol'), mas quanto mais tu vai aproximando a mecânica do inimigo a do player, mais ele vai tendo que ter alguma forma de 'ver o mundo', e a maneira mais fácil pra se fazer isso é com informações de controle que o player não tem (e mesmo se tivesse, não seria tão relevante muitas, porque tu consegue visualmente ver).
É um desafio criar uma IA boa mas também é um processo bem bacana, quando tu consegue estabelecer uma boa base lógica pra trabalhar em cima, e uma base boa é usar máquina de estado e ter o comportamento bem abstraido, organizado, não misturar papéis.
Poisé, pra uma 'IA' de Mário da vida, em geral os bichos não tem praticamente interação com o Player, eles existindo ou não, a movimentação deles seriam as mesmas (tirando alguns inimigos como o 'jogador de beisebol'), mas quanto mais tu vai aproximando a mecânica do inimigo a do player, mais ele vai tendo que ter alguma forma de 'ver o mundo', e a maneira mais fácil pra se fazer isso é com informações de controle que o player não tem (e mesmo se tivesse, não seria tão relevante muitas, porque tu consegue visualmente ver).
É um desafio criar uma IA boa mas também é um processo bem bacana, quando tu consegue estabelecer uma boa base lógica pra trabalhar em cima, e uma base boa é usar máquina de estado e ter o comportamento bem abstraido, organizado, não misturar papéis.
moisesBR gosta desta mensagem
Re: Máquina de estado/State Machine no Unity
Pessoal. Ainda nao consegui entender completamente essas maquinas. Mas tenho observado o qual util elas sao.
Tenho certa difjculdade para compreender algo. E me recuso usar algo qye eu nao entenda o funcionamento como usar uma engine pronta para fazer um game.
Sei que aqui nao é o local adequado, mas estou aproveitando a oportunidade, ha que tocaram no assunto.
Tem como simplificar ao naximo o uso dessa tal maquina?
Tipo: eu quero fazer eu mesmo do zero com minhas proprias nomenclaturas E etc!
Exemplo: quero usar uma maquina rao simplificada que usaria no máximo uns 3 estados!
E no caso no create as vars, no estepe as acoes basicas e mínimas e etc.
Porventura esses estados sao variaveis ou o que?
Apenas scripts? Tipo estou tentando criar minha versao de maquina nos steps usando variáveis definidas no create.
Nas estou encontrando entraves que travam outras coisas e etc.
Eu li, reli, vou ler de novo, mas nao entra na cachola desse velho careca de 44 anos.
Nas bao desisto sei que vou conseguir.
Tenho certa difjculdade para compreender algo. E me recuso usar algo qye eu nao entenda o funcionamento como usar uma engine pronta para fazer um game.
Sei que aqui nao é o local adequado, mas estou aproveitando a oportunidade, ha que tocaram no assunto.
Tem como simplificar ao naximo o uso dessa tal maquina?
Tipo: eu quero fazer eu mesmo do zero com minhas proprias nomenclaturas E etc!
Exemplo: quero usar uma maquina rao simplificada que usaria no máximo uns 3 estados!
E no caso no create as vars, no estepe as acoes basicas e mínimas e etc.
Porventura esses estados sao variaveis ou o que?
Apenas scripts? Tipo estou tentando criar minha versao de maquina nos steps usando variáveis definidas no create.
Nas estou encontrando entraves que travam outras coisas e etc.
Eu li, reli, vou ler de novo, mas nao entra na cachola desse velho careca de 44 anos.
Nas bao desisto sei que vou conseguir.
Re: Máquina de estado/State Machine no Unity
Olá Moises, como vai ?
As máquinas de estado finito (Finite State Machines) são um algoritmo usado bastante pra fazer jogos é ótimo que você tenha interesse.
Mas pra te dar uma dica, não se baseie na implementação acima, ela está ótima mas está complexa pra você entender, e na verdade é bem simples.
Seria melhor você procurar na internet por "Finite State Machine" que existem várias expliações bem simples lá. Mas no modo mais básico que uso seria você declarar uma variavel no create por exemplo:
Neste caso o estado inicia com 1 que pode representar qualquer coisa para este objeto. Mas assim que certas condições forem atendidas ela muda de estado. Você pode usar enums para dar nome a cada estado fica mais fácil que simplesmente 1, ou usar uma string mesmo, nada impede.
Por exemplo, como você faria um código de um inimigo patrulhando um local ? Poderia ser assim:
No estado 1 ele está de um lado para o outro, so faz isso.
Mas quando ele "vê" o player ele muda para o estado 2 que é "perseguição" essa seria a condição de mudança do estado 1 (patrulha) para o 2 (perseguição), e poderia ter um terceiro (ataque).
Depois ele correndo atras do player ele vê que o player está muito longe e desiste, assim ele volta para o estado 1 e o ciclo se inicia.
Viu como a maquina de estados separa as coisas ? Isso facilita muito a criação de AI simples.
Qualquer coisa posta ai!
As máquinas de estado finito (Finite State Machines) são um algoritmo usado bastante pra fazer jogos é ótimo que você tenha interesse.
Mas pra te dar uma dica, não se baseie na implementação acima, ela está ótima mas está complexa pra você entender, e na verdade é bem simples.
Seria melhor você procurar na internet por "Finite State Machine" que existem várias expliações bem simples lá. Mas no modo mais básico que uso seria você declarar uma variavel no create por exemplo:
- Código:
state = 1; // estado inicial da maquina
Neste caso o estado inicia com 1 que pode representar qualquer coisa para este objeto. Mas assim que certas condições forem atendidas ela muda de estado. Você pode usar enums para dar nome a cada estado fica mais fácil que simplesmente 1, ou usar uma string mesmo, nada impede.
Por exemplo, como você faria um código de um inimigo patrulhando um local ? Poderia ser assim:
No estado 1 ele está de um lado para o outro, so faz isso.
Mas quando ele "vê" o player ele muda para o estado 2 que é "perseguição" essa seria a condição de mudança do estado 1 (patrulha) para o 2 (perseguição), e poderia ter um terceiro (ataque).
Depois ele correndo atras do player ele vê que o player está muito longe e desiste, assim ele volta para o estado 1 e o ciclo se inicia.
Viu como a maquina de estados separa as coisas ? Isso facilita muito a criação de AI simples.
Qualquer coisa posta ai!
Re: Máquina de estado/State Machine no Unity
Exatamente o que estou fazendo!
O que me deixava caduco era essa tal FMS.
Mas andei fazendo uns teste, e de certa forma usei essa estrategia de estados. So me confundia pq n sabia o q era esses estados. Se era variáveis, scripts ou outra coisa.
Descobri ou acredito que sao mesmo variáveis.
Eu costumava ate recententemente usar
Situacao="acao". E usava isso no draw para ver/debugar o q tava rolando. Mas dwscobri que o sistema nao obedece!
Entao voltei a usar variaveis para cada situação.
Acho que vou criar um topico pra isso.
Como estou sem internet no pc, ta complicado mas vou tentar.
E questao de honra concluir nao so esse mas outros varios projetos que tenho.
O que me deixava caduco era essa tal FMS.
Mas andei fazendo uns teste, e de certa forma usei essa estrategia de estados. So me confundia pq n sabia o q era esses estados. Se era variáveis, scripts ou outra coisa.
Descobri ou acredito que sao mesmo variáveis.
Eu costumava ate recententemente usar
Situacao="acao". E usava isso no draw para ver/debugar o q tava rolando. Mas dwscobri que o sistema nao obedece!
Entao voltei a usar variaveis para cada situação.
Acho que vou criar um topico pra isso.
Como estou sem internet no pc, ta complicado mas vou tentar.
E questao de honra concluir nao so esse mas outros varios projetos que tenho.
Re: Máquina de estado/State Machine no Unity
eae,
Bom, é como comentei no post do meu jogo sobre como estava fazendo no início, que se tratava de uma 'míni máquina de estado', máquina de estado fake, ou controle de estado hehe, chame como quiser hue
A vantagem de tu fazer uma máquina de estado em que ela troca o estado, é que tu consegue facilmente ter eventos de start e end do state, porém controlar o estado direto por um switch é uma abordagem boa também, e acho que tu só precisa mudar pra uma maquina de estados, quando começar a se sentir desconfortável controlando o estado só por switch. Foi o que eu fiz tanto para o estado de comportamento, quanto o de IA do meu jogo, primeiro fiz utilizando uma variável de estado e um switch, e depois criei/utilizei essa do script aí.
Como o @Vinians já explicou bem, mas então só complementando, uma maneira bem simples seria controlar o comportamento de alguma coisa, desse modo:
tu pode, mas não é necessário, criar outro switch só pra tratar daí as mudanças de estado, por exemplo:
Bom, é como comentei no post do meu jogo sobre como estava fazendo no início, que se tratava de uma 'míni máquina de estado', máquina de estado fake, ou controle de estado hehe, chame como quiser hue
A vantagem de tu fazer uma máquina de estado em que ela troca o estado, é que tu consegue facilmente ter eventos de start e end do state, porém controlar o estado direto por um switch é uma abordagem boa também, e acho que tu só precisa mudar pra uma maquina de estados, quando começar a se sentir desconfortável controlando o estado só por switch. Foi o que eu fiz tanto para o estado de comportamento, quanto o de IA do meu jogo, primeiro fiz utilizando uma variável de estado e um switch, e depois criei/utilizei essa do script aí.
Como o @Vinians já explicou bem, mas então só complementando, uma maneira bem simples seria controlar o comportamento de alguma coisa, desse modo:
- Código:
estado = "parado"
- Código:
switch estado {
case "movimento": hspeed=dirHorizontal; vspeed=dirVertical; break;
case "ataque": atacar(); break;
}
tu pode, mas não é necessário, criar outro switch só pra tratar daí as mudanças de estado, por exemplo:
- Código:
switch estado {
case "movimento": if (atk) estado = "ataque";break;
case "ataque": if (!atk) estado = "movimento"; break;
}
moisesBR gosta desta mensagem
Tópicos semelhantes
» A Máquina
» Máquina de estados
» A Máquina - 1º Capítulo
» Unity 3D, C++,JS, C#?
» Simulador de maquina do tempo
» Máquina de estados
» A Máquina - 1º Capítulo
» Unity 3D, C++,JS, C#?
» Simulador de maquina do tempo
GMBR :: Ensine & Aprenda :: Exemplos :: Exemplos em geral
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos