Calling Gdscript from javascript to move my character

Godot Version

4.3 stable

Question

hi, I am really new to this and trying to call a gdscript function to move my character using javascipt from frontend to my web export game by clicking 2 button sending either true or false to move my character

error when clicking button , i recieve the data but it doesnt move the character

Received move action: {action: 'move', value: true}
VM1371:6 Uncaught ReferenceError: move_up is not defined
    at eval (eval at _godot_js_eval (index.js:9:741633),

here is my player.gd code that i want to move

extends CharacterBody2D

func _ready():

	# Add JavaScript listener for messages from the parent page
	JavaScriptBridge.eval("""
		window.addEventListener('message', function(event) {
			if (event.data && event.data.action === 'move') {
				console.log("Received move action:", event.data);
				if (event.data.value === true) {
					move_up();  // Call the move_up
				} else {
					move_diagonal();  // Call the move_diagonal
				}
			}
		});
	""")
	$AnimatedSprite2D.play("front_walk")
# You need to add velocity or direction for movement to work properly
func _physics_process(delta: float) -> void:
	if velocity != Vector2.ZERO:
		move_and_slide()

# Function to move up
func move_up():
	print("Move Up!")
	velocity = Vector2(0, -200)  # Move up with speed 200

# Function to move diagonally
func move_diagonal():
	print("Move Diagonal!")
	velocity = Vector2(200, -200)  # Move diagonally (right and up)

here is the frontend code that have 2 button to move my character

"use client";
import { useRef } from "react";

export default function GamePage() {
  const iframeRef = useRef();

  // Function to send movement commands to Godot
  const sendCommandToGodot = (value) => {
    if (iframeRef.current && iframeRef.current.contentWindow) {
      iframeRef.current.contentWindow.postMessage(
        { action: "move", value }, // Sending move action with true/false
        "*"
      );
    }
  };

  return (
    <div style={{ width: "100%", height: "100%" }}>
      {/* Embed the Godot game using an iframe */}
      <iframe
        id="godot_iframe"
        ref={iframeRef}
        src="/game/index.html" // Path to the exported Godot game
        style={{
          width: "100%",
          height: "500px",
          border: "none",
        }}
      ></iframe>

      {/* Buttons to control the Godot game */}
      <div style={{ marginTop: "20px", textAlign: "center" }}>
        <button onClick={() => sendCommandToGodot(true)}> Move up</button>
        <button onClick={() => sendCommandToGodot(false)}>
          {" "}
          Move diagonally
        </button>
      </div>
    </div>
  );
}

Eval runs the JavaScript as if your webpage were running it, this causes issues as the “move_up” function only exists in Godot, not in your webpage.

To get this working, you need to use JavaScriptBridge.create_callback, a sadly not well documented method that allows Godot and JavaScript to communicate with eachother. I’ve done some research, I suggest you watch this video of how Godot 3 does it first:
https://youtu.be/Q8G3oyZwbsE?si=bYeXsF9J5Gs-ob4v
According to a recent comment, you can get it to work the same way by replacing JavaScript with JavaScriptBridge.

1 Like