Unable to Send Message while Unity is not Instantiated #500
-
ProblemI have a simple React page with my WebGL game and a Button. When the Unity Game loads, it auto-logs the user in by sending a JWT token to the Unity game using the I also have binded an event listener so that when the user tries to exit the page, a warning dialog pops up with the default browser text: "This page is asking you to confirm that you want to leave — information you’ve entered may not be saved." When this occurs, I attempt to extract the player's score from the Unity game by using the So, I put the same I know #474 exists and has the same error message as me, but their problem seems to be calling Any help is appreciated. Thank you :) Environment
Codeimport React, { useEffect, useState, useCallback, useRef } from 'react';
import { Button, timeoutsShape } from 'reactstrap';
import { Unity, useUnityContext } from "react-unity-webgl";
function CardGame(props) {
const UNITY_userIsPlayingGame = useRef(0);
const UNITY_sessionID = useRef();
const UNITY_playerScore = useRef();
const { unityProvider, requestFullscreen, isLoaded, sendMessage, loadingProgression, addEventListener, removeEventListener } = useUnityContext({
loaderUrl: "Build.loader.js",
dataUrl: "Build.data",
frameworkUrl: "Build.framework.js",
codeUrl: "Build.wasm",
});
// Functions to allow Unity Game to send info to React
useEffect(() => {
addEventListener("setUserIsPlayingGame", UNITY_setUserIsPlayingGame);
addEventListener("setSessionID", UNITY_setSessionID);
addEventListener("setPlayerScore", UNITY_setPlayerScore);
return () => {
removeEventListener("setUserIsPlayingGame", UNITY_setUserIsPlayingGame);
removeEventListener("setSessionID", UNITY_setSessionID);
removeEventListener("setPlayerScore", UNITY_setPlayerScore);
};
}, [addEventListener, removeEventListener, UNITY_setUserIsPlayingGame, UNITY_setSessionID, UNITY_setPlayerScore]);
const UNITY_setUserIsPlayingGame = useCallback((state) => {
UNITY_userIsPlayingGame.current = state;
}, []);
const UNITY_setSessionID = useCallback((sessionID) => {
UNITY_sessionID.current = sessionID;
}, []);
const UNITY_setPlayerScore = useCallback((score) => {
UNITY_playerScore.current = score;
}, []);
// Automatically log the user into the Unity Game once the game is loaded
if (isLoaded === true) {
const jwt = localStorage.getItem('jwt');
// <------------------ This works! ------------------------>
sendMessage("LoginButton", "WebGLLoginAttempt", jwt);
}
useEffect(() => {
window.addEventListener("beforeunload", openWarningDialog);
return () => {
window.removeEventListener("beforeunload", openWarningDialog);
}
}, []);
// Asks user to confirm if they want to leave the page
const openWarningDialog = (e) => {
if (UNITY_userIsPlayingGame.current) {
// <----------- This fails ---------------->
sendMessage("GameManager", "WEBGL_ExtractPlayerScore");
}
e.preventDefault();
e.returnValue = "";
}
const handleOnClick = () => {
// <----------- This works! ---------------->
sendMessage("GameManager", "WEBGL_ExtractPlayerScore");
}
return (
<div>
<Unity
unityProvider={unityProvider}
style={{
width: "1152px",
height: "648px",
visibility: isLoaded ? "visible" : "hidden"
}}
/>
<Button onClick={handleOnClick} style={{visibility: isLoaded ? "visible" : "hidden"}}>Button!</Button>
</div>
);
}
export default CardGame; |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
SolutionThis has been resolved. The problem is that the window Event Listener's function was using old state. That's why it said that Unity wasn't instantiated. I moved the Correct Codeimport React, { useEffect, useState, useCallback, useRef } from 'react';
import { Button, timeoutsShape } from 'reactstrap';
import { Unity, useUnityContext } from "react-unity-webgl";
function CardGame(props) {
const UNITY_userIsPlayingGame = useRef(0);
const UNITY_sessionID = useRef();
const UNITY_playerScore = useRef();
const { unityProvider, requestFullscreen, isLoaded, sendMessage, loadingProgression, addEventListener, removeEventListener } = useUnityContext({
loaderUrl: "Build.loader.js",
dataUrl: "Build.data",
frameworkUrl: "Build.framework.js",
codeUrl: "Build.wasm",
});
// Functions to allow Unity Game to send info to React
useEffect(() => {
addEventListener("setUserIsPlayingGame", UNITY_setUserIsPlayingGame);
addEventListener("setSessionID", UNITY_setSessionID);
addEventListener("setPlayerScore", UNITY_setPlayerScore);
return () => {
removeEventListener("setUserIsPlayingGame", UNITY_setUserIsPlayingGame);
removeEventListener("setSessionID", UNITY_setSessionID);
removeEventListener("setPlayerScore", UNITY_setPlayerScore);
};
}, [addEventListener, removeEventListener, UNITY_setUserIsPlayingGame, UNITY_setSessionID, UNITY_setPlayerScore]);
const UNITY_setUserIsPlayingGame = useCallback((state) => {
UNITY_userIsPlayingGame.current = state;
}, []);
const UNITY_setSessionID = useCallback((sessionID) => {
UNITY_sessionID.current = sessionID;
}, []);
const UNITY_setPlayerScore = useCallback((score) => {
UNITY_playerScore.current = score;
}, []);
// Automatically log the user into the Unity Game once the game is loaded
if (isLoaded === true) {
const jwt = localStorage.getItem('jwt');
// <------------------ This works! ------------------------>
sendMessage("LoginButton", "WebGLLoginAttempt", jwt);
}
useEffect(() => {
+ // Asks user to confirm if they want to leave the page
+ const openWarningDialog = (e) => {
+ if (UNITY_userIsPlayingGame.current) {
+ sendMessage("GameManager", "WEBGL_ExtractPlayerScore");
+ }
+
+ e.preventDefault();
+ e.returnValue = "";
+ }
window.addEventListener("beforeunload", openWarningDialog);
return () => {
window.removeEventListener("beforeunload", openWarningDialog);
}
+ }, [isLoaded]);
- // Asks user to confirm if they want to leave the page
- const openWarningDialog = (e) => {
- if (UNITY_userIsPlayingGame.current) {
- // <----------- This fails ---------------->
- sendMessage("GameManager", "WEBGL_ExtractPlayerScore");
- }
-
- e.preventDefault();
- e.returnValue = "";
- }
const handleOnClick = () => {
// <----------- This works! ---------------->
sendMessage("GameManager", "WEBGL_ExtractPlayerScore");
}
return (
<div>
<Unity
unityProvider={unityProvider}
style={{
width: "1152px",
height: "648px",
visibility: isLoaded ? "visible" : "hidden"
}}
/>
<Button onClick={handleOnClick} style={{visibility: isLoaded ? "visible" : "hidden"}}>Button!</Button>
</div>
);
}
export default CardGame; |
Beta Was this translation helpful? Give feedback.
Solution
This has been resolved. The problem is that the window Event Listener's function was using old state. That's why it said that Unity wasn't instantiated. I moved the
openWarningDialog
function inside theuseEffect()
containing the window Event Listener, and addedisLoaded
in the dependency array.Correct Code