TOP BoneCheckerモジュール

BoneCheckerモジュール


更新履歴

Ver1.1

モジュールのソース

BoneChecker.lua(Ver1.1)

これで何ができるか

指の曲げ伸ばし判定ができるオリジナルモジュールBoneCheckerを導入して、
装着VCIを使用せず、指のみを使って以下のようなことができます。



※指のボーンが設定されていないVRMモデルや、バーチャルキャストの指の仕様変更によっては機能しなくなる可能性があります。


Unityへの導入

UnityPackageのインストール

下記のリンクよりUnityPackageをダウンロードして順番にインストールしてください。
インストール方法は、Unityへファイルを直接ドラッグ&ドロップします。


チュートリアル:指先から弾丸(Sphere)を出してみる

1.テンプレートシーンを開く

シーンAssets/RamenVCI/BoneChecker/Templateを開くと、中に指の曲げ伸ばしのテンプレートVCIがありますので、これをベースに作成していきます。

最初にキューブがありますが、これはバーチャルキャスト内でVCIの再読み込みをするための物なので、不要であれば削除しても構いません。


2.VCIに弾丸(Sphere)を追加する
Hierarchy内の「BoneCheckerTemplate」を右クリックして、3D Object → Sphereを選択してVCI内にSphereを作成します。
作成した弾丸(Sphere)を選択して、Inspectorウィンドウ内のTransformの値を下記に設定してください。
PositionX:0Y:0.2Z:0
ScaleX:0.1Y:0.1Z:0.1
弾丸(Sphere)のInspectorウィンドウからAdd Component → VCI Sub Itemを選択して追加します。

3.VCI出力

BoneCheckerTemplate」を選択して、
VCI → UniVCI-0.XX → Export VCIを選択して保存します。

The Seed OnlineへのアップロードについてはWikiを参照してください。


BoneCheckerの環境準備

1. main.luaの作成

バーチャルキャスト上でVCIを呼び出すと、_main.luaが生成されるのでmain.luaへ名前を変更して編集していきます。
※_BoneChecker.luaは編集しないため、名前変更の必要はありません。

2. 動作確認

main.luaを上書き保存、またはVCIの再読込等で更新後、指の曲げ伸ばしをするとVCIのコンソール画面に状態が表示されます。


弾丸を打ち出すスクリプトを作成

左手を握った時に右手の人差指から弾丸を打ち出すスクリプトを作ってみましょう。
※ここからBoneChecker専用の関数を記述しますが、通常のVCIスクリプトには無い関数なので注意してください。

弾丸のサブアイテムを取得します。
ソースの冒頭部分に下記のソースを追加します。
  1. local bullet = vci.assets.GetSubItem("Sphere")
  2. main.lua
左手の人差し指を曲げた瞬間(左手を握った瞬間)をトリガーとして、右手の人差し指(RightIndexDistal)から弾丸を発射します。

ソースの下の方に左手の人差し指を曲げた時に実行されるfunction BoneEvent_FoldLeftIndex()があるのでこの中に追記していきます。
  1. function BoneEvent_FoldLeftIndex()
  2.     print("左人差し指が折れた")
  3.     --弾丸の位置を右手の人差し指に移動する
  4.     bullet.SetPosition(BoneChecker.GetBonePosition("RightIndexDistal"))
  5.     --弾丸のスピード
  6.     local force = 10
  7.     --弾丸に加速度を設定する
  8.     bullet.SetVelocity(BoneChecker.GetBoneDirection("RightIndexDistal", Vector3.__new(1,0,0) * force))
  9. end
  10. main.lua
動作確認をします。
左手を握ると、弾丸が右の人差し指から出ることを確認します。
またforceの値を高くすると弾速が速くなります。

スクリプトに指の形を判定させる

現在のスクリプトでは、左手を握ると勝手に発砲してしまうため、誤爆防止用に右手が指鉄砲の時だけ、弾丸が撃てるようにします。
今回は簡易的に人差し指が伸び、中指が折れている状態の時を指鉄砲の形とします。

弾丸を撃つ時に、右手の指の形が正しいかチェックします。
先程のBoneEvent_FoldLeftIndex()に追記します。
  1. function BoneEvent_FoldLeftIndex()
  2.     print("左人差し指が折れた")
  3.     --右手の人差し指が伸び、中指が曲げられてる時
  4.     if( (BoneChecker.GetFoldFinger("RightIndex")==false) and (BoneChecker.GetFoldFinger("RightMiddle")==true) )then
  5.         ...発射処理...
  6.     end
  7. end
  8. main.lua
動作確認をします。
右手が指鉄砲以外の形をしていた場合、弾丸がでなくなります。

スクリプトに構えを判定させる

更に誤爆防止として、擬似的に特定の構えをしたときに発砲できるようにします。
今回は右肘に左手が乗っている時に撃てるようにします。

弾丸を撃つ時に、右手の指の形が正しいかチェックします。
先程のBoneEvent_FoldLeftIndex()に追記します。
  1. function BoneEvent_FoldLeftIndex()
  2.     print("左人差し指が折れた")
  3.     --右手の人差し指が伸び、中指が曲げられてる時
  4.     if( (BoneChecker.GetFoldFinger("RightIndex")==false) and (BoneChecker.GetFoldFinger("RightMiddle")==true) )then
  5.         --左肘・右手の距離が0.2m以内の場合
  6.         if(BoneChecker.CheckBoneDistance("RightLowerArm", "LeftHand", 0.2) == true) then
  7.             ...発射処理...
  8.         end
  9.     end
  10. end
  11. main.lua
動作確認をします。
左手が右肘に近い時でないと発射されなくなります。
これを利用すれば、頭に近い位置、肩・腰・胸に手を当ててる時、両手を合わせている時等に発動を限定させることができます。

今回の完成版のサンプルはRamenVCI/BoneChecker/Sample1Bullet.sceneにあります。
また、いつも私が使用している6発リボルバーを、このBoneCheckerに流用した物がRamenVCI/BoneChecker/Sample6Bullets.sceneにありますので、参考にしてみてください。


自分のVCIに後からBoneCkeckerを組み込む方法

作成中のVCI ObjectにBoneCheckerモジュールを組み込みます。
  • ScriptsのSizeの値を+1する
  • 新規追加したソース名(Name)を「BoneChecker」に変更
  • Sourceの中身にBoneChecker/Lua/BoneChecker.luaの中身をコピペする。
BoneChecker/Lua/main.luaを参考に、自分のmain.luaにソースを追記します。
  1. local BoneChecker = require "BoneChecker"
  2. BoneChecker.SetYourName("あなたの名前")
  3. main.lua(冒頭)

  1. function update()
  2.     --BoneChecker用処理(基本的にVCI所有者のみが処理します)
  3.     if(BoneChecker.IsInitialized() == false) then
  4.         BoneChecker.CheckAvatar(vci.studio.GetAvatars())
  5.     end
  6.     BoneChecker.Update()
  7.     BoneCheckerEventSet()
  8. end
  9. main.lua(update)

  1. ------------------------------------------------------------
  2. -- 指チェッカー関数
  3. ------------------------------------------------------------
  4. --左親指が折れた瞬間のイベント
  5. function BoneEvent_FoldLeftThumb()
  6.     print("左親指が折れた")
  7. end
  8. --左人指し指が折れた瞬間のイベント
  9. function BoneEvent_FoldLeftIndex()
  10.     ...
  11. main.lua(末尾)

BoneCheckerの関数定義

BoneCheckerのモジュールを使用することで、下記の関数が使用可能になります。

関数名 説明
SetYourName(yourname) BoneCheckerの対象者をニックネームを指定します。
基本的にVCI所有者のみが処理をする前提で作られています。
一応他の人の名前を指定してもできないことはないですが、その場合はラグが発生します。
引数名 説明
yourname string バーチャルキャスト内で使用する、あなたのニックネーム
IsInitialized() BoneCheckerが使用可能な状態であるかチェック。
内部処理では、SetYourName(yourname)でアバター情報が取得できていれば使用可能とみなします。
返り値
true: BoneChecker使用可能
false:BoneChecker使用不可
Update() main.luaのupdate内で処理させたい関数です。
下記のコードをmain.luaのupdate内に記述することで機能します。
  1. function update()
  2.     --BoneChecker用処理(基本的にVCI所有者のみが処理します)
  3.     if(BoneChecker.IsInitialized() == false) then
  4.         BoneChecker.CheckAvatar(vci.studio.GetAvatars())
  5.     end
  6.     BoneChecker.Update()
  7.     BoneCheckerEventSet()
  8. end
  9. main.lua
CheckAvatar(avatars) SetYourName(yourname)で指定したニックネームのアバターが存在するか検索します。
一度アバターの検索に成功している場合は無視されます。
引数名 説明
avatars スタジオにいる全アバター情報です。
CheckAvatar(vci.studio.GetAvatars())と記述すれば問題ないです。
GetAvatar() BoneChecker対象者のアバター情報を取得します。
未登録の場合はnilが返されます。
返り値
ExportAvatar(対象者のアバター情報)
GetFoldFinger(fingerName) 対象の指が現在曲がっているかチェックする。
引数名 説明
fingerName string 指の名前を指定します。
  • LeftThumb (左親指)
  • LeftIndex (左人差指)
  • LeftMiddle (左中指)
  • LeftRing (左薬指)
  • LeftLittle (左小指)
  • RightThumb (右親指)
  • RightIndex (右人差指)
  • RightMiddle (右中指)
  • RightRing (右薬指)
  • RightLittle (右小指)
返り値
true: 曲げている状態
false:伸ばしている状態
GetBonePosition(boneName) 対象のボーンの位置を取得します。
引数名 説明
boneName string ボーン名を指定します。使用できるボーンについてはこちらを参照してください。
返り値
ボーンの位置をVector3で返します。
失敗した場合はVector3.__new(0,-100,0)で返します。
GetBoneDirection(boneName, forward) 対象ボーンの向きのベクトルを取得します。
用途としてはTransform.GetForward()に似ています。
引数名 説明
boneName string ボーン名を指定します。使用できるボーンについてはこちらを参照してください。
forward Vector3 取得したいベクトルの方向を指定します。
正面を取得(GetForward)したい場合はVector3.__new(0,0,1)とします。
ただし、これはモデルのTスタンスが基準になっているため、腕や手等はVector3.__new(1,0,0)とX軸が正面になることがあります。
返り値
向きベクトルをVector3で返します。
失敗した場合はVector3.__new(0,0,0.001)で返します。
(Vector3.zeroで返すとQuaternion.LookRotation等に使用された時に支障が出るためこの数値にしてあります)
CheckBoneDistance(boneNameA, boneNameB, distance) 対象アバターのボーン間の距離が一定以内か調べます。
例えば、両手が近い位置(0.2m以内)にあるかチェックする場合は下記のように記述します。
CheckBoneDistance("RightHand","LeftHand",0.2)
引数名 説明
boneNameA string ボーン名を指定します。使用できるボーンについてはこちらを参照してください。
boneNameB string
distance number ボーン間の距離のしきい値をメートル単位で指定します。
返り値
true :ボーン同士が一定距離内にある
false:ボーン同士が離れている(またはボーン情報の取得に失敗)
GetLeftHandVelocity()

左手の加速度を取得します。
内部では擬似的な取得方法になるので、素早く振り回している場合は正常に取得できないことがあります。

返り値
左手の加速度をVector3
アバター情報がない場合はVector3.zeroが返されます
GetRightHandVelocity()

右手の加速度を取得します。
内容はGetLeftHandVelocityの右手バージョンです。

返り値
右手の加速度をVector3
アバター情報がない場合はVector3.zeroが返されます