用Unity3D實現簡易的AR Demo
AR(Augmented Reality),即增強現實技術,是一種實時地計算攝影機影像的位置及角度並加上處理相應圖像的技術,這種技術的目標是在屏幕上把虛擬世界套在現實世界並進行互動,實現真實世界信息和虛擬世界信息“無縫”的集成。這種技術最早於1990年提出。隨着現代電子產品運算性能的提升,增強現實的用途也越來越廣,既可以用到醫療、軍事模擬訓練等嚴肅領域,也可以用來製作如miku AR等新穎有趣的應用軟件。
(宅在家也可以打開次元之門了( *︾▽︾)……..)
miku AR效果展示
本文將利用Unity3D遊戲開發引擎及高通AR插件製作一個簡易的技術Demo,併發布到Android系統的手機上進行運行測試。基於高通SDK的良好的封裝和Unity3D引擎強大的功能支持,使得開發該Demo流程十分簡單,大大降低了AR開發的入門門檻。
**************************************************************************************************************************************************************
準備工作:
首先進行一些開發前的準備,我們需要準備好三個文件:
- Qualcomm Vuforia 的SDK對應的Unity3D插件包
這個就是高通AR的SDK了,首先登陸QualcommVuforia的官方網站(https://developer.vuforia.com/)並註冊一個賬號,按要求填入信息即可。
註冊完畢後登陸,點擊Downloads下SDK標籤裏的Downloadfor Unity選項即可開始下載。此外我們看到,我們還可以直接用基於Android或IOS的SDK進行開發,但這裏我們並不需要它們。
- 待識別圖片平面的二進制數據包(同樣以Unity3D package的格式給出)
我們只需要將需要識別的圖片上傳到高通的官網,隨後網站會在雲端對圖片進行特徵值的提取和數據的生成,下載該圖片對應的數據文件即可。
登陸賬號後,選擇Develop下的Target Manger選項卡。如果是第一次使用,應該首先新建數據庫,單擊Add Datebase按鈕,填入數據庫的名稱並選擇類型爲Device,點擊Create即可創建一個新的數據庫。
進入該數據庫,並點擊Add Target按鈕,我們可以看到,我們可以添加多種類型的識別對象,簡單的如平面的圖片、文字等,複雜的還可以識別立方體、圓柱甚至一般的三維物體。在這裏我們選擇Single Image即可,上傳對應的圖片並填入其寬度,最後爲其命名,單擊Add即可添加成功。
上傳後可以看到圖片相應的信息,這裏的Rating代表圖片的可識別質量,星級越高識別質量越好。
最後,勾選圖片前的複選框,單擊Download Dataset按鈕並選擇UnityEditor平臺,即可下載上傳圖片的特徵信息數據集。
- 主角3D模型及動畫數據的Unity3Dpackage包
這個就任意了,可以選用任意自己喜歡的人物模型來代替,在這裏筆者使用的是Unity_Chan(Unity3D在日本的動漫化形象模型包),由於她對應的動作、聲音較多,效果也比較好,爲了保持下面操作的一致,建議讀者第一次操作最好也選用這個。
完成以上三步後,你應該得到以下三個package文件:
終於準備好了….下面我們就開始AR軟件製作之旅。
************************************************************************************************************************************************************
首先打開Unity3D軟件(這裏筆者選用的是Unity3D 5.1.0f3(32-bit)版本,Unity 5 64位版本與高通AR插件不兼容而報錯,無法使用,低於4.6.7版本的Unity也無法使用),新建一個工程,並刪除自帶的攝像機與光源等物體,然後導入準備的3個package文件,保存爲新的場景ar_demo.scene。
將Assets/Vuforia/Prefabs目錄下的ARCamera和ImageTarget預製體拖入場景之中。
ARCamera,即增強現實的虛擬攝像頭,對應於移動設備的硬件鏡頭位置,通過畫面中已經提取過特徵值的圖片的位置識別從而判斷出鏡頭與圖片之間的相對運動,進而調整ARCamera的位置,實現彷彿圖片之上的虛擬人物也在鏡頭之中的假象,構造出一種虛擬的真實感。
現在我們來看一下這個預製體的各項組件:
Vuforia Behavior 是用來調整VR行爲和相機配置的各項屬性的組件。
注意在App License Key一欄中要填入你在高通AR官網上的License Mangaer選項中獲取到的密鑰,其他選項如是否翻轉鏡頭、同時最大追蹤的物體數量、世界中心模式等可根據需要自己控制。
Default Initialization Error腳本是用來處理初始化錯誤的內部腳本,不用理會。
Database Load Behavior腳本用來控制讀取剛纔獲取到的圖片特徵數據文件,在導入相應的package後,可以看到對應的load 和 active選項,注意兩者都要勾選,這樣系統纔可以讀取到圖片特徵信息並進行識別。
Smart Terrian Track 腳本可以實現在比較複雜的平面上的圖像識別,可以根據需要進行勾選。
Web Cam Behaviour 腳本用來方便開發,通過它可以調用筆記本電腦上的攝像頭來實時進行項目效果的檢驗,但是筆者發現當這個腳本運行時會導致Unity3D開啓攝像頭時崩潰,考慮到這只是一個工具腳本,將其註銷掉即可,這並不會影響最終在實體機上面的運行效果。
Keep Alive Behaviour 腳本是一個DontDestroy腳本,它可以實現ARCamera在多個場景之間的保持和生存,根據需要進行勾選。
Video Texture Render腳本是用來渲染圖像的內部腳本。
ImageTarget,即代表待識別圖片目標,它對應於你所要控制識別的那張圖片的位置。
其組件有:
前兩個都是基礎組件,不加說明。
Image Target Behaviour腳本用來加載圖片數據,類型處可以選擇predefined,即表示使用從官網上雲處理而獲取到的圖片數據,在Date Set中選擇圖片對應的數據庫名稱,在ImageTarget中選擇待識別圖片目標的名稱,並可以進行相關寬高的設置,其它選項如智能地形追蹤、擴展追蹤等可以根據需要勾選。
Turn Off Behaviour 腳本是內部腳本,不用理會。
Default Trackable Event Handler 腳本是一個支持用戶擴展的腳本,當相機追蹤狀態發生改變時(如獲取目標、丟失目標等)就會執行該腳本,我們可以模仿並加入自己的控制代碼。
設置好以上兩個預製體的屬性後,我們就可以把自己的模型拖到場景中,並放置在ImageTarget之上,根據需要進行動作、聲音等效果的設置,但這並不是我們這裏的重點,不再贅述。
直接給出控制人物的相關代碼如下:
using UnityEngine;
using System.Collections;
public class ChanCtrl : MonoBehaviour {
private Animator _animator;
private AnimatorStateInfo _currentStateInfo;
private AnimatorStateInfo _preStateInfo;
public float waitTime = 3f;
public bool isRandom = true;
public AnimationClip[] _FaceClips;
public string[] _FaceMotionName;
public AudioClip[] _ChanVoice;
private void ChangeFace()
{
_animator.SetLayerWeight(1,1);
int index = Random.Range(0,_FaceMotionName.Length);
_animator.CrossFade(_FaceMotionName[index],0.5f);
if(GetComponent<AudioSource>().isPlaying)
{
GetComponent<AudioSource>().Stop();
}
GetComponent<AudioSource>().clip = _ChanVoice[index];
GetComponent<AudioSource>().Play();
}
// Use this for initialization
void Start () {
_animator = GetComponent<Animator>();
_currentStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
_preStateInfo = _currentStateInfo;
_FaceClips = Resources.LoadAll<AnimationClip>("FaceMotion");
_ChanVoice = Resources.LoadAll<AudioClip>("ChanVoice");
_FaceMotionName = new string[_FaceClips.Length];
for(int i = 0; i <_FaceClips.Length; i++)
{
_FaceMotionName[i] = _FaceClips[i].name;
}
StartCoroutine(RandomChangeMotion());
}
// Update is called once per frame
void Update () {
RaycastHit hitinfo;
if(Input.GetMouseButtonDown(0))
{
if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition),out hitinfo,Mathf.Infinity))
{
if(hitinfo.collider.tag == "face")
{
ChangeFace();
}
}
}
if(_animator.GetBool("Next"))
{
_currentStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
if(_preStateInfo.shortNameHash != _currentStateInfo.shortNameHash)
{
_animator.SetBool("Next",false);
_preStateInfo = _currentStateInfo;
}
}
}
IEnumerator RandomChangeMotion()
{
while(true)
{
if(isRandom)
{
_animator.SetBool("Next",true);
}
yield return new WaitForSeconds(waitTime);
}
}
}
完成以上工作後,基本就大功告成了。接下來就是項目發佈了,像導出普通的APK文件一樣,設置好相關的Bundle Identifier等數據,指定安卓SDK的安裝目錄,即可以導出相應的APK文件,從而可以安裝到安卓手機上進行測試。
實際效果如下,Unity娘可以隨機作出不同的動作,觸摸臉部還可以更改表情併發出聲音,是不是很萌?快來一起學習製作吧!