金が欲しい
なんか一億円くらい遊ぶ金が欲しいので、今流行りのVRのゲームとか作って大儲けしたい!
って吠えてたら「まずはプロトタイピングしてブツを見せてみなさい」って言われたので作りました。この記事はその過程です。
ステージ
VRならLowPolyな環境が大半ですが、今回作りたかったものはリアルなやつなので、リアルな部屋で無料のやつ。
リアルっぽいのほしいなーってときはいつもこれを使ってます。
こういう屋内のシーンの場合、後から室内を調整することもあるので、壁や天井をこのようにまとめておくと一気にdisable
して室内を見やすくできるのでよいです。
でなんかまるごとMeshColliderつけておきます。
キャラ
Bodyguards
VRなので自キャラとかはいらないですが他のキャラは必要です。
今回は無料で一番リアルっぽいこれを選びます。
Idle MoCap
ぼんやり立っててくれてるだけでいいので、アニメーションはこれ。
実はAssetStoreでアニメーションを探すのってけっこう手間です。見本がYoutubeなので、見てるだけでも時間がかかります。
UnityでAnimationを必要とするような開発してる人はAdobe CC契約してると思うのでmixamoで探したほうが楽かも。ここのAnimationライブラリはかなり充実している上に、検索も簡単だしプレビューもさっと見られるので時間が節約できます。
死んだらぐにゃぐにゃなるやつ
Ragdollのことです。
この単語をなかなか思い出せなくて、検索履歴が「Unity 死体」「Unity 死ぬ」「Unity 死んだら」とかになってました。
でUnity標準のウィザードがこんな感じです。
んなめんどくせえことぜってぇやんねぇからな!
でまあ調べたらいい感じにやってくれるやつあるのでそれを使います。
Ragdoll helper
Ragdoll
を設定していてもAnimator
の動きが優先されます。なので死んだときにAnimator
をdisable
すれば死体になりますが、それだと裏で結局Ragdoll
分のCollider
が計算されている気がするので、通常時はRagdoll
用のCollider
はdisable
にしておいて死んだときに全部enable
にする……とかしたほうがいいんじゃないでしょうか。
操作
まあ金が欲しいと吠えているくらいですからVR機材とか持ってないわけですが、基本的にDayDreamやOculusなどVR系のPrefabはこんな構成です。
でバットが欲しいので素材を探してきます。
Small Survival Pack
あらかじめバットの形状に合わせてCollider
が調整してあっていい感じ。
このバットを先程のRight
の子オブジェクトとして配置します。こうすることでコントローラの動きに連動してバットが動くようになります。
衝突判定をつけるためにRigidBody
を付与します。このときConstrains
にすべてチェックを入れておかないと、バットがなにかに衝突したときに反動を受けてCameraのPrefab全体が回転してVR酔いが大変なことになります。ぜひ試してみてください。
VR機材は持ってないですがNintendo Switchは持ってます。SwitchのコントローラであるJoyconは3DOFです。BluetoothでペアリングすればUnityの入力装置として使えます。
【Unity】Nintendo Switch の Joy-Con のジャイロ・加速度・傾きの値を取得したり、振動させたりすることができる「JoyconLib」紹介
自分のPCはmacですがとりあえずクローンしたもの一式つっこんだら動きました。エラーは出てましたがログ出力する箇所だったのでコメントアウトしただけ。
移動法の参考記事。transform.rightを使う発想がなかった。
Unityでカメラの向きを基準に移動する方法と、追従して回転できるカメラの実装
で参考記事のスクリプトをコピペしつつ「左スティックで移動、右スティックで視点操作」できるようにします。
// Updateの中
var r_stickForce = m_joyconR.GetStick();
var l_stickForce = m_joyconL.GetStick();
// _camera = カメラPrefabのRootObject
var currentPosition = _camera.position;
var forward = _camera.forward;
forward.y = 0;
var right = _camera.right;
right.y = 0;
currentPosition += forward * l_stickForce[1] * 0.1f;
currentPosition += right * l_stickForce[0] * 0.1f;
var currentRotation = _camera.eulerAngles;
currentRotation.x += r_stickForce[1];
currentRotation.y += r_stickForce[0];
_camera.SetPositionAndRotation(currentPosition, Quaternion.Euler(currentRotation));
// _right = バットのTransform
// JoyconとUnityの角度の表し方がは違うらしいがこれで縦持ちでしっくり来る
var q = m_joyconR.GetVector().eulerAngles;
_right.rotation = Quaternion.Euler(-q.y, q.z, q.x);
次はキャラの方です。別のクラス作るのめんどくさいのでUniRxでCollider
の判定をします。
// _rightCollider = バットのCollider
_rightCollider.OnCollisionEnterAsObservable().TakeUntilDestroy(this).Subscribe(
(collision =>
{
if (!string.Equals(collision.gameObject.tag, "GameController"))
{
// 家具に当たったときの判定がめんどくさいのでキャラのパーツすべてにGameControllerのタグを付ける
return;
}
// キャラのAnimatorをdisable。本来ならcollision.gameObjectからどうにかして引っこ抜く。
_animator.enabled = false;
// そのComponentがないときにGetComponentするとnullが返ってくるのでその場合はAddComponentする。
// トリッキーなコードなので使ったらだめ。
var rigid = collision.gameObject.GetComponent<Rigidbody>() ?? collision.gameObject.AddComponent<Rigidbody>();
rigid.AddForce(m_joyconR.GetAccel().normalized * 20f, ForceMode.Impulse);
m_joyconR.SetRumble( 160, 320, 0.6f, 200 );
})
);
以上で完成しました! さっそくプレイしてみましょう。
プレイ
コンセプト
VRは疑似体験に最適。トレーニングツールなどにも導入されている。
今回は3DOFだったが、6DOFのコントローラを使って振動なども調整すればリアルな「人を殴り殺す感触」を体験できる。
殺す人数は少数。多すぎるとゲーム性が強くて実感が薄れる。
みんなゾンビとかいっぱい殺してるけど人間が殺したくてしょうがない奴もいるはず。
反応
- 10分くらいで飽きる奴
- 売ったら逮捕されそう
感想
だいたい3時間くらいでプロトタイピングできたので、改めてUnityはすごいなって思いました。
あと、実際作って操作してみたらあまりにもやばいかったのでいずれ規制されそうだなって思いました。
おしまい。