背景:

  • 公司需求:在APP中植入小游戏
  • 鄙人Android开发,对Unity3D不熟,更加愿意将Unity3D中项目导入到Android工程中再二次开发,对网络上方便的‘Android工程导出jar到Unity3D工程发布‘不甚放心以及在APP中植入Unity3D游戏在业务上是一个比较次要的功能,不能影响到原工程的结构。所以研究了将Unity3D项目导出到Android工程中二次开发并实现之间的数据交互
  • 鄙人JNI,NDK资历尚浅,Unity3D开发还欠入门,有诸多不足之处还请各位大神不吝赐教

电脑环境:

  • iMac OS X EI Capitan
  • Android studio 1.4
  • JRE 1.7.0_79-b15 x86_64
  • NDK android-ndk-r10e
  • Unity3D Version 5.2.2f1

Android工程:

  1. 新建空项目
    下图为 最终版 完整工程目录结构:


    将Unity3D项目导出到Android工程中二次开发并实现之间的数据交互_第1张图片

  2. 如上图所示,在src->main目录下新建jni文件夹,创建NdkClass.c和Android.mk文件:

    • NdkClass.c:

      #include #include static JavaVM *gJavaVM;static jobject gCallbackObject = NULL;//Android中java代码调用此方法,以Java_开头,包含包名,方法名。jint Java_test_gavin_com_unityandroidtest_utils_NdkUtil_initNDK(JNIEnv *env, jobject thiz) {    (*env)->GetJavaVM(env, &gJavaVM);    gCallbackObject = (*env)->NewGlobalRef(env, thiz);    return 1;}//Unity3D中C#会调用该方法void calledFromUnity(char *str) {    JNIEnv *env;    int attached = (*gJavaVM)->AttachCurrentThread(gJavaVM, &env, NULL);    jclass jcls = (*env)->FindClass(env, "test/gavin/com/unityandroidtest/utils/NdkUtil");    jmethodID mid = (*env)->GetMethodID(env, jcls, "messageFromNDK", "(Ljava/lang/String;)V");    (*env)->CallVoidMethod(env, gCallbackObject, mid, (*env)->NewStringUTF(env, str));}
    • Android.mk:

      LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := androidpluginLOCAL_SRC_FILES := \NdkClass.cinclude $(BUILD_SHARED_LIBRARY)注:    LOCAL_MODULE表示将要生成的.so文件名;    LOCAL_SRC_FILES表示需要编译的源文件;    BUILD_SHARED_LIBRARY表示生成的是共享库。
      1. 在命令行中cd到工程jni目录,执行ndk-build:

        ➜ jni pwd
        /Users/Gavin/StudioProjects/UnityAndroidTest/app/src/main/jni
        ➜ jni /Applications/ADT/ndk/android-ndk-r10e/ndk-build
        [armeabi] Install : libandroidplugin.so => libs/armeabi/libandroidplugin.so
        ➜ jni

      2. 显示如上图[armeabi] Install…表示将NdkClass.c编译成功,并自动保存在如下目录 ( androidPlugin前面的”lib”是自动加的,忽略它 ):

        /app/src/main/libs/armeabi/libandroidplugin.so


建立Unity3D工程:

  1. 在Assets文件夹下新建“Plugins->Android”,并将如上生成的libandroidplugin.so拷贝到该目录下:

        /Assets/Plugins/Android/libandroidplugin.so
  2. 在script中新建C#文件:AndroidAPI.cs:

    public class AndroidAPI : MonoBehaviour {    [DllImport("androidplugin")]//定义.so文件里面的方法:    private static extern void calledFromUnity (string str);            void OnGUI (){        if (GUI.Button (new Rect (x,y,width,height), text)) {            calledFromUnity("Hello Android");        }    }    //called from android    void CalledFromAndroid(string str){        toastText = str;    }}
  3. AndroidAPI.cs拖到Main Camera上,然后导出为Android工程:
    • * File -> Build Settings -> Player Settings –> Bundle Identifier 随便设置一个值(e.g. : com.baidu.myproject)*
    • * File -> Build Settings -> Player Settings –> 勾上 Google Android Project –> Export*

导入Unity3D工程到Android Studio:

  • assets整个拷贝到Android项目的/app/src/main/目录下。
  • libs中的unity-classes.jar拷贝到/app/lib/目录下。并Add As Library
  • libs中的armeabi-v7a以及x86连同文件夹一起拷贝到/app/src/main/jniLibs/目录下。

增加NdkUtil.java:

  • test.gavin.com.unityandroidtest.utils.NdkUtil:

    static {    System.loadLibrary("androidplugin");}public NdkUtil(Context context) {    this.context = context;    if (1 != initNDK()) {        Toast -> ("初始化失败");    } else {        Toast -> ("初始化成功");    }}public native int initNDK();public void messageFromNDK(String str) {    //接收从NDK传递过来的消息}

修改MainActivity以及R.layout.activity_main:

  • MainActivity:

        package test.gavin.com.unityandroidtest;    public class MainActivity extends UnityPlayerActivity  {        @Override        protected void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.activity_main);            mUnityPlayer = new UnityPlayer(this);            unityView = (LinearLayout) findViewById(R.id.unity_layout);            unityView.addView(mUnityPlayer);            findViewById(R.id.unity_button).setOnClickListener((view) -> {                    //通过UnitySendMessage向Unity发送消息,                    //三个参数分别是接收消息的GameObject,MethodName,参数;                    UnityPlayer.UnitySendMessage("Main Camera", "CalledFromAndroid", "Hello Unity3D");            }        }    }
  • activity_main:

        <?xml version="1.0" encoding="utf-8"?>            

运行Android程序:

点击Unity3D界面中的按钮就可以唤起Android中的Alert,点击Android中的Button就可以在Unity界面中提示“HELLO”

附上源码:点击下载 (请原谅CSDN不让我上传60MB以上的资源)

哦~~,密码是 4afs

更多相关文章

  1. 总结了近百个Android优秀开源项目,覆盖Android开发的每个领域
  2. Unity3D工程集成到Android工程步骤及问题解决
  3. [置顶] 深入理解Android工程的编译过程(图文)
  4. Android小项目练习之一 项目简介
  5. 提android 项目方案一个求感兴趣者加入

随机推荐

  1. Android进行单元测试难在哪-part4
  2. android之官方下拉刷新组件SwipeRefreshL
  3. Android中点9图简易理解
  4. 【Android(安卓)Developers Training】 8
  5. android同步取得电池状态信息
  6. android 支付功能
  7. android中的多媒体应用MediaPlayer
  8. 为什么用Toast,而不是AlertDialog
  9. Android(安卓)Dialog用法总结
  10. Ubuntu Android(安卓)2.3的编译环境 Ubun