最近 モニュメントバレー [iOS, Android] という錯視パズルゲームを遊んでまして、
おしゃれでよくできてるなあと感嘆しておりました。
で、錯視もさることながら、プレイヤーの姫が重力に逆らい垂直に壁を歩いていったりするのです。
今回はそれをどうにか再現しようとした、試行錯誤の記録です。
NavMeshAgent ?
モニュメントバレーはタップした場所までプレイヤーが自動で移動していくので、システム的にはNavMeshAgentがしっくりきそうです。
が、NavMeshAgentを使うにはシーンにNavMeshをベイクする必要があります。
そしてこのNavMeshをベイクできる斜面の角度には限界があります。
少なくとも天井を歩くのは不可能そうです。
今回の目的には合わなさそう。
CharacterController?
ならばプレイヤー移動用のコンポーネントCharacterControllerではどうか。
が、このコンポーネントをつけると、たとえTransform自体を傾けても、CharacterControllerのコライダーが傾きません。
これでは地面の傾きをうまく表現できないでしょう。
Rigidbody ?
重力するならRigidbodyやろー、となるところですが、
ふとそもそも物理挙動いるのか?という疑問が湧きました。
Rigidbodyつけると物理エンジン対策がいろいろ必要ですし、
衝突したくなったらKinamaticのRigidbodyつければいいんじゃないだろうか。
結局...
特別なコンポーネントはつけず、Transform + スクリプトという、単純でなんとも味気ない構成になりました。
ソース
使用したスクリプトです。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GravityFreeAgent : MonoBehaviour { [SerializeField] Transform CenterOfBalance; // 重心 void Start () { } void Update () { // キーボード入力で移動、回転 if (Input.GetKey(KeyCode.LeftArrow)) { transform.Rotate( new Vector3(0, -3f, 0), Space.Self ); } else if (Input.GetKey(KeyCode.RightArrow)) { transform.Rotate( new Vector3(0, 3f, 0), Space.Self ); } else if (Input.GetKey(KeyCode.UpArrow)) { transform.position = transform.position + (transform.forward * 3 * Time.fixedDeltaTime); } else if (Input.GetKey(KeyCode.DownArrow)) { transform.position = transform.position + (transform.forward * 3 * Time.fixedDeltaTime); } RaycastHit hit; // Transformの真下の地形の法線を調べる if (Physics.Raycast( CenterOfBalance.position, -transform.up, out hit, float.PositiveInfinity)) { // 傾きの差を求める Quaternion q = Quaternion.FromToRotation( transform.up, hit.normal); // 自分を回転させる transform.rotation *= q; // 地面から一定距離離れていたら落下 if (hit.distance > 0.05f) { transform.position = transform.position + (-transform.up * Physics.gravity.magnitude * Time.fixedDeltaTime); } } } }
ソースのCenterOfBalanceは重心(足元)として設定するTransformで、下の画像のようなオブジェクト関係になります。
やってることは
- 自機と地面の傾きの差を求め、補正する
- 地面と離れたら、自機から見て真下方向に移動させる
だけです。
実装した結果
うーむ、おおむねイケてる?
ちょっとカクカクするのが気になります。
これでアクションゲームとか作ってみたいという気分がムラムラと。
まさか...続...っ!? かない