延續(xù)上次內(nèi)容
一些基本操作跟OBS的投影設(shè)定都已經(jīng)完成
那就讓我們先回到第一個(gè)專案中
因?yàn)榈谝粋€(gè)專案中有臉部辨識相關(guān)的語法
那這邊有兩個(gè)方向可以嘗試
首先就是先嘗試從手機(jī)送訊息給PC端的Unity先測試是否能收到封包訊息
另一個(gè)則是先從獲取臉部辨識訊息開始,不過就只是研究方向不同
最後都會使用到
我們就先從臉部辨識的資訊開始
首先新增一個(gè)C#腳本,這邊就按照自己喜好跟習(xí)慣的腳本位置,放在第一個(gè)專案中
那我這邊簡單的命名為FaceMainManager
並且在場景中新增一個(gè)空物件,並且改名為Main,接著掛上需要的腳本
裡面先宣告這兩個(gè),一個(gè)是看log用的
另一個(gè)則是我們要獲取資訊用的ARFaceManager
把這些程式碼放在update中進(jìn)行刷新,並且讓它顯示在UI上
當(dāng)然我們也會需要顯示文字用的UI
這邊不管是使用舊版(Legacy)的Text還是新版上面的Text都可以,操作有一點(diǎn)點(diǎn)不同而已
目前舊版Text操作比較少,只是測試用就可以直接選這個(gè)
在編輯視窗中把UI拉到自己想要的位置,並且拉到剛剛宣告的public Text上面
之後Build到手機(jī)中運(yùn)行一下
就可以從手機(jī)上簡單看到這些數(shù)據(jù)
當(dāng)然裡面還不只這些數(shù)據(jù)
可以稍微研究一下裡面有哪些數(shù)值
主要我們獲取的數(shù)值就可以從ARFace中查找
當(dāng)然研究後可能會發(fā)現(xiàn)...
雖然是有不少數(shù)值,但是能直接用的部分並不多
像是裡面能看到的只有模型的Mesh然後左眼右眼的位置
並沒有像是眨眼或是其他嘴部偵測等等的參數(shù)(至少我這邊沒研究出來)
我想這就是安卓的AR Core的限制的一部分了
不過嘛,既然我們有Mesh,裡面還是有不少東西能看的
至於要怎麼用,就是大家各自發(fā)揮想像力了
首先我們可以先去找到AR Core的所有臉部辨識結(jié)果中的Mesh點(diǎn)位編號
這篇回覆中有看到別人把編號列出來
當(dāng)然這個(gè)自己去實(shí)作也是可以的,只是有點(diǎn)麻煩,我一開始也有試過類似的方法
我實(shí)作的方案是把Shader渲染方式調(diào)整,然後對Mesh中的各個(gè)編號進(jìn)行不同的染色
以此判斷出Mesh的編號
當(dāng)然我用的方案不怎麼好,畢竟顏色對應(yīng)編號這本身還是很難精確判斷
那後來就找到有人提供的編號,這邊就直接對照比較快
那這邊使用方法我就舉個(gè)例子
如上圖,這邊是右眼周圍的點(diǎn)位,想要拿去判斷是否眨眼是可行的其中一個(gè)方案
我這邊就舉幾個(gè)簡單的例子,例如眼睛上下的距離,像是159點(diǎn)位跟145點(diǎn)位
分別是眼睛中央的上下兩個(gè)點(diǎn),就可以判斷這兩點(diǎn)的距離達(dá)到多少算是眨眼
那我們可以準(zhǔn)備一個(gè)function來進(jìn)行判斷
這邊我是把左右眼分開進(jìn)行傳進(jìn)來的兩個(gè)index就是你要判斷的編號
例如剛剛的159就是對應(yīng)145其他的就依此類推
可以自己決定多少的數(shù)值才算是眨眼(或是要判斷多少個(gè)對應(yīng)的點(diǎn))
那這邊還需要處理一個(gè)問題是臉部角度
因?yàn)槟槻總蓽y在不同角度下的準(zhǔn)確性會有強(qiáng)烈影響
所以簡單設(shè)計(jì)可以排除臉在極端角度下的眨眼判斷(因?yàn)闀袛嗖怀鰜?
可以根據(jù)先前的log來決定多少數(shù)值以上就不判斷眨眼的設(shè)計(jì)
而嘴部閉合也可以用同樣的邏輯去計(jì)算,畢竟有了點(diǎn)位就能做到不少計(jì)算了
那相關(guān)的判斷我們可以寫在這裡
![](https://truth.bahamut.com.tw/s01/202411/7891f5fc5af5c0de07b227dcbdded100.PNG)
ARFaceManager的facesChanged可以在臉部Mesh有任何變動的時(shí)候call這個(gè)callback
所以眨眼等等的判斷就能寫在這裡
接下來我們就可以把從手機(jī)處理好的計(jì)算數(shù)值給傳回PC了
首先我們先準(zhǔn)備一個(gè)容器裝要傳送的資訊,格式就自己決定
看大家自己想把什麼偵測後的數(shù)據(jù)傳回去
不過這邊就不推薦把整個(gè)臉部辨識傳回去,因?yàn)閿?shù)據(jù)量太多了,封包太大可能會有些問題
建議把想要用的資料計(jì)算好再把算好的資料傳回去就好(還可以節(jié)省PC的效能開銷)
接下來我們就先來寫傳送封包的腳本
那我預(yù)想這封包會需要比較即時(shí),所以希望封包傳送速度高延遲小的方案
比起TCP來說,使用UDP封包能更小更快一點(diǎn)點(diǎn),而且UDP的風(fēng)險(xiǎn)損失一些封包在設(shè)計(jì)上影響也不大
畢竟臉部辨識的資訊沒有完全同步差異也還好(這邊前提是要先想好設(shè)計(jì)的方式,根據(jù)不同設(shè)計(jì)可能會有差)
我們先新建一個(gè)腳本UDPClient
內(nèi)容大概這樣就好了,我們準(zhǔn)備了一個(gè)可以發(fā)送封包的function
那這邊有endPoint是IP位置,這邊就需要知道你要傳送的PC端的IP為多少了(區(qū)網(wǎng)IP)
例如這樣,最後一個(gè)參數(shù)是port,可以自己定一個(gè)數(shù)字
只要不要用到保留的數(shù)值,並且跟你想當(dāng)Server端的數(shù)字相同就好
這邊通常會假設(shè)在同個(gè)區(qū)網(wǎng)內(nèi),這樣處理起來會比較簡單
而且傳送的速度也會更即時(shí)
接下來我們就回到先前的update去添加語法(這邊也可以考慮先前的facesChanged)
首先發(fā)送封包要用的class
把資料塞進(jìn)去,之後轉(zhuǎn)成json格式發(fā)送
最後丟給剛剛寫的UDPClient就能發(fā)送了
當(dāng)然這邊資料想塞什麼就自己決定,我這邊是還處理了一些額外計(jì)算
那這樣發(fā)送封包的部分就已經(jīng)完成了
我們回到第三專案的PC端的Unity中
在這邊新增UDPServer的腳本
裡面可以把剛剛的FaceDataUdp同樣內(nèi)容複製過來
因?yàn)榻馕龇獍膉son會用到(這邊放哪邊可以自己決定)
接下來我們可以在裡面添加Server端的相關(guān)內(nèi)容
主要就是讓程式碼在啟動後會去接收封包(針對port或是不針對也可)
當(dāng)然也需要準(zhǔn)備停止的時(shí)候的function
![](https://truth.bahamut.com.tw/s01/202411/343cd263fcd614f77c64258a3397e746.PNG)
接下來就是我們解析封包的地方
然後我這邊是直接把資料丟給另一個(gè)腳本進(jìn)行處理MainManager
那這邊我們還需檢查一下防火牆是否已經(jīng)對port開啟
根據(jù)先前的研究,Unity應(yīng)該會預(yù)設(shè)被防火牆阻擋,這塊要到防火牆中處理一下(或是測試期間暫時(shí)先關(guān)閉防火牆方便測試)
第一專案也能打包Build到手機(jī)上執(zhí)行測試了
第三專案則是直接在Unity中執(zhí)行進(jìn)行接收封包
那結(jié)果就如影片這樣,暫時(shí)只做了一些設(shè)置跟調(diào)整
動態(tài)上還有不少可發(fā)展空間
目前就是根據(jù)手機(jī)傳過來的封包進(jìn)行VRM的模型動態(tài)
這次的筆記就先到這邊~
下次的話在考慮弄點(diǎn)什麼新東西加入(或是什麼有趣的東西)
或是有什麼細(xì)節(jié)想問也可以
不過多半就只是一些數(shù)值計(jì)算的過程而已(類似計(jì)算>微調(diào)循環(huán)出來後的結(jié)果)
最後補(bǔ)充一個(gè)算是擔(dān)憂的東西
隨著研究一段時(shí)間
也是看到現(xiàn)在的確有很多現(xiàn)成的Vtuber相關(guān)的APP或是軟體能用
不過老實(shí)說覺得有不少疑慮,當(dāng)然並不是說那些東西肯定有問題
只是對Vtuber來說,隱私安全性相對是更重要的吧
不少APP跟軟體都沒有明確的指出資料如何蒐集使用,並且如何處理的,這塊還是有點(diǎn)令人擔(dān)憂的
也就簡單提一下疑慮而已,希望大家使用的時(shí)候也稍微注意一下了