juicycleff / flutter-unity-view-widget

Embeddable unity game engine view for Flutter. Advance demo here https://github.com/juicycleff/flutter-unity-arkit-demo
BSD 3-Clause "New" or "Revised" License
2.13k stars 518 forks source link

[Unity 2019] Uncaught TypeError: Cannot read properties of undefined (reading 'SendMessage') #754

Open jawaharbabus opened 1 year ago

jawaharbabus commented 1 year ago

When I try to post a message using postMessage api from Flutter to Unity in a web app, I am facing this error. Uncaught TypeError: Cannot read properties of undefined (reading 'SendMessage')

Steps to reproduce the behavior:

  1. Exported the Unity web files using [fuw-2022.1.7f1.unitypackage]
  2. Tried sending a message to unity using postMessage API
  3. run in debug mode in chrome

unityWidgetController.postMessage('gameObj', 'changeOrientation', sensorData);

Output:

Invoking error handler due to Uncaught TypeError: Cannot read properties of undefined (reading 'SendMessage') TypeError: Cannot read properties of undefined (reading 'SendMessage') UnityLibrary/index.html 36:31 C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/html/dart2js/html_dart2js.dart 15896:13 dispatchEvent] packages/flutter_unity_widget/src/web/web_unity_widget_controller.dart 209:19 messageUnity packages/flutter_unity_widget/src/web/web_unity_widget_controller.dart 231:5 postMessage C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/flutter_unity_widget/src/web/web_unity_widget_controller.dart 226:28 postMessage packages/testwebapp/unity_widget_wrapper.dart 56:28 onUnityChanged packages/testwebapp/unity_widget_wrapper.dart 62:5 passData C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54 runBody C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5 _async packages/testwebapp/unity_widget_wrapper.dart 60:16 passData packages/flutter/src/material/ink_well.dart 1072:21 handleTap packages/flutter/src/gestures/recognizer.dart 253:24 invokeCallback packages/flutter/src/gestures/tap.dart 627:11 handleTapUp packages/flutter/src/gestures/tap.dart 306:5 [_checkUp] packages/flutter/src/gestures/tap.dart 239:7 handlePrimaryPointer packages/flutter/src/gestures/recognizer.dart 615:9 handleEvent packages/flutter/src/gestures/pointer_router.dart 98:12 [_dispatch] packages/flutter/src/gestures/pointer_router.dart 143:9 C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart 21:13 forEach packages/flutter/src/gestures/pointer_router.dart 141:17 [_dispatchEventToRoutes] packages/flutter/src/gestures/pointer_router.dart 127:7 route packages/flutter/src/gestures/binding.dart 460:19 handleEvent packages/flutter/src/gestures/binding.dart 440:14 dispatchEvent packages/flutter/src/rendering/binding.dart 337:11 dispatchEvent packages/flutter/src/gestures/binding.dart 395:7 [_handlePointerEventImmediately] packages/flutter/src/gestures/binding.dart 357:5 handlePointerEvent packages/flutter/src/gestures/binding.dart 314:7 [_flushPointerEventQueue] packages/flutter/src/gestures/binding.dart 295:7 [_handlePointerDataPacket] C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 1183:13 invoke1 C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/platform_dispatcher.dart 244:5 invokeOnPointerDataPacket C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 147:39 [_onPointerData] C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 653:20 C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 594:14 C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 288:16 loggedHandler C:/b/s/w/ir/cache/builder/src/out/host_debug/flutter_web_sdk/lib/_engine/engine/pointer_binding.dart 179:80 C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 334:14 _checkAndCall C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 339:39 dcall

It error message points the following lines of code in Index.html under UnityLibrary folder in web directory.

    window.parent.addEventListener('unityFlutterBiding', function (args) {
        const obj = JSON.parse(args.data);
        mainUnityInstance.SendMessage(obj.gameObject, obj.methodName, obj.message);
    });

Unity (please complete the following information):

PS

I built the same app in Android app and It works fine. This excludes the possibility of an issue from the app logic.

jesseburstrom commented 1 year ago

There is a bug in the index.html file in build/web/UnityLibrary/index.html

The unityhandler instance is not instanciated. There should be an .then(... in the end like :

createUnityInstance(document.querySelector("#unity-canvas"), { dataUrl: "Build/UnityLibrary.data", frameworkUrl: "Build/UnityLibrary.framework.js", codeUrl: "Build/UnityLibrary.wasm", streamingAssetsUrl: "StreamingAssets", companyName: "DefaultCompany", productName: "Dice Yatzy", productVersion: "0.1", // matchWebGLToCanvasSize: false, // Uncomment this to separately control WebGL canvas render size and DOM element size. // devicePixelRatio: 1, // Uncomment this to override low DPI rendering on high DPI displays. }).then((unityInstance) => {console.log(unityInstance); mainUnityInstance = unityInstance});

timbotimbo commented 1 year ago

There have been changes in web exports since unitypackage v4, can you try the latest package fuw-2022.1.7?

You might get Newtonsoft errors when importing a recent package in Unity 2019.x. That is because some newtonsoft .dll files were renamed to .dll.txt to avoid conflicts in newer unity versions. Undoing that txt should get it working again. Otherwise save your current newtonsoft folder and paste that in again after importing the new package.

jawaharbabus commented 1 year ago

Tested with fuw-2022.1.7. Still the same :(

jawaharbabus commented 1 year ago

@jesseburstrom, As suggested in another comment, I am testing with fuw-2022.1.7 and this is the script in my index.html

<script>
    var mainUnityInstance;

    window['handleUnityMessage'] = function (params) {
    window.parent.postMessage({
        name: 'onUnityMessage',
        data: params,
        }, '*');
    };

    window['handleUnitySceneLoaded'] = function (name, buildIndex, isLoaded, isValid) {
    window.parent.postMessage({
        name: 'onUnitySceneLoaded',
        data: {
            'name': name,
            'buildIndex': buildIndex,
            'isLoaded': isLoaded == 1,
            'isValid': isValid == 1,
        }
        }, '*');
    };

    window.parent.addEventListener('unityFlutterBiding', function (args) {
        const obj = JSON.parse(args.data);
        mainUnityInstance.SendMessage(obj.gameObject, obj.methodName, obj.message);
    });

    window.parent.addEventListener('unityFlutterBidingFnCal', function (args) {
        mainUnityInstance.SendMessage('GameManager', 'HandleWebFnCall', args);
    });

  var unityInstance = UnityLoader.instantiate("unityContainer", "Build/UnityLibrary.json", {onProgress: UnityProgress});
</script>

I can see your point though. mainUnityInstance has not been instantiated anywhere and the error message suggests the same.

jesseburstrom commented 1 year ago

Hmm i havenot seen the version with : var unityInstance = UnityLoader.instantiate("unityContainer", "Build/UnityLibrary.json", {onProgress: UnityProgress});

I submit original index.html and my version in there the Build/UnityLibrary.json is but as load script. In my version i also take into account transparency on web as well as i compensate for scrollbars i.e. i add 75px inFlutter so i cansubtract 75px to avoidscrollbars in index.html. I found the missing .then was due to a wrong copy paste text in web export build.cs unity

original-index.txt modified-index.txt

jawaharbabus commented 1 year ago

@jesseburstrom

It worked! Thanks a lot. You're a lifesaver. Since, It's not a promise I added a line which assigns the unityInstance to the mainUnityInstance. var unityInstance = UnityLoader.instantiate("unityContainer", "Build/UnityLibrary.json", {onProgress: UnityProgress}); mainUnityInstance = unityInstance;

I hope this will be fixed from the plugin's side asap.

jawaharbabus commented 1 year ago

and also, since I got the fix, should I close the issue or wait for the dev to fix it and close it then

timbotimbo commented 1 year ago

Just did a test with Unity 2022.1.23, 2021.3.14, 2020.3.42 and 2019.4.23 Looks like this issue is specific to Unity 2019.

The export script replaces a section of unityLibrary/index.html to assign mainUnityInstance. (Unity 2020/2021/2022)

script.onload = () => {
    createUnityInstance(canvas, config, (progress) => {
        progressBarFull.style.width = 100 * progress + "%";
-  }).then((unityInstance) => {
+  }).then((unityInstance) => {
+     window.parent.postMessage('unityReady', '*');
+     mainUnityInstance = unityInstance;

With unity 2019.4.23 I get this instead, which doesn't match the search and replace.

 var unityInstance = UnityLoader.instantiate("unityContainer", "Build/UnityLibrary.json", {onProgress: UnityProgress});

The index.html exported by 2019 is different, so the export script can't make the required changes.

I would suggest using a newer unity version like 2021 LTS.

@jesseburstrom's original-index.txt contains yet another variation, but i'm not sure which Unity version that is.

 createUnityInstance(document.querySelector("#unity-canvas"), {
        dataUrl: "Build/UnityLibrary.data",
        frameworkUrl: "Build/UnityLibrary.framework.js",
        codeUrl: "Build/UnityLibrary.wasm",
        streamingAssetsUrl: "StreamingAssets",
        companyName: "DefaultCompany",
        productName: "Dice Yatzy",
        productVersion: "0.1",
        // matchWebGLToCanvasSize: false, // Uncomment this to separately control WebGL canvas render size and DOM element size.
        // devicePixelRatio: 1, // Uncomment this to override low DPI rendering on high DPI displays.
      });
jesseburstrom commented 1 year ago

I use Unity 2022.1.0b5 but the Build.cs or UnityIntegration I can only say was installed 2022.05.29 and submit Build.cs as textfile Build.cs.txt