将Unity3D项目导出到Android工程中二次开发并实现之间的数据交互
背景:
- 公司需求:在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工程:
新建空项目
下图为最终版
完整工程目录结构:
如上图所示,在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表示生成的是共享库。
在命令行中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显示如上图[armeabi] Install…表示将NdkClass.c编译成功,并自动保存在如下目录 ( androidPlugin前面的”lib”是自动加的,忽略它 ):
/app/src/main/libs/armeabi/libandroidplugin.so
建立Unity3D工程:
在Assets文件夹下新建“Plugins->Android”,并将如上生成的libandroidplugin.so拷贝到该目录下:
/Assets/Plugins/Android/libandroidplugin.so
在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; }}
- 将
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.ja
r拷贝到/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
更多相关文章
- 总结了近百个Android优秀开源项目,覆盖Android开发的每个领域
- Unity3D工程集成到Android工程步骤及问题解决
- [置顶] 深入理解Android工程的编译过程(图文)
- Android小项目练习之一 项目简介
- 提android 项目方案一个求感兴趣者加入