GMBR
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Entrar

Esqueci-me da senha

Últimos assuntos
» Problema ao entrar por uma porta e voltar por ela
por aminaro Hoje à(s) 10:08

» Alguém aqui já ganha dinheiro com seus games?
por theguitarmester Ter 30 Abr 2024, 11:43

» Colisões não funcionando
por theguitarmester Ter 30 Abr 2024, 10:16

» Como ajustar velocidade de cada frame da animação no game maker
por pequetux Sex 26 Abr 2024, 16:45

» Preciso de ajuda
por AftonDuGrau Dom 21 Abr 2024, 20:18

» Como faz o evento drawn GUI, não se repetir?
por aminaro Sex 19 Abr 2024, 20:30

» PROBLEMAS COM FÍSICAS DE ÁGUA
por aminaro Ter 16 Abr 2024, 10:07

» Retorno da GMBR!!!
por Ralphed Sex 12 Abr 2024, 22:45

» JOGADOR PARANDO NO AR QUANDO ATACA
por aminaro Qua 10 Abr 2024, 13:51

» Problemas com texto interativo
por Kaaru72 Dom 07 Abr 2024, 11:31

» Erro escondido e indecifrável
por dev_gabize.azv Qui 04 Abr 2024, 10:11

» Mudar cor de apenas uma palavra
por Ralphed Sáb 30 Mar 2024, 00:39

» Procuro Programador de game maker
por Wou Sex 15 Mar 2024, 10:27

» Mod APK
por gamerainha Qua 13 Mar 2024, 06:30

» Aceito pedidos de sprites (Com exemplos meus)
por Sevilha Qua 28 Fev 2024, 12:17

» Inventário simples
por Isquilo_Roedor Qui 22 Fev 2024, 15:18

» Problemas na programaçnao de inimigo [jogo DOOM LIKE]
por Black Mirror Dom 11 Fev 2024, 13:34

» ANDROID MULTI TOUCH
por DiegoBr Dom 04 Fev 2024, 12:13

» Servidor de Discord do fórum?
por Lighter Sáb 27 Jan 2024, 17:18

» Save e Load Json
por Klinton Rodrigues Qui 25 Jan 2024, 11:12

» Colisão com mais de um objeto
por aminaro Seg 22 Jan 2024, 15:02

» Oi sou novo aqui
por Thiago Silveira Alexandre Sáb 20 Jan 2024, 20:55

» Como acessar conteudo comprado no marketplace
por macmilam Sex 19 Jan 2024, 07:42

» Devlogs em vídeos do Block Room
por Joton Seg 15 Jan 2024, 16:56

» ACERVO GMBR MAGAZINE
por Joton Qui 11 Jan 2024, 19:21


Máquina de estado/State Machine no Unity

4 participantes

Ir para baixo

Máquina de estado/State Machine no Unity Empty Máquina de estado/State Machine no Unity

Mensagem por theguitarmester Qua 01 Jul 2020, 15:58

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
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 Smile


Última edição por theguitarmester em Qui 02 Jul 2020, 21:37, editado 2 vez(es)
theguitarmester
theguitarmester

Games Ranking : Nota C

Notas recebidas : B + C
Data de inscrição : 28/02/2012
Reputação : 139
Número de Mensagens : 2211
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 4 Moedas x 0

Ouro x 2 Prata x 2 Bronze x 1

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Plataformas :
  • Unity


http://guitarmester.no.comunidades.net/index.php?pagina=19362978

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por polosam Qua 01 Jul 2020, 21:21

Cara, vou estudar isso! Obrigado por postar!
polosam
polosam

Games Ranking : Nota A

Notas recebidas : A + B
Data de inscrição : 20/12/2010
Reputação : 120
Número de Mensagens : 749
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 1 Prata x 1 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Plataformas :
  • Game Maker 8.0 ou 8.1
  • Game Maker Studio 1.4


Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por vinians Qui 02 Jul 2020, 12:03

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!
vinians
vinians

Games Ranking : Nota B

Notas recebidas : B-C-A-C
Data de inscrição : 18/09/2008
Reputação : 90
Número de Mensagens : 2715
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 1 Moedas x 0

Ouro x 0 Prata x 2 Bronze x 1

Insignia 1 x 0 Insignia 2 x 1 Insignia 3 x 0
Plataformas :
  • Game Maker 8.0 ou 8.1
  • Game Maker Studio 1.4
  • Game Maker Studio 2.0
  • Construct 2
  • Java
  • C#
  • Javascript
  • C ou C++
  • Outros


https://vinians.itch.io

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por theguitarmester Qui 02 Jul 2020, 21:35

@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.
theguitarmester
theguitarmester

Games Ranking : Nota C

Notas recebidas : B + C
Data de inscrição : 28/02/2012
Reputação : 139
Número de Mensagens : 2211
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 4 Moedas x 0

Ouro x 2 Prata x 2 Bronze x 1

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Plataformas :
  • Unity


http://guitarmester.no.comunidades.net/index.php?pagina=19362978

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por vinians Qui 02 Jul 2020, 22:31

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. 
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" :-)
vinians
vinians

Games Ranking : Nota B

Notas recebidas : B-C-A-C
Data de inscrição : 18/09/2008
Reputação : 90
Número de Mensagens : 2715
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 1 Moedas x 0

Ouro x 0 Prata x 2 Bronze x 1

Insignia 1 x 0 Insignia 2 x 1 Insignia 3 x 0
Plataformas :
  • Game Maker 8.0 ou 8.1
  • Game Maker Studio 1.4
  • Game Maker Studio 2.0
  • Construct 2
  • Java
  • C#
  • Javascript
  • C ou C++
  • Outros


https://vinians.itch.io

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por theguitarmester Qui 02 Jul 2020, 23:02

@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.
theguitarmester
theguitarmester

Games Ranking : Nota C

Notas recebidas : B + C
Data de inscrição : 28/02/2012
Reputação : 139
Número de Mensagens : 2211
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 4 Moedas x 0

Ouro x 2 Prata x 2 Bronze x 1

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Plataformas :
  • Unity


http://guitarmester.no.comunidades.net/index.php?pagina=19362978

moisesBR gosta desta mensagem

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por moisesBR Dom 05 Jul 2020, 18:42

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.
moisesBR
moisesBR

Data de inscrição : 24/10/2009
Reputação : 15
Número de Mensagens : 885
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Plataformas :
  • Game Maker 8.0 ou 8.1


http://inprovise.blogspot.com/

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por vinians Seg 06 Jul 2020, 09:15

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:
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!
vinians
vinians

Games Ranking : Nota B

Notas recebidas : B-C-A-C
Data de inscrição : 18/09/2008
Reputação : 90
Número de Mensagens : 2715
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 1 Moedas x 0

Ouro x 0 Prata x 2 Bronze x 1

Insignia 1 x 0 Insignia 2 x 1 Insignia 3 x 0
Plataformas :
  • Game Maker 8.0 ou 8.1
  • Game Maker Studio 1.4
  • Game Maker Studio 2.0
  • Construct 2
  • Java
  • C#
  • Javascript
  • C ou C++
  • Outros


https://vinians.itch.io

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por moisesBR Seg 06 Jul 2020, 11:45

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.

moisesBR
moisesBR

Data de inscrição : 24/10/2009
Reputação : 15
Número de Mensagens : 885
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0
Plataformas :
  • Game Maker 8.0 ou 8.1


http://inprovise.blogspot.com/

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por theguitarmester Ter 07 Jul 2020, 22:17

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:

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

Games Ranking : Nota C

Notas recebidas : B + C
Data de inscrição : 28/02/2012
Reputação : 139
Número de Mensagens : 2211
Prêmios : Máquina de estado/State Machine no Unity Empty

Medalhas x 0 Tutoriais x 4 Moedas x 0

Ouro x 2 Prata x 2 Bronze x 1

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 1
Plataformas :
  • Unity


http://guitarmester.no.comunidades.net/index.php?pagina=19362978

moisesBR gosta desta mensagem

Ir para o topo Ir para baixo

Máquina de estado/State Machine no Unity Empty Re: Máquina de estado/State Machine no Unity

Mensagem por Conteúdo patrocinado


Conteúdo patrocinado


Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos