Hinge

最近因為裝置設計考量 需要在VR中實做一個手臂懸吊系統,模擬實體的裝置運行,才能給出比較準確的數據。

取得手臂角度資訊

首先Oculus的 handtracking只有抓到手掌,沒有手臂資訊(像是沒辦法呈現手掌和手臂是垂直的狀況),嘗試了full body tracking後不確定Oculus是不是真的有track手臂或是直接用ik模擬,因為蠻不準的…。因此決定加裝一顆IMU,經過測試(還不知道為什麼) IMU如果狂甩狂轉,會有一個方位 可能Pitch roll會偏移,換算出的eulerAngle會有一個角度偏移。不過其實我們只需要手臂和地面的仰角角度(剩下Pitch roll用手部的即可),所以就擷取IMU另外兩個角度其中一個做為手臂仰角就足夠了。但這邊又會遇到一個考量 就是需要結合手的另外兩個角度 也就是說轉a 轉b都是從手拿data 但仰角不能被影響 不能疊加在IMU仰角之上,因此就遇到第一個卡的點 最後是透過融合兩邊的quaternion得到結果(不確定是不是好方法 感覺不是 會有gimbal lock)

再來就是用unity裡面的physic 製作懸吊系統 這邊用的是hinge joint

Hinge就是像一個懸吊 可以設定支點和旋轉角度 像蹺蹺板 方法就是把支點設在下方上來一點點 逆時針旋轉時 再透過鎖定下方連接的手臂只能前後移動 把hinge往下拉 就可以達成我們要的效果 這邊有個細節是鎖定手臂能用inspector的constraint 因為那會鎖world position 這邊也讓我卡了蠻久找不到有時候轉個hinge system時就會broke 最後就用code寫死local position很快就解決

現在 只要改變proxy的角度 hinge就會自動轉並聯動手臂 只要得到collider面的角度 給Proxy就可以 這邊很多角度的控制 但千萬記得角度設定不能用角度來設定,永遠使用direction 也就是quaternion quaternion.lookrotation quaternion.axis都是好幫手 永遠unity幫你算旋轉角度 才不會有一堆有的沒有的corner case 絕對可以省去很難debug的角度

再來 為了讓proxy可以根據距離調整角度比例 我們需要得到和平面的最短距離 但如果只單純使用Vector3.distance會用物體的中心算距離 所以我們必須在物體中心展開一個plane 再用closestpointtoplane這個函式 對Unity來說new plane 的Plane是一個抽象的概念 是一個無限擴張的平面 不是在3d object的那個平面 這個函示的Plane可以用來算距離跟判斷在平面的前後 有了最短的點就可以輕鬆得到最短距離了

得到距離之後 就能根據這個距離比例來裁切角度 這邊會用到quaternion.slerp這個函式,很多人會用它來給物體旋轉緩速 但其實他的初衷就是分割角度 只要給起始角度 終點角度 跟比例 就會幫你算出該比例的角度 這邊又遇到一個問題 就是slerp會往比較近的方向算 比如說你想從 0 slerp到270順時針 他會從0 slerp到 -90 逆時針 所以這邊的slerp判斷又讓我卡了一些時間 才讓我的proxy不會往錯誤的方向旋轉


return to

Copyright © CrapyActionFigureMaster