VRIKらしきこと
VRIKは、VRHMDとコントローラからアバターの動きを良い感じに調整してくれるアセット(色々語弊がある)ですが、最近はVIVEトラッカーが潤沢に使える環境にあるので、自分でも似たようなのが作れんじゃね、と考えた
使うのはLookAtだけ
前提はこう
- 頭や首は簡単なHMD追従
- そこから肩・太腿の位置は得られている
基本的なロジックはこう
- コントローラがの位置と向きから肘or膝がある点を求める
- その点に向かって肩or太腿のオブジェクトをLookAt
- そして肘・膝のオブジェクトをコントローラにLookAt
- 手のオブジェクトはコントローラの向きにセット
ということで以下がコード
using UnityEngine;
public class IKSets : MonoBehaviour
{
public Transform FirstPoint;
public Vector3 FirstFix = new Vector3(0,90,0);
public Transform SecondPoint;
public Vector3 SecondFix = new Vector3(0, 90, 0);
public Transform EndPoint;
public Vector3 EndFix = new Vector3(0, 90, 0);
public Transform IkTarget;
private float _f2sDistance;
private float _s2eDinstance;
void Awake()
{
SetDistances();
}
private void SetDistances()
{
_f2sDistance = Vector3.Distance(FirstPoint.position, SecondPoint.position);
_s2eDinstance = Vector3.Distance(SecondPoint.position, EndPoint.position);
}
private void Update()
{
SetObjs();
}
private void SetObjs()
{
var middlePoint = GetMiddlePosition();
FirstPoint.LookAt(middlePoint);
FirstPoint.Rotate(FirstFix);
SecondPoint.LookAt(IkTarget);
SecondPoint.Rotate(SecondFix);
EndPoint.eulerAngles = IkTarget.eulerAngles;
EndPoint.Rotate(EndFix);
}
private Vector3 GetMiddlePosition()
{
var distance = Vector3.Distance(IkTarget.position, FirstPoint.position);
if (distance >= _f2sDistance + _s2eDinstance)
{
return IkTarget.position;
}
return -IkTarget.forward * _s2eDinstance + IkTarget.position;
}
}
単純なベクトル計算なので説明は省略。
hogeFixってついているVector3に関しては、アバターごとの座標軸の違いに対応するための値。
VRMアバターなら全部(0,90,90)にすれば大丈夫、Unityちゃんなら順に(90,90,0), (90,90,0), (0,90,0)
動かしてみた
何をどこにアタッチするかは上記を参照。
まあ、FirstPointに根元のオブジェクト、SecondPointに肘とか膝の中間ポイント、EndPointに手や足先みたいな端のオブジェクト、IKTargetに対応するコントローラかトラッカーを入れてあげればいい。SteamVRのコントローラは向きが変だから気を付けるように。
違和感はもちろんあるし、足に適応したらすごい変だったけど、まあ無料のVRIKと思えばクオリティ的にはこんなもんかってレベル
「えっ?VRIKいらなくなるの!?」そんなわけではない
違和感があるとはいえVRIKに代替できそうな気がするけど、これは四肢が完全にトラッキングできている前提なので、例えばトラッカーがなくて足のトラッキングできないときとかは使えない
それに腰に関して一切考えてないので、お辞儀やや首を捻るとかができない
VRIKがすごいのは、コンポーネントとしてアタッチするだけでほぼ全部のことをやってくれること、特に多脚キャラクターの足の動きを制御してくれるのは凄い