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 517 forks source link

[Informative]: expensiveness of communication #591

Open WouterVandenputte opened 2 years ago

WouterVandenputte commented 2 years ago

I have been taking a look at how sending messages from Unity to Flutter works.

AndroidJavaClass jc = new AndroidJavaClass("com.xraph.plugin.flutter_unity_widget.UnityPlayerUtils"); jc.CallStatic("onUnityMessage", message);

We see a new class is created and a method called on it. The question now is, how expensive is this?

Consider a use case where the Unity partwants to send a message to the Flutter part every single frame as to keep the Flutter UI notified on the current Unity view. E.g. we have a cube in Unity and we want Flutter to display a text above it so we se send the x,y and z coordinates of the cube every single frame.

Is this something that is discouraged? How much impact would that have? Would it be a major optimization or a minor optimization to not instantiate a new AndroidJavaClass every message but rather have only one static instance such that it can be reused? Is the size of serialiazed message a contributing factor of performance for communication? (I know it will be for (de)serialization))

jamesncl commented 2 years ago

Flutter has some great tools for analysing the performance of your app while it's running, I would suggest trying it with / without sending a message every frame. My guess is that yes, it's probably a bad idea, because serialisation is inherently slow.

I do a similar thing in my app, but I get Unity to draw the text instead using TextMesh Pro so there's no need to pass messages every frame, maybe that approach will work for you too

WouterVandenputte commented 2 years ago

Well I originally had this text follow the cube in Unity, but since I wanted to oursource all non 3D logic to Flutter to make the app more neat and have a more consistent layout I thought to do that in Flutter.

I also tried a much more performant approach, that is to not send the location every single frame but rather twice a second and then animate the text (using AnimatedPosition). such that it does not jump every half a second but always animates to the new position which would make it kinda look following the cube (we need to take in account that the cube's motion isn't linear).

But even this makes the framerate exteremely slow (5-9 fps) and the text jumps. I know for a fact that this is an issue in the Unity part of the application because when I mock the unitywidget (using a flutter Container) that sends a message with random coordinates every 500ms ,than I can see the text nicely animating to the random positions smoothly...

Wish there was a way to find the bottleneck and be able to solve it. Would rather not doo logic in Unity. the Flutter app has the entire framework setup with consistent layout and translations etc

juicycleff commented 2 years ago

@WouterVandenputte the message handler between unity and flutter is pretty much simple. The biggest thing to worry about is how your app handles the events. If you do not have an expensive process handling events, then it should be fine.

I will advise writing some event queue and bus at both ends of the app (I mean Flutter and Unity). at the end of the day if your app can call a method 100K times in a second, that events should be propagated correctly to flutter and vice versa, I don't advice you doing that, but i think you get the point

juicycleff commented 2 years ago

I will leave this open