Skip to content

[Draft] Android compatibility for Unity 6000.x #24

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

Closed
wants to merge 9 commits into from

Conversation

timbotimbo
Copy link
Collaborator

@timbotimbo timbotimbo commented Jul 1, 2024

This PR is not meant to be merged in the current state

I wanted to test Unity 6000 for #21, and I might as well share what I changed.

Description

While for iOS there is hardly any difference in newer Unity versions, Android had some breaking changes in 2023.
Given that Unity 2023.3 turned into 6000, we can skip 2023 as the the next LTS will be 6000.x.

This PR is a proof of concept for supporting Android on Unity 6000.x.
Hopefully this will make an eventual update easier when 6000 enters LTS.

All basic functionality is restored for now, as all example functionality seems to work using Unity 6000.0.8 and Flutter 3.22.

Changes in the Unity 6000 export

  • Unity 2023+ makes the UnityPlayer class abstract and exposes UnityPlayerForServiceOrActivity and UnityPlayerForGameActivity instead.

    UnityPlayer no longer extends FrameLayout which breaks some overrides.

  • The exported UnityLibrary/build.gradle now imports a gradle file from a .../shared folder.

  • strings.xml with game_view_content_description is now located in unityLibrary instead of launcher. (6000.0.22+)

  • Gradle versions are updated to 8.x

  • Java is updated to 17

Updates in this PR

  • Use UnityPlayerForServiceOrActivity instead of UnityPlayer
  • Update Gradle and Java versions for compatibility.
  • Make the FrameLayout in UnityView.kt a custom instance, to handle the touch input fix in dispatchTouchEvent instead of in UnitPlayer's onTouchEvent.
  • Hande the new shared folder in the android exporter.
  • Make sure users export Unity as Activity and not GameActivity.

TODO

  • UnityPlayerSingleton can no longer have an override for onWindowVisibilityChanged.
    I've temporarily placed this function in the CustomFrameLayout that now handles the touch input fix.

    However this will likely miss some instances where Unity is removed and reattached.
    Maybe this can be done using a listener on unity's framelayout instead.

  • Cleanup & documentation

Alternatives

This react-native plugin has found a way of supporting both UnityPlayer and UnityPlayerForServiceOrActivity using reflection.
Although a nice concept, I think this will make maintenance harder and reflection won't help with performance.

@timbotimbo
Copy link
Collaborator Author

Because I had to copy some folders, merging/rebasing on main wasn't as clean as I hoped.

So for now I've recreated this in another branch, based on the latest main.
I will recreate this PR based on that branch later.

I got the example fully functional, but it needs some more testing.

@jamesncl
Copy link
Collaborator

Your PRs #36 and #37 are now merged into main and published on pub.dev as flutter_embed_unity 1.2.7 and flutter_embed_unity_2022_3_android 1.1.3. I've also updated the example projects to Kotlin gradle DSL and to support Flutter 3.29 out of the box, including an extra step in the Unity exporter script to remove ndkPath from unityLibrary/build.gradle.

So, hopefully this is a better base for merging in your new Unity 6000 branch.

@jamesncl
Copy link
Collaborator

Because I had to copy some folders, merging/rebasing on main wasn't as clean as I hoped.

So for now I've recreated this in another branch, based on the latest main. I will recreate this PR based on that branch later.

I got the example fully functional, but it needs some more testing.

Thank you, I have created a branch called feat/unity6 and merged your android_Unity_6000 branch from your fork. It merged without any problems. I'll start some testing and maybe start adding a platform package for ios too.

@timbotimbo
Copy link
Collaborator Author

timbotimbo commented May 22, 2025

I believe unity 6000 ios could work with the 2022.3 version, without any changes.
Thats why I didn't add a separate package yet.

After the merge you will be missing 2 changes in the 6000 folders.

  • Flutter 3.29/ Kotlin dsl changes in the android_6000 folder.
  • xrmanifest fix in unity 6000 android exporter.

@timbotimbo
Copy link
Collaborator Author

The only thing I wasn't 100% sure about yet is whether onWindowVisibilityChanged is triggered in all edge cases, since it is now moved up a framelayout in the hierarchy.

Besides that I think everything functions like the 2022.3 version.

@jamesncl
Copy link
Collaborator

I believe unity 6000 ios could work with the 2022.3 version, without any changes. Thats why I didn't add a separate package yet.

Ah I see, thank you. That's great, I'll not add a separate package either.

After the merge you will be missing 2 changes in the 6000 folders.

* Flutter 3.29/ Kotlin dsl changes in the android_6000 folder.

* xrmanifest fix in unity 6000 android exporter.

I'll add these, thank you.

One question: the app-facing package uses the default_package in it's pubspec.yaml to specify which package to use for each platform:

flutter:
  plugin:
    platforms:
      android:
        default_package: flutter_embed_unity_2022_3_android
      ios:
        default_package: flutter_embed_unity_2022_3_ios

In the flutter_embed_unity_6000_0_android example app (and in consumer apps in general) how do you actually override this to specify that the 6000_0 package should be used instead of the 2022_3 package? I see you have added it as a dependency in the example's pubspec.yaml like this:

dependencies:
  flutter:
    sdk: flutter

  flutter_embed_unity_6000_0_android: ^1.1.2-beta.2
  flutter_embed_unity: ^1.2.6-beta.2

(Obviously during development these would be changed to the local paths for those packages). Is that all you need to do? Does Flutter auto-magically figure out that, because you have added a dependency which implements a platform for a federated plugin, that this should override the default? I can't find any documentation which explains this, wondered if you had any insight. Thanks

@timbotimbo
Copy link
Collaborator Author

If you import a package that implements the same platform interface, a direct dependency should override defaults.

Here in Non-endorsed federated plugin they mention

This approach also works for overriding an already endorsed plugin implementation of foobar.

I can actually directly run the example with the following, so you can even test without local paths.

flutter_embed_unity_6000_0_android:
    git:
      url: https://github.com/learntoflutter/flutter_embed_unity.git
      ref: feat/unity6
      path: flutter_embed_unity_6000_0_android/
flutter_embed_unity: ^1.2.6-beta.2

This shoud be simple for documentation and install instructions while multiple Unity versions are supported.

for 2022 (default for now)

flutter_embed_unity: ...

for 6000:

 flutter_embed_unity_6000_0_android: .. # add android override
 flutter_embed_unity: ...

I imagine after a while (months/ year?) this turns into 6000 as default and 2022 with an override.

@jamesncl
Copy link
Collaborator

Thank you, I somehow missed that part in the docs about non-endorsed plugin implementations. This is great, I was hoping it would be a straight-forward configuration change.

I agree, for some amount of time, using 6000 should be opt-in using an override, and at some point in the future it should become the default.

@jamesncl jamesncl closed this May 23, 2025
@jamesncl
Copy link
Collaborator

This is now published as a pre-release for testing:

dependencies:
  flutter_embed_unity: ^1.3.0-beta.1
  flutter_embed_unity_6000_0_android: ^1.2.1-beta.1

Thanks so much for your contribution!

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

Successfully merging this pull request may close these issues.

2 participants