はじめに
12/5 にVCIを使ってものを運ぶ時間を競うVCIコンテストというものが開催されました。
詳細はこちら:https://twitter.com/karasumayun/status/1322821429700653057
今回は上記イベント用に作成したVCI(ホイールローダ)で使用した内容を紹介します。
全体的な構成
基本的には手元のキューブの座標情報を用いてホイールローダを操るという形式をとっています。
今回は勉強がてら以下3つの機能をそれぞれ異なる方法で操作できるようにしました。
・回転同期
・加減速
・アームの上げ下げ
以下の内容もコード内でおこなっていますがそちらは説明を割愛します
・操作用のキューブの手への自動装着
・「回転操作&加減速」と「アーム上げ下げ」のモードの切り替え
・GetTransFormの処理(初期化時にITEMという名前のtableに全部入れてます)
回転同期
こちらは至って簡単で回転用コントローラーのQuaternionをホイールローダ(MACHINE)のQuaternionに入れてあげるだけです。
function update()
ITEM.MACHINE.SetRotation(ITEM.ROTATE.GetRotation())
end
ただし、Y軸以外の回転はさせたくないためUnityの設定で回転用コントローラーの回転軸を以下のように固定しました。
加減速
こちらはGrabした位置をダミーオブジェクトに保存しておき、速度用コントローラーとダミーオブジェクトのy座標の距離に応じて加減速しています。(ダミーオブジェクトはgif画像の半透明の球の部分です)
Grabしていないときは動かないようになっています。
local isGrabSpeed = false
function update()
if isGrabSpeed then
move()
end
end
function move()
--コントローラーとダミーオブジェクトの位置から移動量の計算(上限下限あり)
local distY = (ITEM.CONTROLLER_SPEED.GetPosition().y - ITEM.DUMMY_SPEED.GetPosition().y)
local distPerSec = math.max(math.min(distY*15,5),-5)*0.02
local addVector = ITEM.MACHINE.GetForward().normalized*distPerSec
--MACHINEの位置更新
local machinePos = ITEM.MACHINE.GetPosition()
ITEM.MACHINE.SetPosition(machinePos+addVector)
end
function onGrab(target)
if target == ITEM.CONTROLLER_SPEED.GetName() then
--Grabした位置をダミーオブジェクトに保存
ITEM.DUMMY_SPEED.SetPosition(ITEM.CONTROLLER_SPEED.GetPosition())
isGrabSpeed = true
end
end
function onUngrab(target)
if target == ITEM.CONTROLLER_SPEED.GetName() then
--放した時に位置を同期させる必要はないがなんとなく実施
ITEM.DUMMY_SPEED.SetPosition(ITEM.CONTROLLER_SPEED.GetPosition())
isGrabSpeed = false
end
end
アーム上げ下げ
左右のコントローラーのY座標の位置関係によってアームの角度を変えるようにしています。
function updateAll()
local x = (ITEM.CONTROLLER_ARM_LEFT.GetPosition().y - ITEM.CONTROLLER_ARM_RIGHT.GetPosition().y)*100
x = math.max(math.min(x,10),-60)
ITEM.ARM.SetLocalRotation(Quaternion.Euler(x,0,0))
end
終わりに
今回はVCIコンテスト用のマシーンの操作方法について考えた方法をいくつか紹介しました。
別でuseしたい処理があったため今回はCubeを用いましたが、手の座標を取得して同様のこともできると思います。