refactor: refactored unity controller to a global singleton
Description
Many times we want to control unity without having UnityWidget in the screen or during route transition load a unity scene. Both of these cases was impossible because the unity controller lives as long as the activie unitywidget is mounted.
This PR introduces a singleton flutter unity controller that lives outside the life span of the widget. That is you can control your unity instance from anywhere in your flutter code.
API spec
Listen to stream anywhere
FlutterUnityController.instance.onUnityMessage().listen((event) {
// handleMessage(event.value);
});
Filter events by type to stream anywhere
FlutterUnityController.instance.stream.listen((event) {
if (event.eventType == UnityEventTypes.OnUnityViewCreated) {
// handleMessage(event.value);
}
});
Type of Change
- [x] ✨ New feature (non-breaking change which adds functionality)
- [ ] 🛠️ Bug fix (non-breaking change which fixes an issue)
- [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change)
- [ ] 🧹 Code refactor
- [ ] ✅ Build configuration change
- [ ] 📝 Documentation
- [ ] 🗑️ Chore
I just did a check on android and here is my first impression, I will do more testing and try iOS later.
It doesn't seem to be a breaking change for the existing example project, but the singleton needs some adjustments or documentation, as it doesn't always work as I would expect.
The biggest issue is the last bullet point, crashing with unload.
Using FlutterUnityController before a UnityWidget is used:
-
createreturns null and doesn't do anything. I would expect it to start a hidden Unity instance. - Most other functions return without any result or error (
pause,resume,quit,unload,init). If this is intended, maybe print a warning or error about initializing the controller first. -
isLoadedisReadyisPausedreturn false as expected.InBackgroundthrows an exception:
MissingPluginException (MissingPluginException(No implementation found for method unity#inBackground on channel plugin.xraph.com/base_channel))
-
postMessagewith setRotationSpeed gets me a nice error.Native libraries not loaded - dropping message for Cube.SetRotationSpeed -
openInNativeProcessworks as expected and starts a new standalone unity instance.
Using FlutterUnityController without a UnityWidget, after disposing a UnityWidget:
-
postMessage,openInNativeProcessandquitwork as expected. -
create,pauseandresumedont really seem to do anything. -
isLoadedisReadyisPausedall return true. But i'm not sure if it is actually paused. -
unloadwill crash the app on the next UnityWidget. Even if I callcreateorinitbefore opening the UnityWidget.
call to OpenGL ES API with no current context (logged once per thread)
EDIT: This branch has some updates to the example that I used to play around with the controller. Not final enough for a pull request, but it might be helpful.
WebGL is an interesting one. Unity doesn't stay active without a UnityWidget and boots from the splash screen for each UnityWidget. This makes the new streams kind of useless as we need to have a UnityWidget open anyway.
The current api_screen.dart example is now broken on web as FlutterUnityController.instance throws errors where _unityController doesn't. (error is from FlutterUnityController.instance.postMessage)
MissingPluginException(No implementation found for method unity#postMessage on channel plugin.xraph.com/base_channel)
I'm not sure it is worth the effort to implement the new method channels on web if they don't add new functionality. But it would be nice to fall back to the existing controller to avoid breaking things.
WebGL is an interesting one. Unity doesn't stay active without a UnityWidget and boots from the splash screen for each UnityWidget. This makes the new streams kind of useless as we need to have a UnityWidget open anyway.
The current api_screen.dart example is now broken on web as
FlutterUnityController.instancethrows errors where_unityControllerdoesn't. (error is fromFlutterUnityController.instance.postMessage)MissingPluginException(No implementation found for method unity#postMessage on channel plugin.xraph.com/base_channel)I'm not sure it is worth the effort to implement the new method channels on web if they don't add new functionality. But it would be nice to fall back to the existing controller to avoid breaking things.
Yeah it's only for mobile and nor for web. Web can still keep using unity widget controller
HAve to add tho index.html at end .then((unityInstance) => {console.log(unityInstance); mainUnityInstance = unityInstance}); to actually init the unity instance hope it is fixed with new version
@juicycleff I ran into some regressions on iOS.
1
White screen when returning to UnityWidget:
- Run example project
- Open No interaction Unity demo
- Press Switch Flutter Sceen
- Press back button
Now the no interaction demo page shows only white, instead of Unity. This works fine on master, but is broken in this branch. (Found on iPad with iPadOS 16.1, and Running on Mac mini m1 “Designed for iPhone”)
2
Might be the same issue, but I did not see this on the iPad, only on the Mac in “Designed for iPhone“ mode.
- Run the example project
- Open any of the demo pages
- The page is white and Unity does not show up.
- Closing the page and opening any page a second time fixes it.
This only happens on Unity's first boot. Once you've got it visible it will keep working. Works fine on master branch, bug is introduced in this branch. This one seems like #540 (fixed in #595) is reintroduced here.
Any progress here? Facing also the issue with the white screen on first load
@kamami this specific thread is only about this new feature branch, your issue seems to be on master as you also commentee on multiple issues related to white screens.
@timbotimbo sorry for being MIA for so long. Life happened, I will try to give the PR a lift and see where thing things lead.
@juicycleff Welcome back. Can you look into publishing a plugin update before merging this?
There have been quite a few bug fixes since 2022.2 and I think it is a good idea to have a 'safe' version before a major change like this.
Some fixes have been merged in master, but there are a few open pull request that still need a look too.
Hey @timbotimbo sure I'm currently looking at everything and will make a release as soon as I'm done probably tonight
I have been thinking this would be nice to have so I can make it accessible with Provider.