Skip to content

Commit

Permalink
Add support for onDettached onAttach UnityWidget
Browse files Browse the repository at this point in the history
  • Loading branch information
Ortes committed Dec 13, 2022
1 parent 7f55bc2 commit 05dc276
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,20 @@ class FlutterUnityWidgetController(
// add unity to view
UnityPlayerUtils.addUnityViewToGroup(view)
UnityPlayerUtils.focus()

attached = true

if (UnityPlayerUtils.controllers.size >= 2) {
for (controller in UnityPlayerUtils.controllers.subList(0, UnityPlayerUtils.controllers.size - 1)) {
if (controller.attached) {
controller.detach()
}
}
}

Handler(Looper.getMainLooper()).post {
methodChannel.invokeMethod("events#onViewAttached", null)
}
}

// DO NOT CHANGE THIS FUNCTION
Expand Down Expand Up @@ -384,5 +397,12 @@ class FlutterUnityWidgetController(
Choreographer.getInstance()
.postFrameCallback { f.run() }
}

private fun detach() {
Handler(Looper.getMainLooper()).post {
methodChannel.invokeMethod("events#onViewDetached", null)
}
attached = false
}
//#endregion
}
11 changes: 9 additions & 2 deletions lib/src/facade_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class UnityWidget extends StatefulWidget {
this.unloadOnDispose = false,
this.printSetupLog = true,
this.onUnityUnloaded,
this.onUnityAttached,
this.onUnityDetached,
this.gestureRecognizers,
this.placeholder,
this.useAndroidViewSurface = false,
Expand All @@ -38,6 +40,12 @@ class UnityWidget extends StatefulWidget {
///Event fires when the [UnityWidget] unity player gets unloaded.
final UnityUnloadCallback? onUnityUnloaded;

///Event fires when Unity player is attached to the widget
final UnityAttachedCallback? onUnityAttached;

///Event fires when Unity player is attached to the widget
final UnityDetachedCallback? onUnityDetached;

final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;

/// Set to true to force unity to fullscreen
Expand Down Expand Up @@ -83,7 +91,6 @@ class UnityWidget extends StatefulWidget {
class _UnityWidgetState extends State<UnityWidget> {
@override
Widget build(BuildContext context) {
return Text(
'$defaultTargetPlatform is not yet supported by the unity player plugin');
return Text('$defaultTargetPlatform is not yet supported by the unity player plugin');
}
}
8 changes: 8 additions & 0 deletions lib/src/helpers/events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ class UnityCreatedEvent extends UnityEvent<void> {
class UnityMessageEvent extends UnityEvent<dynamic> {
UnityMessageEvent(int unityId, dynamic value) : super(unityId, value);
}

class UnityAttachedEvent extends UnityEvent<void> {
UnityAttachedEvent(int unityId, void value) : super(unityId, value);
}

class UnityDetachedEvent extends UnityEvent<void> {
UnityDetachedEvent(int unityId, void value) : super(unityId, value);
}
4 changes: 4 additions & 0 deletions lib/src/helpers/misc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ typedef void UnityMessageCallback(dynamic handler);
typedef void UnitySceneChangeCallback(SceneLoaded? message);

typedef void UnityUnloadCallback();

typedef void UnityAttachedCallback();

typedef void UnityDetachedCallback();
16 changes: 16 additions & 0 deletions lib/src/io/device_method.dart
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ class MethodChannelUnityWidget extends UnityWidgetPlatform {
case "events#onUnityCreated":
_unityStreamController.add(UnityCreatedEvent(unityId, call.arguments));
break;
case "events#onViewAttached":
_unityStreamController.add(UnityAttachedEvent(unityId, call.arguments));
break;
case "events#onViewDetached":
_unityStreamController.add(UnityDetachedEvent(unityId, call.arguments));
break;
default:
throw UnimplementedError("Unimplemented ${call.method} method");
}
Expand Down Expand Up @@ -145,6 +151,16 @@ class MethodChannelUnityWidget extends UnityWidgetPlatform {
return _events(unityId).whereType<UnitySceneLoadedEvent>();
}

@override
Stream<UnityAttachedEvent> onUnityAttached({required int unityId}) {
return _events(unityId).whereType<UnityAttachedEvent>();
}

@override
Stream<UnityDetachedEvent> onUnityDetached({required int unityId}) {
return _events(unityId).whereType<UnityDetachedEvent>();
}

@override
Widget buildViewWithTextDirection(
int creationId,
Expand Down
25 changes: 22 additions & 3 deletions lib/src/io/mobile_unity_widget_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class MobileUnityWidgetController extends UnityWidgetController {
/// used for cancel the subscription
StreamSubscription? _onUnityMessageSub,
_onUnitySceneLoadedSub,
_onUnityUnloadedSub;
_onUnityUnloadedSub,
_onUnityAttachedSub,
_onUnityDetachedSub;

MobileUnityWidgetController._(this._unityWidgetState,
{required this.unityId}) {
Expand All @@ -30,11 +32,12 @@ class MobileUnityWidgetController extends UnityWidgetController {
/// in [UnityWidget.onUnityCreated] callback.
static Future<MobileUnityWidgetController> init(
int id, MobileUnityWidgetState unityWidgetState) async {
await UnityWidgetPlatform.instance.init(id);
return MobileUnityWidgetController._(
final controller = MobileUnityWidgetController._(
unityWidgetState,
unityId: id,
);
await UnityWidgetPlatform.instance.init(id);
return controller;
}

@visibleForTesting
Expand Down Expand Up @@ -66,6 +69,18 @@ class MobileUnityWidgetController extends UnityWidgetController {
.onUnityUnloaded(unityId: unityId)
.listen((_) => _unityWidgetState.widget.onUnityUnloaded!());
}

if (_unityWidgetState.widget.onUnityAttached != null) {
_onUnityAttachedSub = UnityWidgetPlatform.instance.onUnityAttached(unityId: unityId).listen((_) {
_unityWidgetState.widget.onUnityAttached!();
});
}

if (_unityWidgetState.widget.onUnityDetached != null) {
_onUnityDetachedSub = UnityWidgetPlatform.instance.onUnityDetached(unityId: unityId).listen((_) {
_unityWidgetState.widget.onUnityDetached!();
});
}
}

/// Checks to see if unity player is ready to be used
Expand Down Expand Up @@ -200,10 +215,14 @@ class MobileUnityWidgetController extends UnityWidgetController {
_onUnityMessageSub?.cancel();
_onUnitySceneLoadedSub?.cancel();
_onUnityUnloadedSub?.cancel();
_onUnityAttachedSub?.cancel();
_onUnityDetachedSub?.cancel();

_onUnityMessageSub = null;
_onUnitySceneLoadedSub = null;
_onUnityUnloadedSub = null;
_onUnityAttachedSub = null;
_onUnityDetachedSub = null;
}

void dispose() {
Expand Down
11 changes: 11 additions & 0 deletions lib/src/io/unity_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ class UnityWidget extends StatefulWidget {
this.unloadOnDispose = false,
this.printSetupLog = true,
this.onUnityUnloaded,
this.onUnityAttached,
this.onUnityDetached,
this.gestureRecognizers,
this.placeholder,
this.useAndroidViewSurface = false,
Expand All @@ -87,6 +89,12 @@ class UnityWidget extends StatefulWidget {
///Event fires when the [UnityWidget] unity player gets unloaded.
final UnityUnloadCallback? onUnityUnloaded;

///Event fires when Unity player is attached to the widget
final UnityAttachedCallback? onUnityAttached;

///Event fires when Unity player is detached to the widget
final UnityDetachedCallback? onUnityDetached;

final Set<Factory<OneSequenceGestureRecognizer>>? gestureRecognizers;

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

// if (widget.onUnityAttached != null)
// widget.onUnityAttached!();

if (widget.printSetupLog) {
log('*********************************************');
log('** flutter unity controller setup complete **');
Expand Down
8 changes: 8 additions & 0 deletions lib/src/io/unity_widget_platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ abstract class UnityWidgetPlatform extends PlatformInterface {
throw UnimplementedError('onUnitySceneLoaded() has not been implemented.');
}

Stream<UnityAttachedEvent> onUnityAttached({required int unityId}) {
throw UnimplementedError('onUnityAttached() has not been implemented.');
}

Stream<UnityDetachedEvent> onUnityDetached({required int unityId}) {
throw UnimplementedError('onUnityDetached() has not been implemented.');
}

/// Dispose of whatever resources the `unityId` is holding on to.
void dispose({required int unityId}) {
throw UnimplementedError('dispose() has not been implemented.');
Expand Down

0 comments on commit 05dc276

Please sign in to comment.