0 votes

Hi,

I'm trying to wrap my head around the node-based state machine structure. I'm reverse engineering the "Finite state machine" demo and trying to define which direction to move the player in 2d with a local event for mobile touch input.

It seems that makeinputlocal is only available for use when extended to KinematicBody2d. Anywhere else in the tree it gives error "method not declared".

(I have a usable version of player movement with all code in one file, but is is getting difficult to maintain with more states. Which is why I'm trying to split it to different files.)

Questions:
- What are the limitations on applying "makeinputlocal"? The docs are unclear on this.
- What would be the most simple node based state machine structure? A tutorial on this?
- Where and how in state machine should I define local event touch controls?

I'll add more detailed information in the comments.

in Engine by (51 points)

At the moment the input direction in the demo is defined with this (in motion.gd):

func get_input_direction():
    var input_direction = Vector2()
    input_direction.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
    input_direction.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
    return input_direction

My usable version of movement detects the direction of the touch from player, like this:

func _input(event):
    if event is InputEventMouseButton and event.button_index == BUTTON_LEFT:
        if event.pressed:
            var local_event = make_input_local(event)
            if local_event.position.x > 20: 
                state = STATES.MoveRight
            elif local_event.position.x < -20:
                state = STATES.MoveLeft
            elif round(local_event.position.x) in range(-19, 19):
                if is_on_ladder:
                    state = STATES.Climb
                elif not is_on_ladder:
                    state = STATES.Jump
        else:
            state = STATES.Idle

The node structure of the demo is:

KinematicBody2d
    State machine
        Idle
        Move
        Jump

The script structure of the demo is:

player_controller.gd (extends KinematicBody2d)
state_machine.gd (extends Node "StateMachine")
player_node_state_machine.gd (extends Node "StateMachine")
state.gd (extends Node "StateMachine")
    motion.gd
        on_ground.gd
              idle
              move.gd
        on_air.gd
              jump

1 Answer

+1 vote

What are the limitations on applying make_input_local? The docs are unclear on this.

No, the documentation is pretty clear about this! make_input_local is a method of the CanvasItem-class, which states at the top that it is inherited by Control and Node2D. So these two nodes and everything than inherits from them directly or indirectly allows for using make_input_local. Judging from your description you might have tried to call make_input_local in a script extending a Node (not a Node2D!) - that indeed won't work as it's not inheriting from CanvasItem.

What would be the most simple node based state machine structure? A tutorial on this?

Have you checked out GDQuest's video on Finite State Machines?

by (10,467 points)

Thank you for answering, that cleared makeinputlocal (and the overall logic) to me. I made a new version of touch controls with (invisible) touchscreenbuttons, which seems to work very well. This allows me to map them directly as "basic" inputs, and I was able to work around makeinputlocal problems.

I've familiarized myself with GDQuest's tutorial on youtube, Godot and github, and also checked out all the available tutorials on youtube. I'm starting to understand how the concept works, but mapping out all the connections seems to take time (since I don't have developer background, I guess).

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.