一、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("currentActivity"))
{
if (null != currActivity)
{
using (AndroidJavaObject intentFilter = new AndroidJavaObject("android.content.IntentFilter", new object[] { "android.intent.action.BATTERY_CHANGED" }))
{
using (AndroidJavaObject batteryIntent = currActivity.Call("registerReceiver", new object[] { null, intentFilter }))
{
int level = batteryIntent.Call("getIntExtra", new object[] { "level", -1 });
int scale = batteryIntent.Call("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,而不仅仅是一个类名。