Unity3D研究之Android实现本地数据共享

下面我先说一下在Unity中结合Android NDK实现本地数据的共享的原理,如下图所示 ,Unity工程加入NDK后工程大致可分为三个部分 Android(JAVA) 、 C/C++(.so)、Unity(C#)它们之间是可以相互调用的,在之前的文章中我向大家介绍了 Android与Unity之间相互调用的原理,unity3d研究院之打开Activity与调用JAVA代码传递参数(十八)。这种方式只能相互传递String字符串,少量数据传递时可以使用这种方式。如果是大量数据这样就有点限制了,其实我们可以把C/C++的代码做为一个中转站,实现两边的数据引用与共享。

创新互联一直通过网站建设和网站营销帮助企业获得更多客户资源。 以"深度挖掘,量身打造,注重实效"的一站式服务,以成都网站制作、网站设计、移动互联产品、全网整合营销推广服务为核心业务。十多年网站制作的经验,使用新网站建设技术,全新开发出的标准网站,不但价格便宜而且实用、灵活,特别适合中小公司网站制作。网站管理系统简单易用,维护方便,您可以完全操作网站资料,是中小公司快速网站建设的选择。

首先在官网中下载NDK最新的安装包,安装包分为三个版本这里我下载使用的是MAC OS版本,最新版本已经到了R8。

下载地址:http://developer.android.com/sdk/ndk/index.html

OK,我们在Eclipse中创建一个Android工程,在res与src平级文件夹目录下创建一个jni的文件夹。接着在文件夹中创建两个代码文件,分别是C与C++还有一个配置文件Android.mk。

        c.c代码一共分为两个方法,先说说方法Java_com_xys_UnityTestActivity_TestAddInt 这个方法是漏给Java代码调用的,jint表示此方法的返回值为整形,数据类型还可以是jlong 、jfloat、jdouble、 jobject、jboolean、jbyte、jchar、jshort,搞程序的一看就应该明白了吧?我就不一一解释了。 方法名中java开头是标准用法,com_xys表示当前程序的包名,UnityTestActivity表示当前类,TestAddInt表示方法名,在Android中就是调用这个方法的,这个方法实现了一个简单的整形相加的操作。在说说第二个方法int addInt(),这个方法是留给Unity中C#语言调用的,它的结构与上面不一样不能在Java代码中调用,同样它也就是实现整形相加的操作。

先是C的文件 c.c

[代码]c#/cpp/oc代码:

01#include
02#include
03 
04//Android中java代码调用此方法
05jint
06Java_com_xys_UnityTestActivity_TestAddInt( JNIEnv* env, jobject thiz ,jint a,jint b)
07{
08    return addInt(a,b);
09}
10 
11//Unity中C#代码调用此方法
12int addInt(int a, int b)
13{
14    return a + b;
15}

在看看C++文件,它和C文件的调用原理差不多,不过值得注意的是C++中一定要把需要调用的方法写在extern “C”{ } 中,否则无法调用。

cplus.cpp

[代码]c#/cpp/oc代码:

01#include
02#include
03 
04//声明一个类
05class  MyClass
06{
07    public:
08    static float add(float a, float b)
09    {
10        return a + b;
11    }
12 
13};
14 
15//外部调用的方法需要写在这里
16extern "C"
17{
18 
19    jfloat
20    Java_com_xys_UnityTestActivity_TestAddFloat( JNIEnv* env, jobject thiz ,jfloat a,jfloat b)
21    {
22        return MyClass::add(a,b);
23    }
24 
25    float addFloat(float a,float b)
26    {
27        return MyClass::add(a,b);
28    }
29 
30}

 再看看第三个配置文件,文件中比较重要的两个变量 LOCAL_MODULE表示生成出的.so的名称 LOCAL_SRC_FILES 表示需要编译的文件,如果是多个C/C++文件中间需要使用  \ 隔开。

Android.mk

[代码]c#/cpp/oc代码:

01LOCAL_PATH := $(call my-dir)
02 
03include $(CLEAR_VARS)
04 
05LOCAL_MODULE    := xuanyusong
06LOCAL_SRC_FILES := \
07c.c \
08cplus.cpp
09 
10include $(BUILD_SHARED_LIBRARY)

 OK ,此时C/C++代码的准备工作就做完了,下面我们学习如何把c.c 与 cplus.cpp 一个C文件与一个C++文件一同打包进.so文件中。首先打开终端,cd到刚刚创建的jni目录下,然后执行一开始下载的DNK开发包中的ndk- build命令,你可以直接在android-ndk-r8中找到ndk-build然后拖拽到终端中即可,如果代码没有错误如图所示表示.so文件编译成功。

再看看当前Android工程的目录结构,libs -> armeabi -> libxuanyusong.so 就是刚刚编译生成的.so文件,xuanyusong.so前面的lib是系统默认添加的,大家不必惊慌。

下面我们编写Java代码,学习如何在java代码中调用C/C++,代码比较简单在OnCreat()方法中分别调用C与C++的方法,并且弹出一个Toast显示在界面中。

UnityTestActivity.java

[代码]java代码:

01package com.xys;
02 
03import android.os.Bundle;
04import android.widget.Toast;
05 
06import com.unity3d.player.UnityPlayerActivity;
07 
08public class UnityTestActivity extends UnityPlayerActivity
09{
10 
11    @Override
12    public void onCreate(Bundle savedInstanceState)
13    {
14        super.onCreate(savedInstanceState);
15 
16        //在这里调用.so中的两个方法,并且显示在屏幕中
17        Toast.makeText(getApplicationContext(), "整形  = " + TestAddInt(1,2)+" 浮点型 = " + TestAddFloat(1.5f, 1.1f),
18                 Toast.LENGTH_LONG).show();
19 
20    }  
21 
22    //声明c.c中的TestAddInt方法
23    public native  int TestAddInt(int a, int b); 
24 
25    //声明cplus.cpp中的TestAddFloat方法
26    public native  float TestAddFloat(float a, float b); 
27 
28    static
29    {
30        //加载.so文件
31        System.loadLibrary("xuanyusong");
32    } 
33 
34}

好的,我们终于把Android的工程建立完毕。接着我们需要把工程拷贝至Unity的Android插件中, 插件的制作还有谁不会?? 不会的朋友请看之前的文章,这里就不赘述。如下图所示,Android插件已经制作完毕放在Unity中。目录结构如下所示。

编写test.cs脚本,实现通过C#脚本直接访问libxuanyusong.so文件,直接把test.cs挂在摄像机上。使用 [DllImport ("xuanyusong")]来引入.so 的方法, 这里注意的是 一定要把.so文件名的lib 与后缀.so去掉, 最后将数据通过GUI显示在屏幕中。

test.cs

[代码]c#/cpp/oc代码:

01using UnityEngine;
02using System.Collections;
03using System.Runtime.InteropServices;
04public class test : MonoBehaviour {
05 
06    int i = 0 ;
07    float f = 0.0f;
08 
09    //引用C 、C++中的方法
10    [DllImport ("xuanyusong")]
11    private static extern int addInt(int a,int b);
12    [DllImport ("xuanyusong")]
13    private static extern float addFloat(float a,float b); 
14 
15    void Start ()
16    {
17        //调用方法中相加函数
18        i = addInt (1,2);
19        f = addFloat (1.0f,2.2f);
20 
21    }
22 
23    void OnGUI()
24    {
25 
26        //将相加后的信息显示在屏幕中
27        if(i !=0)
28        GUILayout.Label(" use  c  =" +  i );
29 
30        if(f !=0.0f)
31        GUILayout.Label(" use  cplus  =" +  f );
32    }
33}

所有的工作已经做完,我们打包编译上真机,首先是在Android中调用.so时 弹出结果的Toast 。

然后是在Unity中调用.so后通过GUI绘制在屏幕中的结果。

文章标题:Unity3D研究之Android实现本地数据共享
URL标题:http://www.gawzjz.com/qtweb/news3/199503.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联