第一次写blog,呵呵,有点激动,主要是方便自己以后复习,写的不好请见谅。。。
这次遇到的问题纠结我好久,关键是对Android不熟悉,下面我来说一下我的问题:
用Unity制作Android上的悬浮窗口,窗口背景透明,用Unity4.2很简单,只要把摄像机的Clear Flags属性设置成Solid Color,然后BackGround属性的RGBA均设置为零,
然后再在Android里设置一下背景透明就可以了。
Android的设置:
private LinearLayout view;
private GLSurfaceView mUnityView;
public FloatWindowSmallView(Context context) {
super(context);
mContext = context;
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
LayoutInflater.from(context).inflate(R.layout.float_window_small, this);
view = (LinearLayout) findViewById(R.id.small_window_layout);
viewWidth = view.getLayoutParams().width;
viewHeight = view.getLayoutParams().height;
LayoutParams lp = new LayoutParams (LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
//主要是这里
mUnityView = new GLSurfaceView(Common.application);
mUnityView.setEGLContextClientVersion(2);
mUnityView.setZOrderOnTop(true);
mUnityView.setZOrderMediaOverlay(true);
mUnityView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
mUnityView.setRenderer(Common.mUnityPlayer);
mUnityView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
view.addView(mUnityView,0,lp);
Common.mUnityPlayer.requestFocus();
Common.mUnityPlayer.resume();
//TextView percentView = (TextView) findViewById(R.id.percent);
//percentView.setText(MyWindowManager.getUsedPercentValue(context));
mLongPressRunnable = new Runnable() {
@Override
public void run() {
//performLongClick();
openBigWindow();
}
};
}
但是Unity4.6这样设置就不行,背景是一片黑色:
所以换了个思路,将Unity视图输出成一个纹理,见纹理编译成bity[]传给Android,Android再解析成Imageview显示出来。
1、将摄像机视图输出成纹理:新建一个Render Texture ,将其拖给摄像机的Target Texture
2、将Render Texture 转换成byte[]
this.jc = new AndroidJavaClass("com.gesture.util.ToUnity");
放在Update每桢更新
#if UNITY_ANDROID && !UNITY_EDITOR
byte[] bts = UnityView();
this.jc.CallStatic("picture", bts);
#endif
public byte[] UnityView()
{
Texture2D myTexture2D = new Texture2D(pic.width,pic.height);
RenderTexture.active = pic;
myTexture2D.ReadPixels(new Rect(0, 0, pic.width, pic.height), 0, 0);
myTexture2D.Apply();
RenderTexture.active = null;
byte[] bytes = myTexture2D.EncodeToPNG();
Destroy (myTexture2D);
return bytes;
}
3、Android的设置
XML配置文档:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/small_window_layout"
android:layout_width="120dp"
android:layout_height="120dp" >
<ImageView
android:id="@+id/image_view"
android:layout_width="119dp"
android:layout_height="119dp"/>
</LinearLayout>
<pre name="code" class="java">private LinearLayout view;
private static ImageView image;
public FloatWindowSmallView(Context context) {
super(context);
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
LayoutInflater.from(context).inflate(R.layout.float_window_small, this);
view = (LinearLayout) findViewById(R.id.small_window_layout);
viewWidth = view.getLayoutParams().width;
viewHeight = view.getLayoutParams().height;
image = (ImageView) findViewById(R.id.image_view);
view.addView(Common.mUnityPlayer.getView());
Common.mUnityPlayer.requestFocus();
Common.mUnityPlayer.resume();
}
//把传输过来的字节流转换成Bitmap
public static Bitmap getBitmaoByStream(byte[] imageByte)
{
if (imageByte != null)
{
ByteArrayInputStream byteImage = new ByteArrayInputStream (imageByte);
return BitmapFactory.decodeStream(byteImage);
}
else
{
return null;
}
}
//更新Imageview
public static void ShowTexture(byte[] b)
{
Bitmap bitmap = getBitmaoByStream(b);
image.setImageBitmap(bitmap);
}
4、Unity端调用Android端方法
//显示unity中Render Texture的内容, 供unity调用
public static void picture(final byte[] b)
{
new Handler(Looper.getMainLooper()).post(new Runnable()
{
@Override
public void run()
{
FloatWindowSmallView.ShowTexture(b);
}
});
}
Unity端每桢调用此方法,来刷新ImageView来显示Unity视图,达成效果!!!
但是目前还有一点小问题待解决,就是ImageView不能完全覆盖LinearLayout,否则Unity不运行,还有就是运行效率问题待提高,目前就这样,后续再更新。。。