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

Changes to InputField cause <Unity> id parameter to change on every keystroke #66

Closed
flipswitchingmonkey opened this issue Jun 18, 2019 · 3 comments

Comments

2 participants
@flipswitchingmonkey
Copy link

commented Jun 18, 2019

React 16.8.4
Unity 2019.1.7f1

I'm trying to combine Unity WebGL and an input form. To capture the input keyboard events, I disable the events in Unity via

WebGLInput.captureAllKeyboardInput = true;  // or false

This works. However, the moment I enter anything into the input field, the Unity object seems to re-render, or rather, it gives itself a new 'id' (uniqueID internally). So with every keystroke I can see ... "id": "ReactUnityWebGL_1"... become "ReactUnityWebGL_2", "ReactUnityWebGL_3" and so on. Thus, breaking the communication to the Unity WebGL.

Edit: actually it's the entire Instance that disappears immediately from the unityContent prop....

Any idea what might cause this?

Here's the code I'm using:

const App = () => {
    const theme = useState("darkblue");
    const unityContent = new UnityContent(
        "build/Build/build.json",
        "build/Build/UnityLoader.js",
        {
            adjustOnWindowResize: true
        }
    );
    unityContent.on("UnityWebGLReady", () => {
        console.log("UnityWebGLReady received");
    });
    unityContent.on("WebGLController", () => {
        console.log("WebGLController received");
    });

    const [assetName, setAssetName] = useState<string>(
        "c213_802402_0200__0001_021"
    );
    const [assetBundlePath, setAssetBundlePath] = useState<string>(
        "build/AssetBundles/"
    );
    const [assetUrlRoot, setAssetUrlRoot] = useState<string>(
        "http://localhost/"
    );

    const loadAsset = () => {
        unityContent.send(
            "AssetLoader",
            "LoadAssetsFromBundleUrl",
            `${assetUrlRoot}${assetBundlePath}${assetName}`
        );
    };

    const testMessage = () => {
        unityContent.send(
            "AssetLoader",
            "TestFunction",
            `${assetUrlRoot}${assetBundlePath}${assetName}`
        );
    };

    const focusCanvas = (enabled: boolean) => {
        if (enabled === true) {
            unityContent.send("WebGLController", "EnableAllKeyboardInput");
        } else {
            unityContent.send("WebGLController", "DisableAllKeyboardInput");
        }
    };

    return (
        <React.StrictMode>
            <div>
                <div className="assetLoadForm">
                   <input
                        value={assetName}
                        onChange={(e: React.FormEvent<HTMLInputElement>) =>
                            setAssetName(e.currentTarget.value)
                        }
                    />
                    <Button
                        icon="refresh"
                        intent="primary"
                        text="Load Asset"
                        onClick={() => loadAsset()}
                    />
                    <Button
                        icon="refresh"
                        intent="primary"
                        text="Test Message"
                        onClick={() => testMessage()}
                    />
                    <Button
                        icon="refresh"
                        intent="primary"
                        text="Enable Canvas Focus"
                        onClick={() => focusCanvas(true)}
                    />
                    <Button
                        icon="refresh"
                        intent="primary"
                        text="Disable Canvas Focus"
                        onClick={() => focusCanvas(false)}
                    />
                </div>
            </div>
            <Unity unityContent={unityContent} />
        </React.StrictMode>
    );
};
@flipswitchingmonkey

This comment has been minimized.

Copy link
Author

commented Jun 18, 2019

I rewrote the entire thing as a class component rather than a functional component and now it works as expected. So, I guess we can close this and just say: "do not use functional components here"?

@jeffreylanters

This comment has been minimized.

Copy link
Member

commented Jun 18, 2019

Interesting, the id increments every time a new UnityContent is constructed. I'm don't use functional components that much. Does it remount when updating?

@flipswitchingmonkey

This comment has been minimized.

Copy link
Author

commented Jun 19, 2019

I'm not sure how it works internally, I know it redraws components constantly during input, but I had assumed this would just affect that specific component and not everything on the page. Also, no idea whether redraws actually trigger a remount too? Sorry.
In any case, doing it the "classic" way via a class works like a charm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.