4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VCIで人型の関節を動かす

Last updated at Posted at 2019-03-20

#概要
VCIで人型オブジェクトの関節を操作できるようにします。
記事を書いてる途中に改めて思いましたが、結構面倒です。
D2CY_nmU4AAqiZz.jpg
© Unity Technologies Japan/UCL
まぁ、でも頑張ると一人でも画面映えしますよ。
結構ゴリ押しなので、バージョンアップでダメになるかもしれません。

#前書き
2019/03/20現在、VCIはwikiに「※SubItemの下の階層にSubItemを配置する事はできません。」とあるとおり、Unityで言う所の子オブジェクトに対する参照ができません。これは、関節の操作をするにあたっては難しい制約です。ので、Fixed Jointを使って無理やり近い振る舞いをさせます。

Unityドキュメントより引用

Fixed Joints は、オブジェクトの動きを別のオブジェクトに依存するよう制限します。これは、親子関係 に若干似ていますが、トランスフォーム 階層ではなく、物理特性を通して実現されます。簡単に分解したいオブジェクトがある場合や、親子関係なしで 2 つのオブジェクトの動きをつなげたい場合などが、最適な使い道です。

#仕組み
以下3つが要点です。
・関節ごとに分離してSubItem化
・関節の位置にFixed Jointで繋いだSubItemの作成
・関節操作用のSubItemの作成

##関節ごとに分離してSubItem化
00.png
人型オブジェクトを根本から辿って、動かしたい関節の部分からVCIObjectの直下に配置してSubItem化します。RigidbodyのUse Gravityは無効にしておきましょう。え?これ動くの?と、私も思いましたが、動きます。UnityEditor上で確認できます。画像の例は「首腕肘足膝」計9関節です。

##関節の位置にFixed Jointで繋いだSubItemの作成
01.png
各関節と同じ位置に別途SubItemを作成して、その親に該当するオブジェクトをFixed Jointで繋ぎます。RigidbodyのUse Gravityは無効にしておきましょう。位置はTransformの右上の歯車からCopy Componen→Paste Component Valuesで同じ位置を設定できます。画像の例は頭なので、親は人型オブジェクトの根本にしています。肘(Elb)なら腕(UpperArm)、膝(Kne)なら足(UpperLeg)にします。

##関節操作用のSubItemの作成
02.png
各関節の操作用に別途SubItemを作成します。操作用なのでColliderを追加します。Colliderの形と大きさを調整して、IsTriggerを有効にします。SubItemはGrabbableを有効にして、ここでもUse Gravityは無効にしておきましょう。

#全体の位置移動と同期
お疲れ様です。一応ここまでの設定で関節操作の準備は整いました。が、全体の位置移動と同期のためにもうひと踏ん張り必要です。
03.png
全体の位置移動のため、人型オブジェクトの根本(Fixed Joint視点で見ても根本)にColliderを追加して、形と大きさを調整、IsTriggerを有効にします。SubItemのGrabbableを有効にして、ここでもUse Gravityは無効です。あとは同期のため、全てのSubItemのGroupIDを1に設定します。
※ここでのColliderの大きさは肩用のColliderと干渉しやすいので、小さめがオススメです。

#スクリプト
仕上げにVCIObjectへスクリプトを貼り付ければ完成です。各SubItemの名前は適宜読み替えて変更してください。

local Obj = {
    "J_Bip_C_Head",
    "J_Bip_L_UpperArm",
    "J_Bip_R_UpperArm",
    "J_Bip_L_LowerArm",
    "J_Bip_R_LowerArm",
    "J_Bip_L_UpperLeg",
    "J_Bip_R_UpperLeg",
    "J_Bip_L_LowerLeg",
    "J_Bip_R_LowerLeg"
}

local Pos = {
    "Pos_Head",
    "Pos_ArmL",
    "Pos_ArmR",
    "Pos_ElbL",
    "Pos_ElbR",
    "Pos_LegL",
    "Pos_LegR",
    "Pos_KneL",
    "Pos_KneR"
}

local Rot = {
    "Rot_Head",
    "Rot_ArmL",
    "Rot_ArmR",
    "Rot_ElbL",
    "Rot_ElbR",
    "Rot_LegL",
    "Rot_LegR",
    "Rot_KneL",
    "Rot_KneR"
}

local Root = "Sample"

local RootGrab = false

function updateAll()
    for i = 1, #Pos do
        local pos = vci.assets.GetSubItem(Pos[i]).GetPosition()
        vci.assets.GetSubItem(Obj[i]).SetPosition(pos)
        vci.assets.GetSubItem(Rot[i]).SetPosition(pos)
    end
    for i = 1, #Rot do
        local rot = vci.assets.GetSubItem(Rot[i]).GetRotation()
        vci.assets.GetSubItem(Obj[i]).SetRotation(rot)
    end
    if RootGrab then
        for i = 1, #Pos do
            local rot = vci.assets.GetSubItem(Pos[i]).GetRotation()
            vci.assets.GetSubItem(Obj[i]).SetRotation(rot)
            vci.assets.GetSubItem(Rot[i]).SetRotation(rot)
        end
    end
end

function onGrab(target)
    if target == Root then
        RootGrab = true
    end
end

function onUngrab(target)
    for i = 1, #Obj do
        Stop(Obj[i])
        Stop(Pos[i])
        Stop(Rot[i])
    end
    Stop(Root)
    RootGrab = false
end

function Stop(target)
    local SubItem = vci.assets.GetSubItem(target)
    SubItem.SetVelocity(Vector3.__new(0, 0, 0))
    SubItem.SetAngularVelocity(Vector3.__new(0, 0, 0))
end

知能が感じられない脳筋スクリプトですが、一応動きます。(ご指摘お待ちしています!

#参考
VCI作成
https://virtualcast.jp/wiki/doku.php?id=%E3%83%A2%E3%83%87%E3%83%AB%E4%BD%9C%E6%88%90:vci%E4%BD%9C%E6%88%90:vci%E4%BD%9C%E6%88%90
使用可能なUnityComponent
https://virtualcast.jp/wiki/doku.php?id=%E3%83%A2%E3%83%87%E3%83%AB%E4%BD%9C%E6%88%90:vci%E4%BD%9C%E6%88%90:%E4%BD%BF%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%AAunitycomponent
Fixed Joint
https://docs.unity3d.com/jp/current/Manual/class-FixedJoint.html
GroupIDについて
https://virtualcast.jp/wiki/doku.php?id=%E3%83%A2%E3%83%87%E3%83%AB%E4%BD%9C%E6%88%90:vci%E4%BD%9C%E6%88%90:groupid%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
バーチャルキャストのVCIスクリプトの例
https://qiita.com/sakano/items/adc88174a7dfd32ae248
サンプルVCI
https://seed.online/items/8d7e3473bd5d31e872a0bffb6829aea468bdc45b9a44e159cb05600226cc3d62

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?