Skip to content

Commit d8ede98

Browse files
committed
Add support for onDettached onAttach UnityWidget
1 parent 7f55bc2 commit d8ede98

File tree

8 files changed

+101
-3
lines changed

8 files changed

+101
-3
lines changed

android/src/main/kotlin/com/xraph/plugin/flutter_unity_widget/FlutterUnityWidgetController.kt

+20
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,20 @@ class FlutterUnityWidgetController(
345345
// add unity to view
346346
UnityPlayerUtils.addUnityViewToGroup(view)
347347
UnityPlayerUtils.focus()
348+
348349
attached = true
350+
351+
if (UnityPlayerUtils.controllers.size >= 2) {
352+
for (controller in UnityPlayerUtils.controllers.subList(0, UnityPlayerUtils.controllers.size - 1)) {
353+
if (controller.attached) {
354+
controller.detach()
355+
}
356+
}
357+
}
358+
359+
Handler(Looper.getMainLooper()).post {
360+
methodChannel.invokeMethod("events#onViewAttached", null)
361+
}
349362
}
350363

351364
// DO NOT CHANGE THIS FUNCTION
@@ -384,5 +397,12 @@ class FlutterUnityWidgetController(
384397
Choreographer.getInstance()
385398
.postFrameCallback { f.run() }
386399
}
400+
401+
private fun detach() {
402+
Handler(Looper.getMainLooper()).post {
403+
methodChannel.invokeMethod("events#onViewDetached", null)
404+
}
405+
attached = false
406+
}
387407
//#endregion
388408
}

lib/src/facade_widget.dart

+8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class UnityWidget extends StatefulWidget {
1616
this.unloadOnDispose = false,
1717
this.printSetupLog = true,
1818
this.onUnityUnloaded,
19+
this.onUnityAttached,
20+
this.onUnityDetached,
1921
this.gestureRecognizers,
2022
this.placeholder,
2123
this.useAndroidViewSurface = false,
@@ -38,6 +40,12 @@ class UnityWidget extends StatefulWidget {
3840
///Event fires when the [UnityWidget] unity player gets unloaded.
3941
final UnityUnloadCallback? onUnityUnloaded;
4042

43+
///Event fires when Unity player is attached to the widget
44+
final UnityAttachedCallback? onUnityAttached;
45+
46+
///Event fires when Unity player is attached to the widget
47+
final UnityDetachedCallback? onUnityDetached;
48+
4149
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
4250

4351
/// Set to true to force unity to fullscreen

lib/src/helpers/events.dart

+8
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,11 @@ class UnityCreatedEvent extends UnityEvent<void> {
3434
class UnityMessageEvent extends UnityEvent<dynamic> {
3535
UnityMessageEvent(int unityId, dynamic value) : super(unityId, value);
3636
}
37+
38+
class UnityAttachedEvent extends UnityEvent<void> {
39+
UnityAttachedEvent(int unityId, void value) : super(unityId, value);
40+
}
41+
42+
class UnityDetachedEvent extends UnityEvent<void> {
43+
UnityDetachedEvent(int unityId, void value) : super(unityId, value);
44+
}

lib/src/helpers/misc.dart

+4
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ typedef void UnityMessageCallback(dynamic handler);
2525
typedef void UnitySceneChangeCallback(SceneLoaded? message);
2626

2727
typedef void UnityUnloadCallback();
28+
29+
typedef void UnityAttachedCallback();
30+
31+
typedef void UnityDetachedCallback();

lib/src/io/device_method.dart

+16
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ class MethodChannelUnityWidget extends UnityWidgetPlatform {
9595
case "events#onUnityCreated":
9696
_unityStreamController.add(UnityCreatedEvent(unityId, call.arguments));
9797
break;
98+
case "events#onViewAttached":
99+
_unityStreamController.add(UnityAttachedEvent(unityId, call.arguments));
100+
break;
101+
case "events#onViewDetached":
102+
_unityStreamController.add(UnityDetachedEvent(unityId, call.arguments));
103+
break;
98104
default:
99105
throw UnimplementedError("Unimplemented ${call.method} method");
100106
}
@@ -145,6 +151,16 @@ class MethodChannelUnityWidget extends UnityWidgetPlatform {
145151
return _events(unityId).whereType<UnitySceneLoadedEvent>();
146152
}
147153

154+
@override
155+
Stream<UnityAttachedEvent> onUnityAttached({required int unityId}) {
156+
return _events(unityId).whereType<UnityAttachedEvent>();
157+
}
158+
159+
@override
160+
Stream<UnityDetachedEvent> onUnityDetached({required int unityId}) {
161+
return _events(unityId).whereType<UnityDetachedEvent>();
162+
}
163+
148164
@override
149165
Widget buildViewWithTextDirection(
150166
int creationId,

lib/src/io/mobile_unity_widget_controller.dart

+26-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ class MobileUnityWidgetController extends UnityWidgetController {
1818
/// used for cancel the subscription
1919
StreamSubscription? _onUnityMessageSub,
2020
_onUnitySceneLoadedSub,
21-
_onUnityUnloadedSub;
21+
_onUnityUnloadedSub,
22+
_onUnityAttachedSub,
23+
_onUnityDetachedSub;
2224

2325
MobileUnityWidgetController._(this._unityWidgetState,
2426
{required this.unityId}) {
@@ -30,11 +32,12 @@ class MobileUnityWidgetController extends UnityWidgetController {
3032
/// in [UnityWidget.onUnityCreated] callback.
3133
static Future<MobileUnityWidgetController> init(
3234
int id, MobileUnityWidgetState unityWidgetState) async {
33-
await UnityWidgetPlatform.instance.init(id);
34-
return MobileUnityWidgetController._(
35+
final controller = MobileUnityWidgetController._(
3536
unityWidgetState,
3637
unityId: id,
3738
);
39+
await UnityWidgetPlatform.instance.init(id);
40+
return controller;
3841
}
3942

4043
@visibleForTesting
@@ -66,6 +69,22 @@ class MobileUnityWidgetController extends UnityWidgetController {
6669
.onUnityUnloaded(unityId: unityId)
6770
.listen((_) => _unityWidgetState.widget.onUnityUnloaded!());
6871
}
72+
73+
if (_unityWidgetState.widget.onUnityAttached != null) {
74+
_onUnityAttachedSub = UnityWidgetPlatform.instance
75+
.onUnityAttached(unityId: unityId)
76+
.listen((_) {
77+
_unityWidgetState.widget.onUnityAttached!();
78+
});
79+
}
80+
81+
if (_unityWidgetState.widget.onUnityDetached != null) {
82+
_onUnityDetachedSub = UnityWidgetPlatform.instance
83+
.onUnityDetached(unityId: unityId)
84+
.listen((_) {
85+
_unityWidgetState.widget.onUnityDetached!();
86+
});
87+
}
6988
}
7089

7190
/// Checks to see if unity player is ready to be used
@@ -200,10 +219,14 @@ class MobileUnityWidgetController extends UnityWidgetController {
200219
_onUnityMessageSub?.cancel();
201220
_onUnitySceneLoadedSub?.cancel();
202221
_onUnityUnloadedSub?.cancel();
222+
_onUnityAttachedSub?.cancel();
223+
_onUnityDetachedSub?.cancel();
203224

204225
_onUnityMessageSub = null;
205226
_onUnitySceneLoadedSub = null;
206227
_onUnityUnloadedSub = null;
228+
_onUnityAttachedSub = null;
229+
_onUnityDetachedSub = null;
207230
}
208231

209232
void dispose() {

lib/src/io/unity_widget.dart

+11
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class UnityWidget extends StatefulWidget {
6161
this.unloadOnDispose = false,
6262
this.printSetupLog = true,
6363
this.onUnityUnloaded,
64+
this.onUnityAttached,
65+
this.onUnityDetached,
6466
this.gestureRecognizers,
6567
this.placeholder,
6668
this.useAndroidViewSurface = false,
@@ -87,6 +89,12 @@ class UnityWidget extends StatefulWidget {
8789
///Event fires when the [UnityWidget] unity player gets unloaded.
8890
final UnityUnloadCallback? onUnityUnloaded;
8991

92+
///Event fires when Unity player is attached to the widget
93+
final UnityAttachedCallback? onUnityAttached;
94+
95+
///Event fires when Unity player is detached to the widget
96+
final UnityDetachedCallback? onUnityDetached;
97+
9098
final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;
9199

92100
/// Set to true to force unity to fullscreen
@@ -192,6 +200,9 @@ class _UnityWidgetState extends State<UnityWidget> {
192200
_controller = controller;
193201
widget.onUnityCreated(controller);
194202

203+
// if (widget.onUnityAttached != null)
204+
// widget.onUnityAttached!();
205+
195206
if (widget.printSetupLog) {
196207
log('*********************************************');
197208
log('** flutter unity controller setup complete **');

lib/src/io/unity_widget_platform.dart

+8
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,14 @@ abstract class UnityWidgetPlatform extends PlatformInterface {
107107
throw UnimplementedError('onUnitySceneLoaded() has not been implemented.');
108108
}
109109

110+
Stream<UnityAttachedEvent> onUnityAttached({required int unityId}) {
111+
throw UnimplementedError('onUnityAttached() has not been implemented.');
112+
}
113+
114+
Stream<UnityDetachedEvent> onUnityDetached({required int unityId}) {
115+
throw UnimplementedError('onUnityDetached() has not been implemented.');
116+
}
117+
110118
/// Dispose of whatever resources the `unityId` is holding on to.
111119
void dispose({required int unityId}) {
112120
throw UnimplementedError('dispose() has not been implemented.');

0 commit comments

Comments
 (0)