learntoflutter / flutter_embed_unity

19 stars 5 forks source link

Safe Area in Unity Not Applied in Flutter Integration #20

Closed GreejeshGajera closed 5 months ago

GreejeshGajera commented 5 months ago

Flutter version 3.22.1

flutter_embed_unity: ^1.0.4

Unity version 2022.3.28f1

Description I'm experiencing an issue where the safe area set in Unity is not being respected when integrating Unity within a Flutter application. Other features of the integration are working as expected, but the safe area configuration from Unity is ignored, causing layout issues on devices with notches or other screen insets.

Steps to Reproduce:

Expected Behavior: The Unity view should respect the safe area set within Unity, ensuring that content is not obscured by notches or other screen insets.

Actual Behavior: The Unity view does not respect the safe area configuration. Content extends into areas that should be padded according to the safe area settings, leading to potential usability issues.

jamesncl commented 5 months ago

Thanks for the bug report!

My first thoughts are that this may be difficult to fix (however there is a relatively simple work around - see below). The reason is that the "export as a library" feature of Unity expects Unity to be running inside a very specific Android activity: UnityPlayerActivity. However, to get Unity to run inside Flutter (which Unity was never designed to do), we have to hack around this, and instead run Unity within the context of FlutterActivity. I'm guessing that his is why the Unity SafeArea API isn't working - it probably tries to call UnityPlayerActivity to get the safe area dimensions, and gets no response.

There is probably a way to fix this, but will need significant work as the internals of how UnityPlayer works and deals with safe area is undocumented, and may change. At the present time I'm unable to commit the time this would require (but of course I would welcome any contributions / PRs). Instead, I wondered if you could work around this by getting the safe area padding within Flutter, and passing it to Unity - something like this:

class Example extends StatelessWidget {

  const Example();

  @override
  Widget build(BuildContext context) {
    final safeAreaPadding = MediaQuery.paddingOf(context);
    return EmbedUnity(
      onMessageFromUnity: (String message) {
        if(message == "scene_loaded") {
          sendToUnity(
            "SafeAreaManager", 
            "SafeAreaReceivedFromFlutter", 
            jsonEncode({
              "top": safeAreaPadding.top,
              "bottom": safeAreaPadding.bottom,
              "left": safeAreaPadding.left,
              "right": safeAreaPadding.right,
            })
          );
        }
      },
    );
  }
}

Let me know what you think.

This appears to also affect flutter_unity_widget and has been raised in a similar issue - it's also discussed on this Unity forums thread

GreejeshGajera commented 5 months ago

I wanted to extend a heartfelt thank you for your swift and effective resolution of the safe area issue I was experiencing with the Unity integration in my Flutter application. Your assistance was invaluable, and everything is now working perfectly.