2012年5月9日 星期三

Unity3D Plug-in for Android -- Activity 擴展方法

Unity3D 的 Android Plug-in 還有另一種實做方法。當需要使用 Android SDK 中的 Java 物件時,利用這個方法來將 Unity3D 與 Android SDK 結合是比較好的。

簡單的步驟,

1. 先在 Eclipse IDE 中,新建一個 Android Project。

2. 在 Project 的 Property 中,點選 Java Build Path,切到 Libraries 的分頁,按鈕 "Add External JARs…",然後選擇 Unity 安裝目錄,找到 "\Editor\Data\PlaybackEngines\androidplayer\bin" 子目錄裡的檔案 classes.jar 來加入
clip_image002

3. 修改 Activity 的 Java Code

Activity 改成自 UnityPlayerActivity 繼承 ( import com.unity3d.player.UnityPlayerActivity ),在 Activity 的 OnCreate 函式裡,把預先產生的 setContentView() 函式呼叫刪除掉不要使用。

一個範例程式碼如下: ( UnityPlayerExtendActivity.java )
這個範例裡,我們不但使用了 Toast,還用到了Android SDK 中的 藍芽 API。這兩項功能,都是Unity3D無法提供的。

package com.activity.unityextend;

import com.unity3d.player.UnityPlayerActivity;

import android.os.Bundle;

import android.widget.Toast;

import android.bluetooth.BluetoothAdapter;

public class UnityPlayerExtendActivity extends UnityPlayerActivity {

private BluetoothAdapter mBluetoothAdapter = null;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//setContentView(R.layout.main);

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (mBluetoothAdapter == null) {

Toast.makeText(this,

"Bluetooth is not available.",

Toast.LENGTH_LONG).show();

finish();

return;

}

if (!mBluetoothAdapter.isEnabled()) {

Toast.makeText(this,

"Please check your BT settings.", // and re-run this program

Toast.LENGTH_LONG).show();

//finish();

//return;

}

}

}

另外呢,AndroidManifest.xml 這個檔案,需要調整一下。因為我們用到了藍芽功能,所以要開啟應用程式的藍芽權限。

image

4. 接著從 Eclipse IDE Export 出 jar 檔案。

 clip_image002[6]
clip_image004

5. 下一步,開啟 Unity3D,修改 Player Settings 設定。要注意的是, Bundle Identifier 與 Minimum API Level 要與 Eclipse 上的 Android Project 相同。

6. 然後將 Eclipse 的 Android Project 檔案複製到 Unity 專案的目錄下, 這裡有幾個需要複製的檔案。

clip_image008 


a. 在 Assets 目錄下建立 Plugins 目錄,再建立 Android 子目錄。

b. 將 Android Project 中的 AndroidManifest.xml 複製到 Plugins/Android 目錄內。

c. 在 Plugins/Android 目錄內建立 bin 子目錄,將 Android Project 輸出的 jar 放進來。

d. 最後將 Android Project 內的 res 子目錄複製到 Plugins/Android 目錄內

7. 最後,從 Unity3D Build & Run,就可以使用 Android SDK 提供的功能了。

 

 

(Update 2012.7.5) 加入了 AndroidManifest.xml 該修改的部分

2012年2月3日 星期五

Unity 3D Plug-in for Android 開發指南

這是一個摸索筆記。

以下是正文。

一. 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

clip_image004

新建立的專案還是 Win32 Platform,點選專案的 Platform 下拉箭頭,選擇 <<New>>,建立新的專案 Platform。

clip_image006

Platform 選擇 Android, Copy Setting 選擇 <Empty>,底下的 Create new solution platforms 要取消打勾。

然後按下 OK

新專案的 Project Platform 就會改成 Android,而專案中的 Property 也會自動調整為 Android 平台相關的設定。

因為要產生的是 Dynamic Library ( .so ) 檔,所以,將 Configuration Type 調整為 Dynamic Library。

clip_image008

其他的 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);

然後,就可以使用這個函式了。

2011年10月7日 星期五

Visual Studio 2010 是好物

很久沒碰 MFC了。

前一陣子 CryEngine 釋出 SDK,抓來看了以後,發現它的編輯器介面很漂亮,多翻了翻,才知道原來是用 MFC Library 做的。

這下子又引起我對 MFC 的興趣。

顯然 MFC 還不至於像傳說中的那麼慘。

最近打算重新改寫遊戲資源檔案打包上傳的工具程式,想到了 MFC,打算拿著來試試。

發現了這麼一篇 Blog

Your First MFC C++ Ribbon Application with Visual Studio 2010

哦~~~

MFC 做出來的應用程式介面不再那麼難看了耶~~

趕快隨手很快的建了一個專案,勾選幾個項目後,完整功能的 Dock Panel, Ribbon Menu ( 還有一個 Outlook的 Navigation Bar 沒勾) 都有了...

clip_image001

沒做什麼事,而應用程式看上去的專業度大大提升...

VS 2010 真是好物...

2011年7月19日 星期二

圖形除錯設備

今年 GDC 給我的一個大震撼,就是,Game Engine / Graphic Engine 裡,要加上圖形除錯功能。

回頭翻了一本 3D Game Engine Architecture 的書,才發現人家早早就有說了。

這些功能的用處很大,做了絕對有好處。

然後發現,啊,Engine 裡頭那個顯示 Bounding Box 的物件,不就是其中一個圖形除錯物件麼?

Bungie 在開發 HALO 時,連網路封包的數據與優先權都用即時圖形顯示。

image

我們真的該把圖形除錯的功能加到 Engine 裡。

我叫它做「圖形除錯設備」。 ( Graphic Debugging Facilities )

首先,我把 Game Timer 做了修改。加上加速、放慢、暫停、甚至每個 Frame 更新固定時間的功能。這些在我們做 Animation 的除錯時,應該會很有幫助。另外,我還加了一個 Real Life 的 Timer,我們總還是會需要知道真實時間的吧?

然後, Engine 裡面加了一整組的 Debug Drawing API,包括畫線、畫圓、畫顆 Wireframe 的球、畫個十字、畫個座標軸、顯示字串訊息在 3D 場景裡,還有一個很有用的,畫個 Frustum 出來。

最後一個組件呢,就是弄了一組除錯用的 Camera 跟 Frustum。遊戲場景的攝影機,是場景管理中很重要的運算基礎,但是我們怎麼知道這些運算有沒有問題? 例如,Frustum 的 Culling 運算、遠方物件的 LOD 選擇,有了除錯 Camera 的模式,我們就可以很簡單的做檢查。

image

Hmm... 看來 Frustum 的 Culling 並沒有算得很乾淨...

2011年6月5日 星期日

30 天打造 OS!

其實這是我今天帶回的一本奇書,它的副標題。

image

(圖片來源: 博客來書籍館)

日本人寫的,譯者有三位。

為什麼說它是奇書 ?

你看標題就知道了, 「自己做作業系統 ? 這什麼 ?」

台灣的資訊相關書籍,多如過江之鯽,作業系統核心的內容已經夠硬了,還要自己寫程式來做 ? 而且一開始還是拿組合語言拼出來的開機程式,這絕對是硬派中的硬派。

市場更是小之又小。

幾個月前我在書店裡看到的時候,愣了一下,覺得很神奇,怎麼會有人出版這種書 ? 有個怪咖會寫這種書不奇怪,但是翻譯了出版來賣 ? 這就很匪夷所思了。

就算上架了,大概也沒幾個人會在書店裡把它拿起來翻閱的吧?

果然, 今天閒晃的時候又看到它,整本書還是跟新的一樣。

我沒有多想,就把它買下帶回家了。

這種市場小之又小的書,一不注意,就會消失在書店裡,再也找不著。

話又說回來,書的封底是這麼寫的:

-----

可能是史上最有趣且實用的作業系統書籍!日文版已突破13刷!

這是一本兼具趣味、實用與學習性的作業系統書籍。作者以獨創手法,從電腦的構造、組合語言、C語言開始解說,讓讀者透過實作與測試學會演算法,並在自由愉悅的氛氛下,從零開始建構作業系統。

即使是初學者,也不需畏懼,因為連貓咪都能輕鬆學會自作作業系統!

-----

貓咪也能學會? 廣告不實...

2011年3月8日 星期二

GDC 2011 Day 5

最後一天,算算只有四個小時的課。

今天的開場,由 Bungie 的 Halo : Reach 開始。

首先是 Automated Level of Detail Generation。

顧名思義,就是用程式算出 LOD Mesh。裡頭的演算方法,是很不錯的想法,可以找時間來模擬嘗試看看。

而除了 LOD Mesh 之外,他們還提出了一個做法 – "Unified material model"。

簡單講,就是所有的 LOD Mesh 都使用同一種材質 Shader ,這樣一來,也可以提升很多效能。更重要的是,反正距離很遠、物件很小的時候,就算畫的很粗略,也不是那麼明顯...

在這裡,他們也展示了一個在除錯模式下的攝影機,可以用來檢查 LOD 的變化是否如預期。

Hmm… 我們似乎也該弄個 Debug Mode Camera 來了。

第二段,講述的是 Halo : Reach 裡的 Effect。

第一個來的 Effect,就是嚇死人的粒子系統。

有多恐怖?

1. 粒子的運算全部交由 GPU 計算,CPU 只決定粒子的數量。

2. 在 GPU 裡計算的粒子,照樣可以跟場景中的物件計算碰撞跟彈跳。

所以,只要一個 GPU Draw Call ,就可以畫出所有的粒子,而且還會有碰撞彈跳。

碰撞與彈跳計算的資料來源有兩個,Depth Buffer 與 Normal Buffer。計算的概念,說穿了一點都不難,但是,要能夠想到這點,還真的是不容易。

接下來的效果,都跟 Depth Buffer 有關。

Bungie 給了一個結論 – "Depth buffer is incredibly useful"

前兩天,岩田聰社長說 : "Content is KING"

今天我們的結論是 : "Depth Buffer is KING"

接下來聽了一場跟想像中的內容不太一樣的講題。

本來以為他們會介紹如何處理一個龐大遊戲場景的概念與方法,結果,他們是有介紹啦,但是卻是基於他們自己的工具系統,有一點失望,不過也還是有一點收穫就是。

下午聽了一場是關於拳擊遊戲裡,對於拳手的皮膚效果的處理方式,很新鮮,而且他們的專業研究,也不得不讓人佩服。

過去一整個看起來像 "塑膠" 的皮膚,經過研究分析改進之後,變得非常自然。

真是夠專業。

 

最後,把像素拼圖的完成圖拍了下來。 ( 雖然這已經是由工作人員完成的了... )

DSC01442

2011年3月4日 星期五

GDC 2011 Day 4

中午又跑去任天堂的展場去玩 3DS,本來是想要玩玩薩爾達的,可是人好多擠不進去,晃了一陣,只玩到 Street Fighter。

也很讚。

早上第一場,去聽了 Killzone 3 有關 Occlusion Culling 的技術,基本概念也還是用個 Buffer 來記錄深度,然後做測試運算,沒什麼新的。不過說的很詳細,比起昨天用兩三張畫面帶過的那一場,好太多了。

更重點是,他們做了一整套在 Occlusion Culling 上的 Debug 工具,可以很清楚看到 Occlusion Culling 計算前計算後的結果。

視覺化很重要,尤其是這東西跟美術有關。

接下來去聽了 Dead Rising 2 在網路功能方面的經驗分享。

這遊戲好像賣的很不錯? 整場聽眾有爆滿啊...不過我很懷疑有多少人不是技術背景的,至少最後發問的人裡頭有一兩個...( 問的問題居然是遊戲的銷售量?? )

網路功能,嗯,對我們在 MMO 上面已經有些經驗的人來說,這些分享的內容並沒有太多的不同。反倒是,他們也做了個 工具來監看 Traffic、監看資料同步的結果...就顯示在遊戲畫面上...Real-Time…

只能說,他們真的很愛做工具。不知道是因為專業還是因為人太多?

下午,有一個題目很吸引人。

"Adaptive Order Independent Transparency"

Render 半透明物件不用先排序。

基本概念還是與 A-Buffer 有關。只不過,將 A-Buffer 的第二階段 -- 排序與組成,引入一個 "Visibility Function",以當作權重的方式,計算半透明 Pixel 最後合成的結果。用這樣的方式,刪去耗費時間的排序工作。

效能增加很多。

不過這 "Visibility Function"的計算有些複雜。

接下來的課程是,Bugie 講述 Halo : Reach 遊戲裡網路相關的技術分享。

有一句話寫得好 : "Technology to help multiple players sustain the belief that they are playing a fun game together"

他舉了兩個遊戲中的例子,來看他們把網路延遲藏的有多好。

然後,又看到了 Traffic 監看的工具...也是直接顯示在遊戲畫面上...也是 Real-Time…

DSC01306

他們真的很喜歡做工具...

不過,這工具應該還是有用的,至少他們抓到了一個問題: 一個還在滾動的手榴彈用了很大量的頻寬...

最後一堂課程是超大的一顆地雷...

又沒有其他課程好去,所以就坐著混到下課...

 

今天的像素拼圖長這樣:

DSC01234

昨天那個日本人做的馬力歐已經不見了,應該是工作人員把它拆了。

那個蹲著在拼的,應該就是工作人員。手上有一大包同樣顏色的方塊,拼完了又去拿了一大包來拼。

有工作人員做修正,那這個活動也沒什麼意思了...