把Unity作为Android的子视图
Posted B612灯夫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了把Unity作为Android的子视图相关的知识,希望对你有一定的参考价值。
网上已经有不错的教程来做这件事了,这篇教程也是参考了他们的理论和一些代码,仅仅是作为自己学习的一个记号,来写一写这个过程。
首先做Unity部分:
1、新建工程:我的工程是这样的,白色的方块是可以通过控制转动的,红色方块仅仅是来做标记
2、代码控制,以及和android交互的预设
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class TestView : MonoBehaviour
public GameObject cube;
bool left = true;
bool right = false;
bool stop = false;
// Use this for initialization
void Start ()
// Update is called once per frame
void Update ()
if(left)
cube.transform.Rotate(Vector3.up,1f);
if (right)
cube.transform.Rotate(Vector3.up, -1f);
public void Direction(string tt)
switch (tt)
case "left":
left = true;
right = false;
break;
case "right":
right = true;
left = false;
break;
default:
left = false;
right = false;
break;
void OnGUI()
if(GUILayout.Button("Left",GUILayout.Height(80)))
Direction("left");
if (GUILayout.Button("stop", GUILayout.Height(80)))
Direction("stop");
if (GUILayout.Button("Right", GUILayout.Height(80)))
Direction("right");
3、一些细节:安卓和unity的交互需要android给Unity发送消息
UnityPlayer.UnitySendMessage("Manager", "Direction", "left");其中,Manager是要被控制的Cube的命名,Direction是挂在该物体上脚本的一个函数,left是你要发送给Direction的数据。
之后导出安卓工程,记得设置 bundle
下面是android的部分:
直接打开eclipse,然后通过File->Import->existing Android code 选择你刚才倒出来的目录文件,将安卓工程加载进来。之后Run一边到安卓设备上,如果没什么问题就最好,有问题的话我也不管(。。不是这篇内容。。。)
下面参考了这个链接,不想自己写了http://www.itnose.net/detail/6077772.html,谢谢大神
打开工程的Src文件夹有3个类,分别是UnityPlayerActivity.java,UnityPlayerProxyActivity.java,UnityPlayerNativeActivity.java。前两个打开个后只有一行代码,说的是UnityPlayerActivity和UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity。而打开UnityPlayerNativeActivity中居然有代码,而且我估计这应该是UnityPlayerNativeActivity的源码。
由于关于UnityPlay的资料我只找到这么一个,所以我把UnityPlayerNativeActivity中的代码都贴出来,如果我注解有不对的地方希望大家指正。
/**
* UnityPlayerActivity,UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity
* 而UnityPlayerNativeActivity继承自NativeActivity
* 在该类里定义了一些和ANDROID生命周期相同的回调方法,留给自定义的Activity子类重写。
*/
public class UnityPlayerNativeActivity extends NativeActivity
//UnityPlayer的引用,并且我们不能改变这个引用变量的名字,它被native code所引用
protected UnityPlayer mUnityPlayer;
protected void onCreate (Bundle savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
// 设置显示窗口参数
getWindow().takeSurface(null);
setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
getWindow().setFormat(PixelFormat.RGB_565);
// 创建一个UnityPlayer对象,并赋值给全局的引用变量
mUnityPlayer = new UnityPlayer(this);
//为UnityPlayer设置一些参数
if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))
getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
boolean trueColor8888 = false;
// UnityPlayer.init()方法需要在将view附加到layout之前调用。它将会调用native code
mUnityPlayer.init(glesMode, trueColor8888);
// 从UnityPlayer中获取到Unity的View视图
View playerView = mUnityPlayer.getView();
// 将Unity视图加载到根视图上
setContentView(playerView);
// 使Unity视图获取焦点
playerView.requestFocus();
protected void onDestroy ()
// 当Activity结束的时候调用UnityPlayer.quit()方法,它会卸载之前调用的native code
mUnityPlayer.quit();
super.onDestroy();
// 下面几个方法都是ANDROID相关回调方法,确保在ANDROID执行相应方法时UnityPlayer也需调用相应方法
protected void onPause()
super.onPause();
mUnityPlayer.pause();
protected void onResume()
super.onResume();
mUnityPlayer.resume();
public void onConfigurationChanged(Configuration newConfig)
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
public void onWindowFocusChanged(boolean hasFocus)
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
public boolean dispatchKeyEvent(KeyEvent event)
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);
return super.dispatchKeyEvent(event);
在这里面,unity完成和Android的接口的对应,那么我们只要继承UnityPlayerNativeActivity就可以了。
编写XML视图
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:rowCount="3"
android:columnCount="10">
<FrameLayout
android:id="@+id/fl_forUnity"
android:layout_width="match_parent"
android:layout_height="250dip"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_column="4"
android:layout_row="0"
android:background="#f00" >
</FrameLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rotate Right"
android:id="@+id/right"
android:layout_column="4"
android:layout_row="2"
android:layout_alignTop="@+id/stop"
android:layout_toRightOf="@+id/stop"
android:layout_toEndOf="@+id/stop"
android:layout_marginLeft="30dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Rotate Left"
android:id="@+id/left"
android:layout_column="9"
android:layout_row="2"
android:layout_alignTop="@+id/stop"
android:layout_toLeftOf="@+id/stop"
android:layout_toStartOf="@+id/stop"
android:layout_marginRight="30dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop"
android:id="@+id/stop"
android:layout_below="@+id/fl_forUnity"
android:layout_centerHorizontal="true"
android:layout_margin="10dip" />
</RelativeLayout>
下面新建一个MainActivity用来继承 UnityPlayerNativeActivity
package com.example.unityuseandroid;
import com.unity3d.player.UnityPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.*;
import android.widget.*;
public class MainActivity extends UnityPlayerActivity
Button left;
Button stop;
Button right;
FrameLayout fl_unity;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
left=(Button)findViewById(R.id.left);
stop=(Button)findViewById(R.id.stop);
right=(Button)findViewById(R.id.right);
fl_unity = (FrameLayout)findViewById(R.id.fl_forUnity);
fl_unity.addView(mUnityPlayer.getView());
init();
void init()
left.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// TODO Auto-generated method stub
UnityPlayer.UnitySendMessage("Manager", "Direction", "left");
);
stop.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// TODO Auto-generated method stub
UnityPlayer.UnitySendMessage("Manager", "Direction", "stop");
);
right.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
// TODO Auto-generated method stub
UnityPlayer.UnitySendMessage("Manager", "Direction", "right");
);
比较简单。
当然为了能正确运行,还要在Mianifest.xml修改启动时加载的Activity
如果没什么意外的话,现在就可以运行一下我们的项目了
然后你会发现,点击事件是不能用的,这是什么问题呢?后来才发现是NativeActivity的问题,因为Unity写的和android的结合部分是C++来处理的,所以继承了比较底层的NativeActivity
有两种解决方案
第一种直接将NativeActivity替换成Activity那么我们的功能就正常了
第二种解决办法,仍然继承NativeActivity,不过要在mainifast里面修改一些东西,将下面划红线的地方,全部改为True就可以正常响应事件了
就这样吧,有问题私聊。
待会上传附件
谢谢Java同事Data
以上是关于把Unity作为Android的子视图的主要内容,如果未能解决你的问题,请参考以下文章