UnityでValveIndexコントローラーの指入力を取り、Humanoid対応モデルの指を動かす方法です
本題の前に
- SteamVRは2.0以降を使用します
- SteamVRのセットアップ、ValveIndexコントローラーの指入力を取る方法の説明は以下の記事を参照してください
UnityでValveIndexコントローラーの指入力を取る
スクリプトの作成
HoldFinger.cs
using UnityEngine;
using Valve.VR;
public class HoldFinger : MonoBehaviour
{
private Animator animator;
private HumanPoseHandler handler;
private HumanPose humanPose;
private SteamVR_Action_Skeleton actionLeftSkeleton;
private SteamVR_Action_Skeleton actionRightSkeleton;
void Start()
{
actionLeftSkeleton = SteamVR_Actions.default_SkeletonLeftHand;
actionRightSkeleton = SteamVR_Actions.default_SkeletonRightHand;
animator = GetComponent<Animator>();
handler = new HumanPoseHandler(animator.avatar, animator.transform);
// 開始時点のポーズを取得
handler.GetHumanPose(ref humanPose);
}
private void Update()
{
// 左親指
humanPose.muscles[55] = 1 - (2 * actionLeftSkeleton.thumbCurl);
humanPose.muscles[57] = 1 - (2 * actionLeftSkeleton.thumbCurl);
humanPose.muscles[58] = 1 - (2 * actionLeftSkeleton.thumbCurl);
// 左人差し指
humanPose.muscles[59] = 1 - (2 * actionLeftSkeleton.indexCurl);
humanPose.muscles[61] = 1 - (2 * actionLeftSkeleton.indexCurl);
humanPose.muscles[62] = 1 - (2 * actionLeftSkeleton.indexCurl);
// 左中指
humanPose.muscles[63] = 1 - (2 * actionLeftSkeleton.middleCurl);
humanPose.muscles[65] = 1 - (2 * actionLeftSkeleton.middleCurl);
humanPose.muscles[66] = 1 - (2 * actionLeftSkeleton.middleCurl);
// 左薬指
humanPose.muscles[67] = 1 - (2 * actionLeftSkeleton.ringCurl);
humanPose.muscles[69] = 1 - (2 * actionLeftSkeleton.ringCurl);
humanPose.muscles[70] = 1 - (2 * actionLeftSkeleton.ringCurl);
// 左小指
humanPose.muscles[71] = 1 - (2 * actionLeftSkeleton.pinkyCurl);
humanPose.muscles[73] = 1 - (2 * actionLeftSkeleton.pinkyCurl);
humanPose.muscles[74] = 1 - (2 * actionLeftSkeleton.pinkyCurl);
// 右親指
humanPose.muscles[75] = 1 - (2 * actionRightSkeleton.thumbCurl);
humanPose.muscles[77] = 1 - (2 * actionRightSkeleton.thumbCurl);
humanPose.muscles[78] = 1 - (2 * actionRightSkeleton.thumbCurl);
// 右人差し指
humanPose.muscles[79] = 1 - (2 * actionRightSkeleton.indexCurl);
humanPose.muscles[81] = 1 - (2 * actionRightSkeleton.indexCurl);
humanPose.muscles[82] = 1 - (2 * actionRightSkeleton.indexCurl);
// 右中指
humanPose.muscles[83] = 1 - (2 * actionRightSkeleton.middleCurl);
humanPose.muscles[85] = 1 - (2 * actionRightSkeleton.middleCurl);
humanPose.muscles[86] = 1 - (2 * actionRightSkeleton.middleCurl);
// 右薬指
humanPose.muscles[87] = 1 - (2 * actionRightSkeleton.ringCurl);
humanPose.muscles[89] = 1 - (2 * actionRightSkeleton.ringCurl);
humanPose.muscles[90] = 1 - (2 * actionRightSkeleton.ringCurl);
// 右小指
humanPose.muscles[91] = 1 - (2 * actionRightSkeleton.pinkyCurl);
humanPose.muscles[93] = 1 - (2 * actionRightSkeleton.pinkyCurl);
humanPose.muscles[94] = 1 - (2 * actionRightSkeleton.pinkyCurl);
// ポーズを設定
handler.SetHumanPose(ref humanPose);
}
}
使い方
HumanoidキャラクターのAnimatorと同じ階層に、先ほど作成したスクリプト「HoldFinger.cs」をAddComponentします
ゲームを再生してValveIndexコントローラーを握ると、コントローラーを握った指の形に合わせてHumanoidキャラクターの指が動きます
微調整
Vroidなど、モデルによっては親指の付け根が伸びたり、小指~人先し指の第1関節が曲がりすぎることがあります
HumanoidリグのConfigureで直す方法もありますが、ここではスクリプトから調整します
// 左親指
//humanPose.muscles[55] = 1 - (2 * actionLeftSkeleton.thumbCurl); // 親指の第3関節を曲げない
humanPose.muscles[57] = 1 - (2 * actionLeftSkeleton.thumbCurl);
humanPose.muscles[58] = (1 - (2 * actionLeftSkeleton.thumbCurl))/2; // 指の第1関節の曲がる量を半分にする
// 左人差し指
humanPose.muscles[59] = 1 - (2 * actionLeftSkeleton.indexCurl);
humanPose.muscles[61] = 1 - (2 * actionLeftSkeleton.indexCurl);
humanPose.muscles[62] = (1 - (2 * actionLeftSkeleton.indexCurl)) / 2;
// 左中指
humanPose.muscles[63] = 1 - (2 * actionLeftSkeleton.middleCurl);
humanPose.muscles[65] = 1 - (2 * actionLeftSkeleton.middleCurl);
humanPose.muscles[66] = (1 - (2 * actionLeftSkeleton.middleCurl)) / 2;
// 左薬指
humanPose.muscles[67] = 1 - (2 * actionLeftSkeleton.ringCurl);
humanPose.muscles[69] = 1 - (2 * actionLeftSkeleton.ringCurl);
humanPose.muscles[70] = (1 - (2 * actionLeftSkeleton.ringCurl)) / 2;
// 左小指
humanPose.muscles[71] = 1 - (2 * actionLeftSkeleton.pinkyCurl);
humanPose.muscles[73] = 1 - (2 * actionLeftSkeleton.pinkyCurl);
humanPose.muscles[74] = (1 - (2 * actionLeftSkeleton.pinkyCurl)) / 2;
// 右親指
//humanPose.muscles[75] = 1 - (2 * actionRightSkeleton.thumbCurl);
humanPose.muscles[77] = 1 - (2 * actionRightSkeleton.thumbCurl);
humanPose.muscles[78] = 1 - (2 * actionRightSkeleton.thumbCurl);
// 右人差し指
humanPose.muscles[79] = 1 - (2 * actionRightSkeleton.indexCurl);
humanPose.muscles[81] = 1 - (2 * actionRightSkeleton.indexCurl);
humanPose.muscles[82] = (1 - (2 * actionRightSkeleton.indexCurl)) / 2;
// 右中指
humanPose.muscles[83] = 1 - (2 * actionRightSkeleton.middleCurl);
humanPose.muscles[85] = 1 - (2 * actionRightSkeleton.middleCurl);
humanPose.muscles[86] = (1 - (2 * actionRightSkeleton.middleCurl)) / 2;
// 右薬指
humanPose.muscles[87] = 1 - (2 * actionRightSkeleton.ringCurl);
humanPose.muscles[89] = 1 - (2 * actionRightSkeleton.ringCurl);
humanPose.muscles[90] = (1 - (2 * actionRightSkeleton.ringCurl)) / 2;
// 右小指
humanPose.muscles[91] = 1 - (2 * actionRightSkeleton.pinkyCurl);
humanPose.muscles[93] = 1 - (2 * actionRightSkeleton.pinkyCurl);
humanPose.muscles[94] = (1 - (2 * actionRightSkeleton.pinkyCurl)) / 2;
参考
Unityでスクリプトから、Animatorコンポーネントの「Chest-Twist」などの値を取得する方法
https://teratail.com/questions/168728
【Unity】スクリプトからキャラクターのボーンを制御する準備 (備忘録)
https://qiita.com/Nekomasu/items/8884b8584bfc191582d4