前言

上個月去聽了一下HTC新的分享會得知Focus推出了一個整合型的SDK,號稱可以支援各家Standalone的頭盔。看到整頁的簡報上秀出來的Logo,幾乎就是這幾年我所碰到也實際接過的所有廠商了,所以這一步算是有滿足動機,只要有時間就可以開始研究這個解決方案的實用性是否真如台上的講者所說的如此美好。

終於這一天來到了,因為某個案子需要支援Focus,開始要整合HTC wave sdk,不過因為專案整個資料量有60G左右,又包含許多分支和系統,也不可能直接從空專案開始,所以每一布都需要採用穩紮穩打的方式進行,避免改掉某個地方造成其他地方癱瘓的事情發生。但是即使是這樣,過程中Wave SDK還是讓我驚呆了,踩了幾個坑到今天才順利爬出來

開始整合

之前同事已經將此專案先升級到2017的版本,於是直接採用這個branch開始製作。

首先將Wave SDK內建的prefab拉進場景,再加入所需要的Define到 Player Settings 中,開啟 XR Settings的 Virtual Reality Supported,Virtual Reality SDKs也調整到 Mock HMD - Vive 這個選項後,這時候就迫不及待將專案執行一下,瞬間迎來了Unity死亡粉紅聖光

It’s holy shit !!

unity_crash

因為看到這個畫面,可能的原因是某些plugin互相衝突,但是這些plugin都是Wave SDK宣稱有支援的硬體,因此對Focus SDK小組宣稱的整合開始覺得懷疑,有一種不祥的感覺。

後來發現在Editor測試的時候,先把VR mode關掉就不會當掉了,確保在PC上測試的時候是安全的,build到實機上再把VR mode打開,這樣是比較可以接受的方案,因為這個奇怪的問題要找到可能曠日廢時,先把其他問題解決,最後再來解這個問題。

自作聰明

整合如火如荼在進行中,直到遇到一個奇怪的問題,讓我整個丈二金剛摸不著頭腦。事情是這樣的,一個場景在一開始的時候,某個按鈕Animation只是把物件放大而已,這在其他系統上都是正常的,但是WAVE SDK竟然連動畫系統都會失效,這是為什麼呢?正當苦惱之際,也到論壇上尋找是否有相關的issue,可惜這個問題就是無法找到真正的發生原因。直到某個script發生一個問題,那個程式片段是利用define避開執行的區段

#if !WAVEVR_SINGLEPASS_ENABLED
    IVRManager.Instance.m_useResetPosition = true;
#endif

照理說不會執行的區段卻執行了,顯然define失效了,檢查player settings才發現Wave SDK的define不見了,怎麼不見的呢?翻了整個SDK會發現這一段程式碼:

    public const string WVRSPDEF = "WAVEVR_SINGLEPASS_ENABLED";

    public static List<string> GetDefineSymbols(BuildTargetGroup group)
    {
        //https://github.com/UnityCommunity/UnityLibrary/blob/master/Assets/Scripts/Editor/AddDefineSymbols.cs
        var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(group);
        return symbols.Split(';').ToList();
    }

    public static void SetSinglePassDefine(BuildTargetGroup group, bool set, List<string> allDefines)
    {
        var hasDefine = allDefines.Contains(WVRSPDEF);

        if (set)
        {
            if (hasDefine)
                return;
            allDefines.Add(WVRSPDEF);
            PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", allDefines.ToArray()));
            Debug.Log("Add \"" + WVRSPDEF + "\" to define symbols");
        }
        else
        {
            if (hasDefine)
            {
                allDefines.Remove(WVRSPDEF);
                PlayerSettings.SetScriptingDefineSymbolsForGroup(group, string.Join(";", allDefines.ToArray()));
                Debug.Log("Remove \"" + WVRSPDEF + "\" from define symbols");
            }
        }
    }

看起來是WVR自己拿掉的?我不知道為什麼要這麼自作聰明做這樣的動作,尤其是這個define又相當重要,很多運作會因為define失效就不正常,原本我認為是我沒看清楚相關的document,後來再去仔細翻了一下官方文件,隻字未提這個設計,只能說天啊,誰來救救這群人好嗎?不要老是想要扮演上帝的角色好嗎?

頭盔位置問題

另外一個坑是每次deploy到focus的時候都會發現頭盔位置會被自動移動到原點(0,0,0),後來同事提醒有個地方可能可以解決這個問題,找到head下WaveVR_DevicePoseTracker把tracePosition設成false,才解決了自動歸零這個問題

head trace position

EventSystem的問題

Wave SDK的按鍵自然有自己的一套處理流程,這個無可厚非,但是原本系統的EventSystem需要取消,改用底下這個設定才能避免相關的問題

event system disable

我出坑了

經過幾天的奮鬥終於把一些奇奇怪怪的問題解決了,現在deploy到focus終於能夠正常的執行,但是翻著文件還是很感嘆HTC出了一台很貴的設備,但是文件始終沒有好好撰寫,至少要能夠提醒開發者避開某些不必要的坑,減少一些怨念產生,但是顯然這個地方還是HTC該注意而沒注意到的地方,讓開發者痛就會減少產品移植到focus上的機會,以現在這個雰圍我不知道HTC還有多少的優勢和時間可以這樣浪費,如果這些地方能夠精進,不要說做到跟oculus一樣的系統,但是如果文件能夠更完備,不是開個論壇其蓋開發者自行發問解決,這樣是不負責任的做法。