What is/are the Unityscript/C#/Java example file/s of “•Rendering to custom java surfaces. Exposed in Unity as additional displays.” in http://unity3d.com/unity/whats-new/unity-5.0 ?
UnityPlayer now expose a function “boolean displayChanged(int index, Surface surface)”. Using this function you can attach your own surface to Unity. If you attach a surface using index 0 you will override the main unity surface. One thing you have to make sure of is to call this function anytime the Surface properties change (i.e. width/height/format). If you want to detach a surface you can call displayChanged with a null argument.
The c# api for accessing that surface is promoted through the Display api.
@bitter :
Are you 100% sure both your C# API and the Unity 5 promoted feature are link? The C# api you pointed has something to do with the “Rendering to custom java surfaces”. This promoted feature works on Android and the C# doc talk about about a feature working on IPhone.
I am actively looking for some Documentation on this feature, but on the java side, I mean, when the Android native java side of the app.
I am bumping this topic, because this new Unity 5 feature can be a miracle solution for making Android Live Wallpaper with the Unity Player. Unfortunately, I cannot use the function because I still has an exception trying to initiating the UnityPlayer with the Wallpaper Service,. The error is bellow:
Process: com.sien.test.androidplayer5, PID: 6445
java.lang.NullPointerException: Attempt to invoke virtual method ‘boolean com.unity3d.player.UnityPlayer.displayChanged(int, android.view.Surface)’ on a null object reference
at com.sien.test.androidplayer5.GLWallpaperService$GLEngine.onSurfaceCreated(GLWallpaperService.java:103)
at android.service.wallpaper.WallpaperService$Engine.updateSurface(WallpaperService.java:751)
at android.service.wallpaper.WallpaperService$Engine.attach(WallpaperService.java:881)
at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:1168)
at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:37)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
If I were to guess you are trying to invoke displayChanged() on a null object.
UnityPlayer player = null;
player.displayChanged(0, myawesomesurface);
In this days I’m trying to attach surface from Unity to Java program, but I don’t have any success.
Below is link to my two projects:
One project for Unity and other to Eclipse.
After that you build and deploy the project, run one time the application and later try to initialize Wallpaper no errors, but nothing is displayed.
You have to run one time because I’m using the instance of activity to use later on Wallpaper.
I used the method “displayChanged”, but nothing is displayed.
I’ve done several tests but got no success yet!
If you make any changes in the code and the program will display any image of Unity, please share your changes.
Best regards.
@bitter
Is there any chance for documentation on how and when to use UnityPlayer.onDisplayChanged
? The Display api docs don’t even mention Android.
What I’m trying to do is to make a live wallpaper. Problem is, live wallpaper application generally has no Activity, just a WallpaperService, and UnityPlayer “UnityPlayer(ContextWrapper)” constructor crashes when the argument is anything other than Activity (i.e. “new UnityPlayer(this.getApplication())”). The error is below:
Error
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: java_object == null
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] in call to GetObjectClass
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] from void com.unity3d.player.UnityPlayer.nativeFile(java.lang.String)
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] "main" prio=5 tid=1 Runnable
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] | group="main" sCount=0 dsCount=0 obj=0x7415a000 self=0xb8cac7b8
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] | sysTid=29034 nice=0 cgrp=default sched=0/0 handle=0xb6fbabec
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] | state=R schedstat=( 0 0 0 ) utm=2 stm=9 core=1 HZ=100
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] | stack=0xbe7b0000-0xbe7b2000 stackSize=8MB
12-06 07:58:22.857: A/art(29034): art/runtime/check_jni.cc:65] | held mutexes= "mutator lock"(shared held)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #00 pc 000047c0 /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #01 pc 00002fc1 /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #02 pc 002464ed /system/lib/libart.so (art::smile:umpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+68)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #03 pc 0022aedd /system/lib/libart.so (art::Thread::smile:ump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+144)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #04 pc 000b1b2b /system/lib/libart.so (art::JniAbort(char const*, char const*)+602)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #05 pc 000b2295 /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+60)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #06 pc 001a8559 /system/lib/libart.so (art::JNI::GetObjectClass(_JNIEnv*, _jobject*)+556)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #07 pc 000b7011 /system/lib/libart.so (art::CheckJNI::GetObjectClass(_JNIEnv*, _jobject*)+48)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #08 pc 004f7f44 /data/app/com.zimm.est-1/lib/arm/libunity.so (NativeRuntimeException::IsErrorReporterActive()+208)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #09 pc 004f7358 /data/app/com.zimm.est-1/lib/arm/libunity.so (NativeRuntimeException::install_signal_handlers()+36)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #10 pc 004f1028 /data/app/com.zimm.est-1/lib/arm/libunity.so (NativeRuntimeException::GetExceptionState()+72)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #11 pc 004f23c4 /data/app/com.zimm.est-1/lib/arm/libunity.so (nativeFile(_JNIEnv*, _jobject*, _jstring*)+16)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] native: #12 pc 000076db /data/dalvik-cache/arm/data@app@com.zimm.est-1@base.apk@classes.dex (Java_com_unity3d_player_UnityPlayer_nativeFile__Ljava_lang_String_2+102)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] at com.unity3d.player.UnityPlayer.nativeFile(Native method)
12-06 07:58:22.858: A/art(29034): art/runtime/check_jni.cc:65] at com.unity3d.player.UnityPlayer.<init>(UnityPlayer.java:140)
This happens on all Unity 5.x versions, from 5.0 to 5.3. I can send a repro project if needed.
If I use an actual Activity to instantiate the UnityPlayer, and then use UnityPlayer.onDisplayChanged
in the live wallpaper service to redirect Unity output, then it kind of works, but extremely buggy, not to mention the UnityPlayer is tied with Activity, and live wallpapers don’t even have a main Activity.
TL;DR: Is there a way to use UnityPlayer for drawing on a custom surface without any Activity?
@ZimM_1 that crash is a bug for sure. It should definitely be possible to run Unity without an activity. But with limited functionality of course. The limitations are not really Unity specific but the same as for any Android application without an Activity. For instance as of ‘M’ only Activities can be granted dangerous permissions iirc
Anyway, please file a bug on the crash. I know what the issue is and it should be easy to fix.
In my example I’m using the Unity Activity in background to instantiate UnityPlayer, but nothing appears on the screen.
Only black screen.
Nothing happens, but no errors.
Any advice or tips?
I’ve filled the bug, case #751102.
Limitations are expected, I’m totally fine with that. The only thing that bothers me is that input most probably won’t work without an Activity. But it’d be pretty easy to program some basic input code, so it’s not a big deal.
Also, fun fact: being able to instantiate UnityPlayer without Activity was working fine until Unity 4.1 (or around that), so this is a 2+ years bug that I saw quite a lot of people complain about, and yet seemingly no one before has filed a bug report on it
So you are instantiating UnityPlayer in an Activity in background and then do… what? You have to force Unity to output to your own surface, and also prohibit Unity from pausing, since by default UnityPlayerActivity stops rendering when Activity is paused (which happens when Activity goes to background). But even if you manage to make that work (somewhat), it’d be hard to impossible to actually use that in a project, since that method is an extremely flawed hack, with no good way to make it work without actually not using the Activity. That’s why the fix is required so badly.
@ZimM_1
Thanks for your reply.
I’m making some testing and trying some possibilities!
For now nothing works!
private SurfaceView findSurfaceView(View v)
{
if (v == null) return null;
else if (v instanceof SurfaceView) return (SurfaceView)v;
else if (v instanceof ViewGroup) {
int childCount = ((ViewGroup)v).getChildCount();
for (int i = 0; i < childCount; i++) {
SurfaceView ret = findSurfaceView(((ViewGroup)v).getChildAt(i));
if (ret != null) return ret;
}
}
return null;
}
I thought I could use displayChanged but I instead converted the above to C# so that my C# class with AndroidJavaObject instances can use it.
Any update on this one (case #751102)? I’ve managed to work around this issue with a really ugly hack, but it’d be nice to avoid it, especially if it’s an easy fix on your side
If I Render Unity to my own view,
would it be possible to Override the OnDraw() method and simulate an on-demand render compared to Unity’s continuous render??