1. 程式人生 > >Unity程式設計技巧:使用巨集定義,讓程式碼更整潔,實現程式碼和渠道SDK解耦等

Unity程式設計技巧:使用巨集定義,讓程式碼更整潔,實現程式碼和渠道SDK解耦等

筆者從一年前開始做VR開發,移動端PC端的應用都有,因為當前VR市場還很混亂,並且硬體標準太多單我使用過作開發的VR裝置就有5、6種之多,更別說只是用過聽過的裝置,並且每一家的API都不一樣,這也增加了發不同的渠道包的工作量。這裡我將就我使用的只用解決方案,做一下簡單的描述,因為還在公司任職不便使用專案程式碼,所以主要就是使用方法,沒有太多的具體程式碼

哪裡設定全域性巨集,開啟BuildSetting,在下圖紅線處設定輸入巨集,不同巨集用分號隔開

這裡寫圖片描述

問題1:不同硬體廠商的SDK程式碼互相沖突

國內做VR硬體的廠商很多,而他們家的SDK程式碼大部分都一樣(具體就是都和oculus SDK的程式碼一樣,具體為什麼一樣我也就不明說了),關鍵是一些家的SDK和別人一樣就一樣吧,你加一個自己家的namespace 把程式碼區分開好不好,他們偏不,也是任性的不行。這就苦了我們做應用開發的,拿到一個B家的SDK匯入到現成(做過A家的硬體適配)的專案下,全是報錯,一個一個查,發現是程式碼衝突,但是又必須適配這家的裝置,怎麼辦,把A家的SDK刪掉?當然這是一種解決辦法,但是專案中做過A家的適配,刪掉了A家的SDK,引用到SDK的程式碼妥妥的報錯啊!!況且以後還要給A家的硬體打包程式。

怎麼辦?使用全域性巨集定義
在Unity BuildSetting 下設定兩個全域性巨集 VRA;VRB
然後把A家的SDK程式碼全部用VRA的巨集設定下:
    SDKA.cs
    #if VRA
    ......
    #endif
把B家的SDK程式碼全部用VRB的巨集設定一下:
    SDKB.cs
    #if VRB
    .......
    #endif

問題2:不同VR裝置的SDK裡某一個同樣功能的API介面不一樣

假設我們結果了SDK衝突的問題,然後就是實際應用了,比如A家SDK獲取手柄輸入的方法是InputA.GetKey();B家SDK的獲取手柄輸入的方法是InputB.GetKey();
我們不想每次打包都修改程式碼,尤其是發包比較頻繁的情況下,而且這樣也不方便做程式碼管理,哪天不小心寫錯了,等到打包出來又沒有測試,就完蛋了。同時,如果哪天不用做B家的SDK了,需要從專案下把B的SDK刪掉,那還要把引用到B家SDK的程式碼一個個修改一遍。怎麼辦?使用全域性巨集定義+程式碼功能抽象
定義一個獲取輸入的類CustomInput.cs。專案中所有獲取玩家輸入的地方都要使用這個類。該類的內容如下:

//這裡只是個簡單的結構示例,具體的程式碼根據不同VR裝置的輸入功能 要更加複雜,而且程式碼不是在編輯器裡寫的,如有語法錯誤還請見諒
//CustomInput.cs
//這個類應該使用單例模式,但不是我們討論的重點,這裡沒有寫
public class CustomInput:MonoBehaviour {
    public static System.Action OnClick;//點選手柄或者頭盔上的觸控板
    private void Update()
    {
        #if SDKA
         CheckSDKAInput();
        #elif SDKB
CheckSDKBInput(); #endif } #if SDKA private void CheckSDKAInput() { if(InputA.GetKey()) { if(OnClick!=null)On_Click(); } } #endif #if SDKB private void CheckSDKBInput() { if(InputB.GetKey()) { if(OnClick!=null)On_Click(); } } #endif } //使用輸入的地方 //Move.cs public class Move:MonoBehaviour { private void OnEnable(){ CustomInput.OnClick+=OnClick; } private void OnDisable(){ CustomInput.OnClick-=OnClick; } private void OnClick() { //跳躍移動或其他邏輯 } }

這樣我們的具體邏輯程式碼就和不同平臺的SDK完全解耦,如果某家SDK程式碼有改動,完全不會對專案其他部分的程式碼有任何影響,只需要修改CustomInput.cs這裡一處的程式碼就可以。

問題3:每一家代表玩家物件的預製體都不一樣。

做過VR開發的一定知道,因為VR模式是雙攝像機代表左右眼,而且往往還有代表左右手的3Dof手柄或者6Dof手柄。為了降低開發者的上手難度,SDK裡都會提供一個預製體,把這個預製體放到場景裡就是玩家物件。例如HTCCameraRig代表HTC vive PC端VR的玩家物件,GearCameraRig:代表GearVR 的玩家物件IVRCameraRig代表Idealens移動端VR的玩家物件。我們不能每次打不同廠家的包時都拖拽一個Prefab到場景裡吧,況且為了實現一些邏輯這些預製體上我們會掛載一些自己的指令碼剛體碰撞之類的,而且場景內其他地方的程式碼可能對這個預製體有引用關係,手動切換並不是一個合適的方法,因為是人就會有失誤。怎麼辦?還是用全域性巨集
把需要用到的所有平臺的預製體都拖拽到場景的一個代表玩家的gameobject下
這裡寫圖片描述

//VRSwitchCameraRig.cs
//把該指令碼掛到Player物件上,並且把對應的transform拖拽到固定的內容上。
//HTC vive
public class HTCCameraRig
{
    public Transform parentObj;
    public Transform head;
    public Transform leftHand;
    public Transform RightHand;
}
//Gear VR 
public class GearVRCameraRig{
    public Transfrom parentObj;
    public Transfrom head;
}
//Pico 裝置
public class PVRCameraRig{
    public Transform parentObj;
    public Transform head;
    public Transform hand; 
}
//如果有其他裝置,繼續定義其他裝置的與預製體結構
public class VRSwitchCameraRig : MonoBehaviour{
    public HTCCameraRig htcCameraRig;
    public GearVRCameraRig gearVRCameraRig;
    public  PVRCameraRig pVRCameraRig;
    public Transfrom mHead{ //專案下其他程式碼如果需要獲取頭部資訊,都從這裡拿,左右手或者其他部件同樣如此,這裡不再寫
        get{
            #if HTCVIVE
            return htcCameraRig.head;
            #elif GEARVR
            return gearVRCameraRig.head;
            #elif PICOVR
            return pVRCameraRig.head;
            #endif
        }
    }
    void Awake()
    {
        #if !HTCVIVE
        Destroy(htcCameraRig.parentObj.gameObject);
        #endif

        #if !GEARVR
        Destroy(gearVRCameraRig.parentObj.gameObject);
        #endif

        #if !PICOVR
        Destroy(pVRCameraRig);
        #endif
    }
}

相關推薦

Unity程式設計技巧使用巨集定義程式碼整潔實現程式碼渠道SDK

筆者從一年前開始做VR開發,移動端PC端的應用都有,因為當前VR市場還很混亂,並且硬體標準太多單我使用過作開發的VR裝置就有5、6種之多,更別說只是用過聽過的裝置,並且每一家的API都不一樣,這也增加了發不同的渠道包的工作量。這裡我將就我使用的只用解決方案

PowerBI技巧玩UniCode函數表格有趣

進行 unicode 一個 fff 特殊符號 聊天 戰鬥力 統一 size 正文開始:百度百科:UniCode(統一碼、萬國碼、單一碼)是計算機科學領域裏的一項業界標準,包括字符集、編碼方案等。Unicode 是為了解決傳統的字符編碼方案的局限而產生的,它為每種語言中的每

IDEA自定義代碼模板開發快樂

ideaIDEA自定義代碼模板,讓開發更快更快樂IDEA中有個Live Template選項,就是用來自定義代碼模板,來提高編碼效率。1、創建模板,並做基本的變量配置,例如:@Service() $INTER$Impl $INTER${ Logger log = Logger.getLogger($I

Excel技巧定義選項卡

excel 自定義 http clas .com 圖片 什麽 是你 分享圖片 Excel不僅可以自己創建選項卡和組,還可以重命名或更改內置選項卡和組的順序。直接說可能很難理解,下面我直接演示效果吧。 看紅色的選框,大家一看圖片就知道我要表達什麽意思了吧?我是怎麽操作的呢?請

Unity基礎篇解決漏檢測問題(射線檢測輸入檢測點選檢測)

今天我在做專案的時候,發現我滑鼠實際點選數和Unity感應到的數量不一樣。 同樣的,這也就導致了一系列問題。 鍵盤輸入漏檢測 滑鼠輸入漏檢測 射線漏檢測 我大概想了一下,應該是檢測更新速度不夠,所以會漏掉我的輸入。 出現問題了,我們就要解決問題。經過摸索,解

mp-redux小程式中的業務與檢視測試容易

專案地址:點我,歡迎star和issue mp-redux 一個用於小程式和輕量級H5應用的狀態管理工具, 使用方法是一個簡化版本的Redux。之所以是適用於輕量級應用,主要是因為沒有實現元件間的資料共享。因此不適合於複雜,龐大的前端應用。 是否你需要使用它? 如果你也和我有同樣的困惑,那麼你就該嘗試

大資料解決方案挖掘大資料價值選擇有依據

隨著科技的高速發展,資料在人們生活和決策中所佔的比重越來越大,大資料的熱浪已然覆蓋了整個時代。資料顯示,到2020年,中國大資料產業規模或達13626億元。大資料一直在積極賦能眾多產業,包括金融、醫療、農業、教育等,如何在各個行業中深度挖掘大資料價值,讓決策者的選擇有據可依,這就需要專業的大資料解決

定義gradle程式碼簡潔簽名安全

文章目錄 rootproject下自定義gradle檔案(config.gradle) gradle.properties中設定簽名信息 app下的module中的build.gradle引入依賴 AndroidStudio3.0以

pandas DataFrame高效程式設計方法 根據多列的值做判斷生成新的列值,其中多列的值是包含多個值的資料型別

一.遇到的問題描述: 我遇到問題的資料比較複雜,下面以比較簡單的資料為例說明問題,所以這些資料的含義是沒有意義的,可以忽略資料的的具體意義。資料如下所示: import numpy as np import pandas as pd data = {'city': [{'Beijing':1

高併發程式設計系列NIO、BIO、AIO的區別及NIO的應用框架選型

文章目錄 AIO、BIO、NIO的區別 NIO的3個核心概念 NIO的應用和框架 談到併發程式設計就不得不提到NIO,以及相關的Java NIO框架Netty等,並且在很多面試中也經常提到NIO和AIO、同步和非同步、阻塞

第69課-技巧定義記憶體管理

第69課 技巧:自定義記憶體管理 一、筆試題 統計物件中某個成員變數的訪問次數 程式設計實驗:成員變數的訪問統計 實現方法一:使用mutable #include<iostream> using namespace std; class Test{

巨集定義中的###的作用

核心中有很多的巨集定義,在巨集定義define中經常看到兩個字串##和#,這裡把它的用法做一下說明:  一、 ##是一個連線符號,用於把引數連在一起         例如:          &n

大廠經驗兩步搞定PHP-FPM優化伺服器平穩

導言:Web伺服器的CPU指標和MEM指標異常,不穩定?可能是PHP-FPM程序重啟機制的問題導致的,一同和百度外賣探索下如何優化吧。 作者簡介: 猛哥 百度外賣基礎架構部線上開發方向負責人 負責線上開發框架的持續優化和長期演進,主導研發的WFE/WODP/WOSP組成一套完整高效的WEB架構,支撐

玩兒轉C語言巨集定義(1)

1、為什麼要有巨集定義?         程式碼中某個特定數值需要參與運算,而且該數值作用於多個地方,當需要對該數值進行修改時,希望只改動一個地方就能實現該數值的全部更新;即便某個數值只用到一次,當修改時也會面臨搜尋閱讀大量程式碼、數值含義不明晰的問題;某些“操作塊”封裝成

程式設計技巧matlab fprintf輸出到txt檔案實現換行

<code class="language-plain"><textarea readonly=”readonly” name=”code” class=”matlab”> result_file=fopen('D:\buildingdat

C程式設計--常量(巨集定義const關鍵字定義

說明:(個人總結,有不對之處,還望指正) 常量 常量是固定值,在程式執行期間不會改變。這些固定的值,又叫做字面量。 常量可以是任何的基本資料型別,比如整數常量、浮點常量、字元常量,或字串字面值,也有列舉常量。 常量就像是常規的變數,只不過常量的值在定

vSphere使用技巧定義管理規範使用

本文轉載至:http://blog.chinaunix.net/uid-21089721-id-1565198.html 一、      前言 我們在使用vCenter Client的時候,常常會使用模板來安裝伺服器,但是這樣就會帶來一些問題。例如WINDOWS伺服器,在使

Unity預處理與巨集定義

  大家好!我是小唐,今天給大家分享一下unity預處理與巨集定義。 如果在編輯模式下執行,列印結果如圖: 也可以自己定義巨集定義。 加入自定義的巨集定義之後記住在PlayerSetting中的Scripting Define Symbols中輸入你自己定義的巨集定義

即時通訊系統中實現聊天訊息加密通訊安全【低調贈送C#開源即時通訊系統(支援廣域網)——GGTalk4.5 最新原始碼】

  在即時通訊系統(IM)中,加密重要的通訊訊息,是一個常見的需求。尤其在一些政府部門的即時通訊軟體中(如稅務系統),對即時聊天訊息進行加密是非常重要的一個功能,因為談話中可能會涉及到機密的資料。我在最新的GG 4.5中,增加了對即時聊天訊息進行加密的功能,但這一功能並不是強制的,可以通過開關來進行控制。本文

C語言程式設計---9定義資料型別

/*輸入學生的學號、姓名、性別、年齡、成績、家庭住址,輸出成績較高的學生資訊*/ #include<stdio.h> void main() { struct student