開發 Unity Android Plugin – 基本認識 – Basis of Unity Android Plugin

透過網路上的資源,初次嘗試撰寫自己所需要的 Unity Android Plugin,結果卻發現相關資源中所說明的開發過程不盡相同,經過一段時間的碰壁跟嘗試,歸納出了幾個再開始動手開發 Plugin 前,應該要先弄懂的幾件事,再依照需求選擇相對適合的開發邏輯進行撰寫。

本文將提到:

  •  Android  Plugin 的基本原理
  • 是否繼承 UnityPlayerActivity 的差別
  • jar 檔放置位置的差別
  • AndroidJavaClass  與 AndroidJavaObject 之異同

Android  Plugin 的基本原理

Unity 之所以有著強大的跨平台能力,是因為它在不同的平台都提供了一個撥放器(Player)來執行專案,所以可以在幾乎不修改專案內容的情況下,搬運整個作品到另一個平台執行。但是這形成了優點的同時也產生了缺點,並不是每次依賴 Unity API 的功能就可以達成想要的效果。為了補充 Unity Player 的不足或者分享自己專案的一部份,Plugin因應而生。

Unity Android Plugin

在沒有 Android Plugin 的 Unity 專案中,專案程式與 Android 的關係就如同 上圖(a) 所示,在 Android 上啟動 App 之後,Unity Android Player 會立即被執行,它是一個 Android Activity (在 Android App 中的一個基本執行單元),這個 Player 再進一步撥放 Unity Scene 與 Script 的內容,呈現我們的作品內容。Android – Unity Player – Unity Project 三者的關係,就類似於過去 瀏覽器 – Flash撥放器 – Flash專案 這樣的關係。

Android Plugin 在 Unity 中,就是補充 Player 的這一個部分,例如 上圖(b) 顯示的關係,Plugin 中會有一部份是 JAVA 程式是直接運作在 Android 之上,然後專案腳本的部分會控制這些 JAVA 程式完成需要的工作。為了使用方便,可能會將控制 JAVA 程式的這部分在另外包裝成 C# Class,也就成了一個可以在 Unity 專案中隨處呼叫的 Android Plugin。

小結:一個常見的 Android Plugin,會有 JAVA 部分跟 C# 部分。共同作為溝通 Android 與專案腳本的橋樑。

 

是否繼承 UnityPlayerActivity 的差別

網路上的資源可以找到各式各樣的 Android Plugin 開發範例,但其中的 JAVA 部分,有些會繼承 UnityPlayerActivity 而有些不會,兩者之間有何差別?

上一段提到了 Unity 會有一個相容於 Android 的撥放器,這便是 UnityPlayerActivity,依照你開發 Plugin 的需求不同,會影響你繼承 UnityPlayerActivity 的必要性。假如你的 Plugin 需求是有關於:

  • 修改 UnityPlayerActivity 中的一些功能或流程
  • 增加 UnityPlayerActivity 在 Activity 生命週期上的動作 (onStart、onStop等) 或與其他新增的 Activity 進行互動

這些動作與 Unity Player 的 Activity 身分有關,繼承並重新實作才有辦法進行介入。但要注意,繼承 UnityPlayerActivity 之後,你的 Plugin 會處於 上圖(c) 的情況,直接替換掉 UnityPlayer 的位置,因此需要 Manifest.xml 的撰寫,以及專案本身相對應的設定,詳細可以參考官方文件。另外因為繼承與取代的動作,這類實作方式的 Plugin 在與其他 Plugin 的互動與相容會更容易出現衝突,需要額外去處理。

如果沒有上述需求,那 Plugin其實不必繼承 UnityPlayerActivity,如 上圖(b),只要新增另外的 JAVA class 與 C# class 就可以完成 Plugin 的開發,其中一個例子就是操作藍芽。因為 Unity 本身並沒有支援藍芽功能的API,所以在 Unity 使用藍芽的方法通常是撰寫一個操控藍芽設備的 JAVA class,在包裝成 C# class 於專案中使用。

因為沒有繼承 UnityPlayerActivity,所以這樣的 Plugin 有較佳的獨立性,大部分的情況都不容易與其他 Plugin 衝突,同一個 Plugin 也很方便在不同的專案中重複利用。

小結:如果真的不確定該不該繼承 UnityPlayerActivity,那就是不必繼承。

 

jar 檔放置位置的差別

通常 Android Plugin 都會有 jar 檔,而這個檔案只要放在這個路徑之中就可以被 Unity 讀取到專案之中了。

Assets/Plugins/Android/libs/*.jar
Assets/Plugins/Android/Manifest.xml

不過如果有複數個 Plugin,為了方便管理可以將它置於一個子資料夾中的 libs 之中,例如下列的路徑:

Assets/Plugins/Android/MyPlugin/libs/*.jar
Assets/Plugins/Android/MyPlugin/Manifest.xml

不過要記得,另外放於子資料夾中後,要新增一個檔案告知 Unity 這個資料夾是一個 Plugin 的資源,必須包含到專案之中。

Assets/Plugins/Android/MyPlugin/project.properties

檔案的內容是段文字:

android.library=true

AndroidJavaClass 與 AndroidJavaObject 之異同

每個 Plugin 要確實讓 JAVA 程式運作起來,通常要透過 AndroidJavaClass 與 AndroidJavaObject 來呼叫,但這兩個超像的東西到底該用哪一個?

根據官方文件,AndroidJavaClass 繼承於 AndroidJavaObject,但是沒有增加額外的功能。主要的差別在於,建立一個 AndroidJavaObject 的同時,Unity 也會呼叫對應的 JAVA 建構子來建立實體,所以可以同時傳入值給建構子使用;而 AndroidJavaClass 只會尋找對應的 JAVA class 備用,不會建立實體。

平常使用上,會用 AndroidJavaClass 來呼叫 static 成員或函式;用 AndroidJavaObject 接收函式的回傳結果,或者呼叫實體相關的非靜態功能。

小結:AndroidJavaObject 有實體,AndroidJavaClass 沒有。

 

參考資料

http://docs.unity3d.com/Manual/PluginsForAndroid.html

http://answers.unity3d.com/questions/837762/where-can-jar-files-be-placed-under-assetspluginsa.html

http://answers.unity3d.com/questions/715007/what-is-the-difference-between-androidjavaclasscal.html

Advertisements

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s