Open IgeeTheron opened 2 years ago
Hi @IgeeTheron Can you type Unity Version and Device Info? Also Can you show source code with Unity Page?
Unity version: 2021.3.4f1
Device Info: Galaxy A31 One UI verion: 3.1 Android version: 11
Unity Home screen
import 'dart:async';
import 'package:eden/config/strings.dart';
import 'package:eden/enums/chapter_type.dart';
import 'package:eden/models/recorded_data.dart';
import 'package:eden/models/user_chapter_progress.dart';
import 'package:eden/screens/chapters/chapter_info.dart';
import 'package:eden/screens/mantras/mantra_menu.dart';
import 'package:eden/screens/popup/coming_soon.dart';
import 'package:eden/services/connection_service.dart';
import 'package:eden/services/impl/connection_service_impl.dart';
import 'package:eden/services/impl/user_chapter_progress_service_impl.dart';
import 'package:eden/services/user_chapter_progress_service.dart';
import 'package:eden/shared/constants.dart';
import 'package:eden/shared/fade_page_route.dart';
import 'package:eden/shared/loading.dart';
import 'package:eden/utilities/EdenUtils.dart';
import 'package:eden/utilities/print_color.dart';
import 'package:eden/widgets/settings/settings_menu.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_unity_widget/flutter_unity_widget.dart';
import 'package:eden/shared/globals.dart' as globals;
import 'package:google_fonts/google_fonts.dart';
import 'package:just_audio/just_audio.dart';
import 'package:visibility_aware_state/visibility_aware_state.dart';
class Home extends StatefulWidget {
_HomeState createState() => _HomeState();
}
class _HomeState extends VisibilityAwareState<Home> with TickerProviderStateMixin {
final GlobalKey<ScaffoldState> _key = GlobalKey();
final ConnectionService _connectionService = ConnectionServiceImpl();
UnityWidgetController _unityWidgetController;
UserChapterProgressService _userChapterProgressService;
RecordedData _recordedData;
AnimationController _animationControllerIn;
AudioPlayer _audioPlayerButton;
bool _ignorePointer = false;
bool _loading = false;
int transitionSize = 1;
List<UserChapterProgress> chapters;
@override
void initState() {
_connectionService.checkConnection();
_userChapterProgressService = new UserChapterProgressServiceImpl();
_audioPlayerButton = new AudioPlayer();
_animationControllerIn = new AnimationController(vsync: this, duration: Duration(milliseconds: 300));
super.initState();
}
@override
void onVisibilityChanged(WidgetVisibility visibility) async {
print(PrintColor.magentaExtended("HOME: onVisibilityChanged " + PrintColor.cyan("$visibility")));
// print("context.widget.toStringShort: ${context.widget.toStringShort()}");
// print(PrintColor.yellow("${ModalRoute.of(context).isCurrent}"));
// print(PrintColor.yellow("${context.widget.toStringShort()}"));
// print(PrintColor.yellow("${ModalRoute.of(context).currentResult}"));
switch (visibility) {
case WidgetVisibility.VISIBLE:
{
print(PrintColor.magentaExtended("VISIBLE"));
print(PrintColor.magentaExtended("SWITCH: onVisibilityChanged " + PrintColor.cyan("$visibility")));
if (_unityWidgetController != null) {
print(PrintColor.magentaExtended("_unityWidgetController has a value"));
final _isPaused = await this._unityWidgetController.isPaused();
initStart(_isPaused);
} else {
print(PrintColor.magentaExtended("_unityWidgetController is null"));
initStart(false);
}
}
break;
case WidgetVisibility.INVISIBLE:
{
print(PrintColor.magentaExtended("INVISIBLE"));
print(PrintColor.magentaExtended("SWITCH: onVisibilityChanged" + PrintColor.cyan("$visibility")));
// TODO: Fade out sound on settings page instead of immediate stop, ERROR: The cemented code makes soo that when hiding app on drawer the pause does not trigger
// if (_key.currentState.isDrawerOpen) {
// fadeSoundOut();
// await Future.delayed(Duration(milliseconds: 1800));
// }
// if (!ModalRoute.of(context).isCurrent) {
await _unityWidgetController.pause();
// }
}
break;
case WidgetVisibility.GONE:
{
print(PrintColor.magentaExtended("GONE"));
}
break;
}
super.onVisibilityChanged(visibility);
}
@override
void dispose() {
print(PrintColor.magentaExtended("unity dispose"));
_connectionService.dispose();
globals.unityWidgetController = null;
_unityWidgetController.dispose();
_audioPlayerButton.dispose();
super.dispose();
}
@override
Widget build(context) {
print(PrintColor.magentaExtended("BUILD"));
return Stack(
children: [
IgnorePointer(
ignoring: _ignorePointer,
child: MaterialApp(
home: Scaffold(
key: _key,
backgroundColor: Colors.grey[400],
body: Container(
child: Stack(
children: <Widget>[
Container(
color: Colors.black,
),
Container(
child: UnityWidget(
onUnityCreated: _onUnityCreated,
onUnityMessage: onUnityMessage,
fullscreen: false,
borderRadius: BorderRadius.circular(0),
),
),
],
),
),
drawer: SettingsMenu(unityWidgetController: _unityWidgetController),
floatingActionButton: FloatingActionButton(
heroTag: "Home",
elevation: 0,
backgroundColor: primaryColor,
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 22,
child: Image.asset(
"assets/icons/meditation_icon_white.png",
),
),
onPressed: null,
),
floatingActionButtonLocation: FloatingActionButtonLocation.startDocked,
bottomNavigationBar: BottomAppBar(
color: Colors.white,
// shape: const CircularNotchedRectangle(),
child: Row(
children: <Widget>[
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.fromLTRB(12, 42, 0, 0),
child: Text(
"HOME",
style: GoogleFonts.montserrat(
textStyle: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w300,
),
),
),
),
],
),
),
Expanded(
child: SizedBox.fromSize(
size: Size(76, 76),
child: InkWell(
splashColor: Colors.transparent,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
height: 30,
child: Image.asset(
"assets/icons/hebrew_black.png",
),
),
SizedBox(height: 10),
Text(
"EXTRA",
style: GoogleFonts.montserrat(
textStyle: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w300,
),
),
),
SizedBox(height: 10),
],
),
onTap: () async {
setState(() {
transitionSize = 1;
});
fadeSoundOut();
await Future.delayed(Duration(milliseconds: 1500));
_animationControllerIn.reverse().whenComplete(() {
print(PrintColor.magentaExtended("_animationControllerIn"));
Navigator.of(context).push(FadePageRoute(MantraMenu(), 2));
});
},
),
),
),
Expanded(
child: Container(
padding: EdgeInsets.only(right: 12),
child: SizedBox.fromSize(
size: Size(76, 76),
child: InkWell(
splashColor: Colors.transparent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Column(
children: [
const Icon(Icons.menu, size: 30,),
SizedBox(height: 10),
Text(
"SETTINGS",
style: GoogleFonts.montserrat(
textStyle: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w300,
),
),
),
SizedBox(height: 10),
],
),
],
),
onTap: () {
_key.currentState.openDrawer();
},
),
),
),
),
],
),
),
),
),
),
/// Transition animation
FadeTransition(
opacity: Tween(begin: 1.0, end: 0.0).animate(_animationControllerIn),
child: Container(
color: Colors.black,
height: MediaQuery.of(context).size.height * transitionSize,
width: MediaQuery.of(context).size.width * transitionSize,
),
),
/// Loader
(_loading) ? Loading() : Container(),
],
);
}
void _onUnityCreated(controller) async {
print(PrintColor.magentaExtended("Unity Created"));
print(PrintColor.cyan("$controller"));
if (controller != null) {
setState(() {
_loading = true;
});
this._unityWidgetController = controller;
globals.unityWidgetController = controller;
await _unityWidgetController.pause();
String name;
chapters = await _userChapterProgressService.getAllChapters();
chapters.forEach((chapter) {
if (chapter.status.toLowerCase().trim() != TO_DO.toLowerCase().trim()) {
name = chapter.title;
}
});
print(PrintColor.magentaExtended("startingPositions"));
print(EdenUtils.capitalize(name));
print(PrintColor.magentaExtended("startingPositions"));
startingPositions(EdenUtils.capitalize(name));
await Future.delayed(Duration(milliseconds: 9000));
final _isPaused = await this._unityWidgetController.isPaused();
initStart(_isPaused);
}
}
void initStart(bool isPaused) async {
print(PrintColor.magentaExtended("initStart"));
switch (globals.animNewLevel) {
case ChapterType.CHAPTER2:
startTransitionAnim("CHAPTER2");
break;
case ChapterType.CHAPTER3:
startTransitionAnim("CHAPTER3");
Future.delayed(const Duration(seconds: 7), () {
showDialog(
context: context,
builder: (BuildContext context) {
return ComingSoon();
},
);
});
break;
case ChapterType.CHAPTER4:
startTransitionAnim("CHAPTER4");
break;
case ChapterType.CHAPTER5:
startTransitionAnim("CHAPTER5");
break;
default:
break;
}
globals.animNewLevel = null;
if (isPaused) {
Future.delayed(
Duration(milliseconds: 50),
() async {
await this._unityWidgetController.resume();
},
);
}
await _animationControllerIn.forward().whenComplete(() {
print(PrintColor.magentaExtended("_animationControllerIn from black"));
setState(() {
_ignorePointer = false;
transitionSize = 0;
});
fadeSoundIn();
});
final _isPaused = await this._unityWidgetController.isPaused();
print(PrintColor.magentaExtended("InitStart: " + PrintColor.cyan("$_isPaused")));
if (_isPaused) {
initStart(_isPaused);
} else if (_loading == true) {
print(PrintColor.magentaExtended("Loading to false"));
setState(() {
_loading = false;
});
}
}
void onUnityMessage(message) async {
print(PrintColor.magentaExtended("onUnityMessage"));
print(PrintColor.cyan("$_ignorePointer"));
if (!_ignorePointer && (message == "Chapter1") || (message == "Chapter2")) {
setState(() {
_ignorePointer = true;
});
print(PrintColor.magentaExtended("Message"));
print(PrintColor.magentaExtended("Received message from unity: " + PrintColor.cyan("${message.toString()}")));
chapters = await _userChapterProgressService.getAllChapters();
bool accessGranted = false;
chapters.forEach((chapter) {
if (message.toString() == EdenUtils.capitalize(chapter.title)) {
accessGranted = chapter.status.toLowerCase().trim() != TO_DO.toLowerCase().trim();
}
});
print(PrintColor.magentaExtended("accessGranted"));
print(accessGranted);
print(PrintColor.magentaExtended("accessGranted"));
if (accessGranted) {
await _audioPlayerButton.setAsset("assets/audio/harp_button_1.mp3");
_audioPlayerButton.play();
_recordedData = new RecordedData();
setState(() {
transitionSize = 1;
});
_animationControllerIn.reverse().whenComplete(() {
print(PrintColor.magentaExtended("_animationControllerIn to dark"));
navigate(message.toString());
});
}
} else {
print(PrintColor.redExtended("Not active"));
}
}
void navigate(String message) {
print(PrintColor.magentaExtended("navigate"));
print(PrintColor.cyan("$_ignorePointer"));
switch (message) {
/// Display Chapter1
case "Chapter1":
{
print(PrintColor.magentaExtended("Load Chapter1"));
_recordedData.chapterType = ChapterType.CHAPTER1;
_recordedData.chapterTitle = "Chapter1";
_recordedData.nextChapterType = ChapterType.CHAPTER2;
_recordedData.nextChapterTitle = "Chapter2";
// await Future.delayed(const Duration(milliseconds: 300), (){});
Navigator.of(context).push(FadePageRoute(ChapterInfo(recordedData: _recordedData), 2));
}
break;
/// Display Chapter2
case "Chapter2":
{
print(PrintColor.magentaExtended("Load Chapter2"));
_recordedData.chapterType = ChapterType.CHAPTER2;
_recordedData.chapterTitle = "Chapter2";
_recordedData.nextChapterType = ChapterType.CHAPTER3;
_recordedData.nextChapterTitle = "Chapter23";
// await Future.delayed(const Duration(milliseconds: 300), (){});
Navigator.of(context).push(FadePageRoute(ChapterInfo(recordedData: _recordedData), 2));
}
break;
/// Display Chapter3
// case "Chapter3": {
// print(PrintColor.magentaExtended("Load Chapter3"));
//
// _recordedData.chapterType = ChapterType.CHAPTER3;
// _recordedData.chapterTitle = "Chapter3";
// _recordedData.nextChapterType = ChapterType.CHAPTER4;
// _recordedData.nextChapterTitle = "Chapter4";
//
// // await Future.delayed(const Duration(milliseconds: 300), (){});
//
// Navigator.of(context).push(FadePageRoute(ChapterInfo(recordedData: _recordedData), 2));
// }
// break;
//
// /// Display Chapter4
// case "Chapter4": {
// print(PrintColor.magentaExtended("Load Chapter4"));
//
// _recordedData.chapterType = ChapterType.CHAPTER4;
// _recordedData.chapterTitle = "Chapter4";
// _recordedData.nextChapterType = ChapterType.CHAPTER5;
// _recordedData.nextChapterTitle = "Chapter5";
//
// // await Future.delayed(const Duration(milliseconds: 300), (){});
//
// Navigator.of(context).push(FadePageRoute(ChapterInfo(recordedData: _recordedData), 2));
// }
// break;
//
// /// Display Chapter5
// case "Chapter5": {
// print(PrintColor.magentaExtended("Load Chapter5"));
//
// _recordedData.chapterType = ChapterType.CHAPTER5;
// _recordedData.chapterTitle = "Chapter5";
//
// // await Future.delayed(const Duration(milliseconds: 300), (){});
//
// Navigator.of(context).push(FadePageRoute(ChapterInfo(recordedData: _recordedData), 2));
// }
// break;
default:
{
print(PrintColor.redExtended("Not active"));
}
break;
}
}
void startTransitionAnim(String name) {
print(PrintColor.magentaExtended("SEND MESSAGE startTransitionAnim"));
_unityWidgetController.postMessage("Main Camera", "StartTransitionAnim", name);
}
void startingPositions(String name) {
print(PrintColor.magentaExtended("SEND MESSAGE StartingPositions"));
_unityWidgetController.postMessage("Main Camera", "StartingPositions", name);
}
void fadeSoundIn() {
_unityWidgetController.postMessage("Main Camera", "FadeSoundIn", "Transition");
}
void fadeSoundOut() {
_unityWidgetController.postMessage("Main Camera", "FadeSoundOut", "Transition");
}
}
This gets called every time I return to the app.
D/FlutterUnityController(28989): onResume D/FlutterUnityController(28989): Attaching unity to view
Since i am playing and pausing it manual what can I do to disable the automatic onResume function
Can you try this with the alternative type of android PlatformView?
You used to be able to switch using useAndroidViewSurface: /*true or false*/
but Flutter 3.0 broke the false option.
This parameter is ignored and forced to true in the latest versions of the plugin.
I've found this Flutter 3.0 workaround kind of buggy, so I prefer to use the plugin on Flutter 2.10.5 until the issue gets fixed.
Two way to try it:
use Flutter 2.10.5 with Flutter_unity_widget 2022.1.0+7.
use useAndroidViewSurface: false
use Flutter beta 3.3.0-0.0.pre (this seems to fix the flutter 3 issue)
Use a local copy of the flutter_unity_widget plugin, like the example project does.
Uncomment the following lines in /lib/src/io/device_method.dart
to restore the parameter, and use useAndroidViewSurface: false
// commented for 3.0.0 changes in platform view rendition
// if (!useAndroidViewSurface) {
// return AndroidView(
// viewType: _viewType,
// onPlatformViewCreated: onPlatformViewCreated,
// gestureRecognizers: gestureRecognizers,
// creationParams: creationParams,
// creationParamsCodec: const StandardMessageCodec(),
// hitTestBehavior: PlatformViewHitTestBehavior.opaque,
// layoutDirection: TextDirection.ltr,
// );
// }
@timbotimbo
Thanks for the advice. I commented out the code and it fixed the issue i had when the keyboard opens up (Unity resumed each time a keyboard was opened up).
But the package issue remains and is worse now. When opening ImagePicker and closing it unity displays over other flutter widgets.
Any time you leave the app and come back unity displays over the flutter widgets. Any solution for this?
Hello, I have a home screen were unity scene is located. On that screen I have a menu with a account button. When clicking on the account button the unityWidgetController.pause() is called and it opens up a new page where you can select different options. Profile is one of the options that you can choose to enter. Once you are on the profile screen you can edit your profile image.
The issue I currently have is when I click to change my profile image, the ImagePicker is called and unity is resumed automatically. This only happens on android.
I want to prevent unity from automatically resuming.
The code below is what I am currently using to bypass this issue just by pausing the unity widget when exiting the image picker.
This is what I get in my console
Unity also automatically plays when I pause unity and try to sign in using google or Apple. It seems to me whenever you leave the app and come back it plays.