标签:unity android unity3d与android交互
这两天刚刚接触Unity3d,之前一直是做android开发,对于Unity3d的开发有专门的人才,我主要涉及在Unity3d与android的交互,经过两天是实验终于完成了下面的效果:
本来想写几篇博客,来详细说明下Unity3d导出android Project然后再进行二次开发的过程,后来发现几篇博客,过程和我的类似,对于重复的过程我就不写了,大家参考他的博客就可以了。而且,包括了Unity3d调用android脚本,这一块我暂时还没有涉及。
在此,道一声博主辛苦,对于上面的三篇博客大家看完之后,肯定已经可以从Unity3d导出android project,然后再倒入Eclipse了。我们可以看到MainActivity不是继承自NativeActivity就是集成自UnityPlayerActivity(或者UnityPlayerNativeActivity),这样就会给新手一个错觉,就是要展示Unity3d的视图,就必须要集成自这几个接口,那么这个想法,是错误的,具体大家可以参考一下这个博客:
这个帖子中,就是使用继承自Activity的类来展示的U3d的视图。
这样的话,之前可能存在的一个问题,如果只能继承自那几个类,那么supportV4包中的Fragment岂不是不能用了,我们都知道,android.app.Fragment只支持2.3以上的版本,而V4中可以支持到1.6,所以一般来说都推荐大家使用V4包中的Fragment。
好了,说完这个问题,我们就看上面那个效果,如果在android原生应用的话,这个是很常见也很简单的应用,我们可以不停的切换中间的Fragment。
那么换成Fragment来展示U3d,并且相互切换的话,应该怎么样书写代码呢?大家看看下面两个代码块。
/**
* 主界面
* @author gavin
*
*/
public class MainActivity extends FragmentActivity implements OnClickListener {
private Button btn1;
private Button btn2;
private FragmentManager fm;
View playerView;
private Fragment currentFragment;
private U3dFragment u3dFragment = new U3dFragment();
private MenuOneFragment menuOneFragment = new MenuOneFragment();
private MenuTwoFragment menuTwoFragment = new MenuTwoFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Constants.mUnityPlayer = new UnityPlayer(this);
int glesMode = Constants.mUnityPlayer.getSettings().getInt("gles_mode", 1);
boolean trueColor8888 = false;
Constants.mUnityPlayer.init(glesMode, trueColor8888);
fm = getSupportFragmentManager();
setContentView(R.layout.activity_main);
initView();
currentFragment = u3dFragment;
changeFragment(currentFragment);
}
/**
* 初始化控件
*/
private void initView(){
btn1 = (Button) findViewById(R.id.btn1);
btn2 = (Button) findViewById(R.id.btn2);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.btn1:
Toast.makeText(MainActivity.this, "btn1", Toast.LENGTH_SHORT).show();
if(currentFragment instanceof U3dFragment || currentFragment instanceof MenuTwoFragment){
currentFragment = menuOneFragment;
changeFragment(currentFragment);
}else{
currentFragment = u3dFragment;
changeFragment(currentFragment);
}
break;
case R.id.btn2:
Toast.makeText(MainActivity.this, "btn2", Toast.LENGTH_SHORT).show();
if(currentFragment instanceof U3dFragment || currentFragment instanceof MenuOneFragment){
currentFragment = menuTwoFragment;
changeFragment(currentFragment);
}else{
currentFragment = u3dFragment;
changeFragment(currentFragment);
}
break;
}
}
/**
* 方法用来改变界面
*/
private void changeFragment(Fragment fragment){
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content, fragment);
ft.commit();
}
protected void onDestroy ()
{
Constants.mUnityPlayer.quit();
super.onDestroy();
}
// onPause()/onResume() must be sent to UnityPlayer to enable pause and resource recreation on resume.
protected void onPause()
{
super.onPause();
Constants.mUnityPlayer.pause();
}
protected void onResume()
{
super.onResume();
Constants.mUnityPlayer.resume();
}
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
Constants.mUnityPlayer.configurationChanged(newConfig);
}
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
Constants.mUnityPlayer.windowFocusChanged(hasFocus);
}
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return Constants.mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);
return super.dispatchKeyEvent(event);
}
}
上面是Activity的写法。
/**
* 展示u3d的界面
* @author gavin
*
*/
public class U3dFragment extends Fragment {
private Activity context;
View playerView;
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
context = activity;
}
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
playerView = Constants.mUnityPlayer.getView();
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
playerView.setLayoutParams(lp);
if(playerView.getParent() != null){
((ViewGroup)playerView.getParent()).removeAllViews();
}
return playerView;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
// Constants.mUnityPlayer.quit();
super.onDestroy();
}
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Constants.mUnityPlayer.pause();
}
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
Constants.mUnityPlayer.resume();
}
}
上面是展示U3d视图的Fragment的写法。
要注意的有以下几点:
1.UnityPlayer这个对象被定义为了静态变量,在MainActivity中进行初始化,在Fragment中进行使用,用来获取Unity3d的view。
2.在U3dFragment中没有在onDestroy中,调用quit()方法。
3.在U3dFragment中的onCreateView()方法中,进行了下面的处理。
((ViewGroup)playerView.getParent()).removeAllViews();
对于上面三个问题,如果不处理会相应的引发下面三个问题。
1.展示U3d视图的Fragment无法显示Unity3d的动画效果。
2.切换页面的时候会报下面的错误:
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeVideoFrameCallback:VILII
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSoftInputClosed:V
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetTouchDeltaY:VF
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetInputString:VL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetInputCanceled:VZ
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetExtras:VL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetDefaultDisplay:VI
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeResume:V
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeResize:VIIII
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRequestedAA:I
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRequested32bitDisplayBuffer:Z
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRender:Z
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRecreateGfxState:VL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativePause:Z
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeKeysPressed:VL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeInjectEvent:ZL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeInitWWW:VL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeFocusChanged:VZ
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeFile:VL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeDone:V
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeActivityIndicatorStyle:I
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.initJni:VL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.UnitySendMessage:VLLL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetLocationStatus:VI
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetLocation:VFFFFDF
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeForwardEventsToDalvik:VZ
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeDeviceOrientation:VI
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodUnblockStreaming:I
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodProcess:IL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodInitJni:I
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodGetInfo:II
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodBlockStreaming:I
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodProcessMicData:ILI
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/ReflectionHelper;.nativeProxyInvoke:LILL
10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/ReflectionHelper;.nativeProxyFinalize:VI
3.会报下面的错误:
Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child‘s parent first.
现在来说,功能是实现了,但是还有很多可以改进和不明白的地方,大家可以一起讨论一下。
android与fragment交互,fragment显示unity3d视图。
标签:unity android unity3d与android交互
原文地址:http://blog.csdn.net/jiguangcanhen/article/details/40150475