Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SendMessage: object does not have receiver for function #498

Open
1 of 2 tasks
nwoodr94 opened this issue Mar 29, 2023 · 2 comments
Open
1 of 2 tasks

SendMessage: object does not have receiver for function #498

nwoodr94 opened this issue Mar 29, 2023 · 2 comments
Assignees
Labels

Comments

@nwoodr94
Copy link

Please avoid duplicates

Language and Compiler

Babel and WebPack JavaScript

What environment are you using?

Local Development Server

When does your problem occur?

When the Unity App is running

What does your problem relate to?

The problem seems Unity related

React-Unity-WebGL Version

^9.4.0

React Version

^18.1.0

Unity Version

2021.3.5f1

What happened?

It appears that this library doesn't work with static Unity functions.

I wanted to call a Unity function from React, and then sends Unity data back to React. With static functions, this doesn't work, and so I had to refactor my Unity class to use regular methods. Not sure if this is expected behavior, but the error message was confusing.

Using the sample code attached to this bug report, the console will log:

SendMessage: object ReactManager does not have receiver for function RetrieveGameObjects!

Action: Maybe update the error message to suggest static methods are not supported.

Reproducible test case

ListNodes.cs

using UnityEngine;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using Utility;

namespace DeepLynx
{
    public class ListNodes : MonoBehaviour
    {
       // This script is attached to an empty game object called ReactManager

        [DllImport("__Internal")]
        private static extern void SendGameObjects(string response);

        public static void RetrieveGameObjects()
        {
            Debug.Log("Retrieving GameObjects");
            string response = ListGameObjects();

            Debug.Log(response); // "Object1, Object2, Object3"

#if UNITY_WEBGL == true && UNITY_EDITOR == false
            SendGameObjects(response);
#endif
        }

        public static string ListGameObjects()
        {
            // This is a custom function that returns a list of game objects
            List<GameObject> gameObjects = CustomTags.GetGameObjects("SpecificTag"); 
            List<string> nodes = new List<string>();

            foreach (GameObject go in gameObjects)
            {
                nodes.Add(go.name);
            }

            return string.Join(",", nodes);
        }
    }
}

/Plugins/WebGL/React.jslib

mergeInto(LibraryManager.library, {
  SendGameObjects: function (response) {
    try {
      window.dispatchReactUnityEvent("SendGameObjects", UTF8ToString(response));
    } catch (e) {
      console.warn("Failed to dispatch event");
    }
  }
});

Component.js

// React Hooks
import React, { useCallback, useEffect, useState } from "react";

// Unity
import { Unity, useUnityContext } from "react-unity-webgl";

// Material
import {
  Box,
  Button,
} from "@mui/material";


function WebGL(props) {

  // GameObjects
  const [GameObjects, SetGameObjects] = useState();

  const { unityProvider, sendMessage, addEventListener, removeEventListener } =
    useUnityContext({
      // These 4 compiled assets are the bundle that Unity generates when you build to WebGL
      loaderUrl: "webgl/sandbox/Build/sandbox.loader.js",
      dataUrl: "webgl/sandbox/Build/sandbox.data",
      frameworkUrl: "webgl/sandbox/Build/sandbox.framework.js",
      codeUrl: "webgl/sandbox/Build/sandbox.wasm",
    });

  const handleGameObjects = useCallback((response) => {
    console.log(response);
  }, []);

  useEffect(() => {
    addEventListener("SendGameObjects", handleGameObjects);
    return () => {
      removeEventListener("SendGameObjects", handleGameObjects);
    };
  }, [addEventListener, removeEventListener, handleGameObjects]);

  function listGameObjects() {
    sendMessage("ReactManager", "RetrieveGameObjects");
  }

  return (
    <Box>
        <Button
          onClick={() => {
            listGameObjects();
          }}
        >
          Game Objects
        </Button>
    </Box>
  );
}

export default WebGL;

Would you be interested in contributing a fix?

  • yes, I would like to contribute a fix
@jeffreylanters
Copy link
Owner

I don't think SendMessage works with static methods, try making it an instance method

@dungmv
Copy link

dungmv commented Apr 16, 2023

create listGameObjects by useCallback instead of directly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants