主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2019/12/21
前回までの記事で、せっかく自分の動きでアバターを動かせるようにしたけど、
大きさがあっていないので、若干の違和感が発生してしまっていました。
ということで、この記事では自己流でサイズを合わせてみました。
いつもの通り、前提環境は以下の通りです。
使用するアセットは以下の通りです。
使用した 3D モデルは、以下の 2 種類です。
アバターのサイズを人間に合わせるには、いくつかの手段があります。
私が知っている限りは、アバターのサイズを変えるのが一般的でした。
しかし、私は世界観的に VR 空間内のオブジェクトの大きさ比は維持されて欲しいので、
VR 空間そのものの大きさを変えることにしてみました。
まず初めに、 World
という空の GameObject を設置します。
次に、 SteamVRObjects
という空の GameObject を設置します。
画像のように配置する
設置したら、その中にそれぞれ対応する GameObject を入れていきます。
World
には世界に関連するもの (鏡やアバターなどなど) を、
SteamVRObjects
には SteamVR 関連のものを入れていきます。
今回の場合、最終的には下のような構成になりました。
これで前準備は完了です。
次は、大きさをどのように変えるかを C# Script で組みます。
いくつかの VR ゲームをプレイすると分かるのですが、
ユーザーに身長を選択もしくは入力させることがあります。
これをヒントに、以下の流れで拡大率を決定しました。
World.transform.localScale
を設定する個体差はあるものの、人間の形は大体にたようなものなので、
身長さえ分かれば、あとは大体計算で求めることが可能です。
今回、両腕の長さ (実際には手首まで) を 身長 * .78
として算出しました。
これは、標準的な人間の身長に対して、以下の法則がある (らしい) からです。
今回の場合、私の身長は 157cm なので、両腕の長さはだいたい 122cm で計算します。
次に、1 つめのアバターのシャペルちゃんは、両腕の長さが 90cm 程度だったので、
世界の大きさをだいたい 1.38 倍にしてあげると、ちょうど良い感じになります。
それを行っているのが、以下のスクリプトです。
using RootMotion.FinalIK;
using UnityEngine;
#pragma warning disable 649
namespace SteamVR_Sandbox.Scripts
{
public class AvatarCalibrator : MonoBehaviour
{
private const float PlayerHandDistanceByHeight = .78f;
// Start is called before the first frame update
private void Start()
{
if (World == null)
return;
var avatarHandDistance = Vector3.Distance(IK.references.leftHand.position, IK.references.rightHand.position);
var playerHandDistance = PlayerHeight * PlayerHandDistanceByHeight;
var worldScale = playerHandDistance / avatarHandDistance;
World.transform.localScale = Vector3.one * worldScale;
}
[SerializeField]
private GameObject World;
[SerializeField]
private VRIK IK;
[SerializeField]
[Tooltip("Player Real Height (m)")]
private float PlayerHeight;
}
}
これを適当な GameObject にくっつけて、 World に先ほど作成した World
を、
IK にはアバターにくっつけている VRIK
を、 PlayerHeight には身長を入れます。
私の場合の設定例
最後に、デバッグモードで起動してあげれば、身長、コントローラーの位置ともに、
ちょうど良い感じになります (若干まだ調整はいりそうですが)。
ということで、ではでは~(╹⌓╹ )