Currently I have a Unity scene running as a view in an activity (very similar to this solution). As we're migrating to more composables, I'm wondering how to do that in this case. Simplistically I could put a UnityPlayer
in an AndroidView
composable but I feel like that's missing a lot of context and lifecycle stuff that Unity depends on. I tried a quick proof of concept using an AndroidView composable and didn't get very far. Before spending too long trying to figure it out I thought I'd check if there's a known solution. Has anyone tried this before and found a working solution?
Thank you!
Someone posted an answer yesterday and before I could approve it, it was removed. So here's my version of the answer I was given yesterday. To whoever posted it - thank you.
@Composable
fun UnityComposable(modifier: Modifier = Modifier) {
val context = LocalContext.current
val unityPlayer = remember { UnityPlayer(context) }
DisposableEffect(Unit) {
onDispose {
unityPlayer.quit()
}
}
AndroidView(
modifier = modifier,
factory = { context ->
unityPlayer.apply {
val params = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
layoutParams = params
}
},
update = { view ->
unityPlayer.settings?.getInt("gles_mode", 1).also {
if (it != null) {
// Unsure if this is required, but I have it and it works
unityPlayer.init(it, false)
}
}
view.windowFocusChanged(true)
}
)
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> unityPlayer.resume()
Lifecycle.Event.ON_PAUSE -> unityPlayer.pause()
Lifecycle.Event.ON_DESTROY -> unityPlayer.quit()
else -> {}
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}