這是一個摸索筆記。
以下是正文。
一. Unity3D Plug-in 必須知道的概念
Unity 的 Plug-in 是以二進位存在的,所以,在不同的平台上,必須開發不同的 Plug-in,例如,在 PC Windows 平台,使用 dll 檔,在 Android 系統,使用 .so 檔。
在使用 Unity 開發專案時,因為是在 PC Windows 平台上操作,所以當使用了 Android 的 .so 檔時,會造成無法在 Unity Editor 中即時操作遊戲的問題。至於是否可以有個取代方案,例如,另外寫個相同功能的 dll 檔來在 PC Windows 平台上操作,這要再做進一步測試。
二. Unity3D Plug-in 的安裝
Unity 的官方文件,是建議將 Plug-in 複製到專案的 Assets/Plugins/Android 目錄下,如果沒這個目錄,就自行建立一個。
所以,就是將寫好編譯好的 .so 檔,複製到這個目錄下就可。
官方文件上有一個模稜兩可的說法,說 Plug-in 安裝後,Unity 會自動抓出其中的 Java Class 什麼的,不要相信它,因為完全試不出來。
三. Unity3D Plug-in 的使用
.so 檔複製到專案以後,是無法取得任何資料的。必須透過 C# Script 來載入。 官方文件中,只提供了使用 C# Script 來參考 Plug-in 的方法,找不到 Java Script 的方法,所以就先以 C# Script來做。
官方網站上有一個可以參考的範例,"AndroidNativePlugin.zip",可以下載來參考。
zip 檔解開後,將 unity package import 進 Unity Editor,可以抓到 .so 檔,原始程式碼,以及使用 Plug-in 的 C# Script。
C# Script 如下 (已經改過了)
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class CallNativeCode : MonoBehaviour {
public GUISkin mySkin;
[DllImport("ttt")]
private static extern float add(float x, float y);
void OnGUI ()
{
GUI.skin = mySkin;
float x = 3;
float y = 10;
GUI.Label (new Rect (15, 125, 450, 100), "add" + x + " and " + y + " equals " + add(x,y));
}
}
幾個重點:
1. [DllImport(“ttt”)] : 這行程式,是負責載入 Plug-in,依照官方規定,這個Plug-in 的檔名是 libttt.so,也就是,前綴必須有”lib” 三個字母,後面是 .so 副檔名。
2. private static extern float add(float x, float y); -- 這一行是宣告Plug-in中的函式。
3. 載入與宣告函式完成後,在 Script 的 OnGUI 函式中,就可以使用這個函式了。
四. Android Plug-in 的開發
接著就是,.so 這個檔怎麼做出來了。
.so 檔,可以視作是 Android 系統上的 Dynamic Load Library (dll)
1. 建立開發環境
一般書籍或網站上找到的 Android 應用開發,多是以 Java 環境來做的,這是無法編譯 .so 檔案的。
Android 的 Development Kit 有兩種,一種是 SDK (Software Development Kit), 一種是 NDK (Native Development Kit),編譯 .so 檔,需要 NDK。
傳統的建立開發環境的方法是,要安裝 cygwin (Windows 上的 Linux 模擬器)、NDK、SDK、Eclipse IDE 等等,現在有個神人把整個開發環境整合到了 Visual Studio 2010上,所以建立開發環境的方法,就以整合 VS 2010 來做了。
vs-android -- Integrated development of Android NDK C/C++ software under Visual Studio
下載vs-android,sample solution,然後下載 Android NDK (r7 or later),SDK,Java SDK (32 bits版),以及 Ant。
需要安裝的安裝,可以解壓縮複製的,就解壓縮複製。( Android SDK 的安裝,比較複雜些,請找資料看看 )
然後要設定幾個環境變數
ANDROID_HOME : Android SDK 的根目錄位置,例如 C:\Develop\android-sdks
ANDROID_NDK_ROOT : Android NDK 的根目錄位置,例如 C:\Develop\android-ndk-r7
ANT_HOME : Apache Ant 的目錄,例如 C:\Develop\apache-ant-1.8.2
2. 測試範例程式 san-angeles
設定完成,打開 VS 2010,載入 Sample Solution,USB接上測試用設備,Build Solution,然後就 OK 了。
<< 不過,還是會碰到編譯不過的情形啦。以下是幾個可能要處理的狀況。
a.
Unable to resolve target 'android-4'
因為在 SDK中的 Platform 版本裡沒有安裝 API Level 4,修改 project.properties 這個檔案中的 target=android-4,改為 SDK 有安裝的API
b.
ANTBUILD : [dx] error : Could not create the Java Virtual Machine.
ANTBUILD : [dx] error : A fatal exception has occurred. Program will exit.
[dx] Error occurred during initialization of VM
[dx] Could not reserve enough space for object heap
這問題,打開 android-sdks\platform-tools 目錄中的 dx.bat 檔案,將
set defaultXmx=-Xmx1024M
改為
set defaultXmx=-Xmx512M
>>
3. 建立要編譯 .so 檔的專案
因為 vs-android 的神人作者,還沒有寫好 Project Wizard,所以,要靠半手動的方式來建立新專案。
簡單一點的做法是,就在範例程式 solution 下新加入一個專案,選擇 Win32 Console App,然後建立 Empty Project。
Project 的名稱,以 lib 開始,符合 Unity Plug-in 的規則。例如,libunityplug1
專案建立完成,開啟專案的 Property Page,點選 Configuration Manager
新建立的專案還是 Win32 Platform,點選專案的 Platform 下拉箭頭,選擇 <<New>>,建立新的專案 Platform。
Platform 選擇 Android, Copy Setting 選擇 <Empty>,底下的 Create new solution platforms 要取消打勾。
然後按下 OK
新專案的 Project Platform 就會改成 Android,而專案中的 Property 也會自動調整為 Android 平台相關的設定。
因為要產生的是 Dynamic Library ( .so ) 檔,所以,將 Configuration Type 調整為 Dynamic Library。
其他的 API Level, Architecture,有需要也可以改看看。
然後就開始加入原始程式碼檔案吧!!
4. Plug-in 程式碼與使用
很快,隨便寫了個 .c 的程式
float multiply(float x, float y)
{
return x * y;
}
然後 Build 這個 libunityplug1 專案,沒問題的話,會得到 libunityplug1.so 的檔案,把 .so 檔案複製到 Unity 的 Assets/Plugins/Android 目錄下
修改 Unity C# Script
[DllImport("unityplug1")]
private static extern float multiply(float x, float y);
然後,就可以使用這個函式了。