Inspiaaa / UnityHFSM

A simple yet powerful class-based hierarchical finite state machine for Unity
MIT License
1.05k stars 121 forks source link

How to use AddTransition in two different TStateId based by enum? #36

Closed Wumuuu closed 5 months ago

Wumuuu commented 9 months ago

Use an example from the wik.

enum PlayerStates {
    MOVE, JUMP
}

enum MoveStates {
    WALK, DASH
}

enum JumpStates {
    JUMP,FALL
}

enum Events {
    ON_DAMAGE, ON_WIN
}
var fsm = new StateMachine<PlayerStates, Events>();
var moveFsm = new StateMachine<PlayerStates, MoveStates, Events>();
var jumpFsm = new StateMachine<PlayerStates, JumpStates, Events>();

fsm.AddState(PlayerStates.MOVE, moveFsm);
fsm.AddState(PlayerStates.JUMP, jumpFsm);

moveFsm.AddState(MoveStates.WALK);
moveFsm.AddState(MoveStates.DASH);
moveFsm.AddTransition(new Transition<MoveStates>(MoveStates.WALK, MoveStates.DASH));

jumpFsm.AddState(JumpStates.JUMP);
jumpFsm.AddState(JumpStates.FALL);
jumpFsm.AddTransition(new Transition<JumpStates>(JumpStates.JUMP, JumpStates.FALL));

//It will get an error.
moveFsm.AddTransition(MoveStates.DASH,JumpStates.FALL);

I'm new to coding,I only know a compromise thatfsm.AddTransition(PlayerStates.MOVE,PlayerStates.JUMP) and then jumpFsm.SetStartState(JumpStates.FALL).

sandsalamand commented 9 months ago

You can't transition from one enum type to another within the same StateMachine. You're trying to transition from a MoveState to a JumpState, but moveFsm was defined as a StateMachine<PlayerStates, MoveStates, Events>, with the second T parameter, MoveStates, showing that moveFsm will only allow transitions between MoveStates. The first T there, PlayerStates, is only applicable if you're nesting the state machines.

See on the line fsm.AddState(PlayerStates.MOVE, moveFsm); They're adding moveFsm to fsm as a nested state machine. This is possible because moveFsm had \ as its first parameter, meaning that you're allowed to nest it under fsm which transitions between PlayerStates.