我创建了一个Android Unity插件(.aar文件),它为我的Unity游戏提供了一些自定义定位数据。在我的 Unity 脚本中,我使用
var x = customClass.CallStatic<float>("getHeadX");
为了获取一些位置数据。此方法按帧调用以获取更新的数据(轮询方法),这使其效率低下。相反,我决定在更新的数据准备就绪时从我的 Java 代码(插件端)在 Unity 脚本中调用 C# 方法。为此,在我的Java插件中,我写道:
import com.unity3d.player.UnityPlayer;
...
UnityPlayer.UnitySendMessage("Manager", // gameObject name
"PluginCallback", // this is a callback in C#
"Hello from android plugin"); // msg which is not needed actually
但是,编译器抱怨包com.unity3d.player.UnityPlayer不存在。所以我从中复制了类.jar文件
C:\程序文件 (x86)\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes \类.jar
进入我的安卓插件项目的"库"文件夹。我成功构建了它,并将生成的.aar文件(mylibrary-release.aar)复制到我的Unity项目的Assets\Plugins\Android文件夹中。
当我构建 Unity 项目(使用"内部"构建系统)时,它给了我这个错误:
IOException:无法从中移动文件/目录 'Temp/StagingArea\android-libraries\mylibrary-release\classes.jar' to 'Temp/StagingArea\android-libraries\mylibrary-release\libs\classes.jar'. UnityEditor.Android.PostProcessor.Tasks.ProcessAAR.Execute ...
发生此错误是因为类.jar依赖项与类的名称冲突.jar(由我的插件中的 Unity 制作)。所以我将依赖项名称更改为unity_classes.jar解决了这个问题,但现在我在构建 Unity 应用程序时遇到一个新错误:
CommandInvokationFailure:无法将类转换为 dex 格式。C:/Program Files/Java/jdk1.8.0_102\bin\java.exe -Xmx2048M Dcom.android.sdkmanager.toolsdir="C:/Users/kamran.shamloo/AppData/Local/Android/Sdk\tools" -Dfile.encoding=UTF8 -jar "C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\sdktools.jar">
stderr[ 未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lbitter/jnibridge/JNIBridge;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lbitter/jnibridge/JNIBridge$a;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lcom/unity3d/player/NativeLoader;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lcom/unity3d/player/ReflectionHelper;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lcom/unity3d/player/ReflectionHelper$1;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lcom/unity3d/player/ReflectionHelper$a;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lcom/unity3d/player/UnityPlayer;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lcom/unity3d/player/UnityPlayer$1;未捕获的翻译错误: java.lang.IllegalArgumentException:已经添加: Lcom/unity3d/player/UnityPlayer$10; ...
类.jar(您后来将其重命名为"unity_classes.jar")会自动包含在Unity 构建的.apk中,因此您不应该再次包含它(在您的 Android 插件中),即使使用不同的名称也是如此。
换句话说,首先你的安卓插件将这个.jar文件"嵌入"在里面。然后,当 Unity 将您的插件添加到游戏项目中时,它还会添加自己的该.jar文件副本(它对所有 android 项目都这样做)。因此,Unity 基本上最终在项目中拥有相同.jar文件的 2 个副本,并通过说"无法将类转换为 dex 格式"来抱怨。
因此,尽管您必须在项目中使用此库(.jar文件),但不应将此库与项目捆绑在一起。怎么做?如果您使用的是 Android 工作室,则可以通过将.jar文件标记为具有提供范围依赖项来实现此目的。
为此,您可以:
1)转到模块的"build.gradle"并更改以下内容:
compile files('libs/jars/unity_classes.jar')
对此:
provided files('libs/jars/unity_classes.jar')
或
2) 您可以右键单击模块(在 Android 窗格中),然后选择打开模块设置。然后转到"依赖项"选项卡。找到 Unity 模块(我将其重命名为 unity_classes.jar)并将其范围更改为"提供"。