Unity原生平台插件开发简介(Android/iOS)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/langresser/article/details/57080521

一、Unity如何调用c#之外的语言的内容

1、c/c++可以编译成.so动态库(android平台下),.dll动态库(window平台和编辑器下),.a静态库(iOS平台下),.bundle包(Mac平台下和编辑器下)

      把编译好的东西放在Plugins目录下的指定平台目录下即可。比如iOS平台就放在iOS文件夹下面。Android平台根据cpu架构不同放在对应文件夹下面,比如Anroid/libs/armeabi-v7a。 Window平台及编辑器一般放在x86_64目录下。

      不同动态库可能有冲突,比如x86的动态库以及x86_64的动态库是互相冲突的,这个要在编辑器中设置各个库的对应平台是哪个。

2、iOS扩展也可以直接把.m或者.mm的源文件放在iOS目录下,Unity打包的时候会直接将其打包到xcode工程里面。这个跟编译好静态库是一样的。

3、Window平台的动态库可以用vs来编译,也可以用mingw来编译。如果是c99用的比较多的,推荐用mingw。比如tolua就是用这套来编译的。

4、Android平台的插件如果是java的,推荐用Android Studio来编译。如果是c/c++的,推荐用ndk来编译。这个后面会详细介绍。

5、在c#中直接用DllImport即可直接使用对应函数,比如

#if UNITY_IOS
       // iOS相关函数实现在.m文件中
[DllImport( "__Internal" )]
private static extern float _iOSSetBatteryMonitoringEnabled(); // 启用电量监控

#elif UNITY_ANDROID
        // android相关函数用动态库封装调用

        [DllImport("NativePlugin")]
        private static extern int _AndroidCheckTemperature();   // 检测温度

#endif

6、Android的java的部分,可以直接使用AndroidJavaClass来调用相应的函数,比如以下是获取Android系统电量的代码

try
        {
            using (AndroidJavaClass unityPlayer = new AndroidJavaClass(UNITY_CLASS))
            {
                if (null != unityPlayer)
                {
                    using (AndroidJavaObject currActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
                    {
                        if (null != currActivity)
                        {
                            using (AndroidJavaObject intentFilter = new AndroidJavaObject("android.content.IntentFilter", new object[] { "android.intent.action.BATTERY_CHANGED" }))
                            {
                                using (AndroidJavaObject batteryIntent = currActivity.Call<AndroidJavaObject>("registerReceiver", new object[] { null, intentFilter }))
                                {
                                    int level = batteryIntent.Call<int>("getIntExtra", new object[] { "level", -1 });
                                    int scale = batteryIntent.Call<int>("getIntExtra", new object[] { "scale", -1 });

                                    // Error checking that probably isn't needed but I added just in case.
                                    if (level == -1 || scale == -1)
                                    {
                                        return 50f;
                                    }
                                    return ((float)level / (float)scale) * 100.0f;
                                }

                            }
                        }
                    }
                }
            }
        }
        catch (System.Exception ex)
        {
        }
        return 100;


二、Android平台插件开发注意事项

1、推荐使用Android Studio来开发。不要在用Eclipse ADT了。

2、使用gradle来编译。Android开发的编译经历了Ant、Maven到Gradle。Gradle提供了更加灵活强大的构建支持。从依赖管理到编译控制。

3、推荐使用CMake来编译jni部分代码。官方不再推荐使用ndk来编译了。Android Studio和Gradle也支持CMake。

4、编译出来的东西是一个.aar的文件,这个相对于.jar来说,就是一个更加丰富的包。它可以包含资源、动态库、jar代码、AndroidManifest.xml等等。

5、工程中要加入classes.jar,这个可以在Unity的安装路径中找到。我们需要的UnityPlayer等等都是在这个包里面的。不过有一点比较麻烦的是,在打包完毕之后必须将aar包中的此文件再删除掉(libs/classes.jar),否则会造成冲突导致Unity打包失败。

6、build.gradle中的minSdkVersion targetSdkVersion要跟Unity中的设置一致。如果之前在项目中已经有AndroidManifest.xml了,则这些数据要一致,否则也会编译失败。

7、自己如果需要扩展Activity的行为,则需要自己实现一个新的MyUnityPlayerActivity,继承自UnityPlayerActivity。修改后,AndroidManifest.xml中相关内容也要进行修改。如果仅仅是想封装一些原生系统功能的话,那么直接写一个类就可以了。需要用到Activity的时候,使用UnityPlayer.currentActivity调用相关函数即可。

      另外再注意一下,在C#代码中创建AndroidJavaClass的时候传入的参数应该包含完整的包名,比如 com.xxxx.MyPlugin,而不仅仅是一个类名。


猜你喜欢

转载自blog.csdn.net/langresser/article/details/57080521