00 / OVERVIEW
この作品について
Reflectionは、ゾンビのいるエリアでアイテムを集め、帰還を目指すゲームです。僕が特にこだわったのは、身体に取り付けたボディーカメラを通して見る世界です。移動に伴う傾き、カメラが追い付くまでの遅れ、レンズの歪みを重ねて、記録された映像のような見え方を作っています。
人は移動するとき、いつもまっすぐ立っているわけではありません。角の先を覗く、横へ動く、周囲を見回す。そのとき、無意識に身体や視点を傾けています。こうした小さな姿勢の変化を、操作や周囲の障害物に合わせて映像へ反映させました。
普段目にする映像には、カメラを通すことで生まれるリアルさがあります。Reflectionでは、景色を細かく描くだけでなく、それを撮っている身体や機器の動きまで表現したいと考えています。U-22プログラミング・コンテスト2024でSAJ賞をいただきました。
- 01 / INPUT & SPACE
動きと、周囲の空間
Q・Eで覗く
横へ移動する・振り向く
左右のRayで障害物を検知 - 02 / BODY & CAMERA
身体とカメラの姿勢
傾きを背骨の回転に重ねる
歩行の揺れと追従の遅れを加える
静止・歩行・走行でカメラを切り替える - 03 / RECORDED IMAGE
カメラを通した映像
身体に伴って傾くフレーム
広角レンズの歪み・周辺減光
彩度とコントラストを調整
設計の流れを示す模式図です。固定の揺れを再生するだけでなく、入力・移動状態・周囲の障害物を姿勢の変化につなげています。
PLAY / REFLECTION
実機プレイ映像
YouTubeで見る ↗01 / DESIGN NOTES
身体の動きから、カメラの傾きを作る
ボディーカメラらしい動きを作るために、覗き込み、横移動、振り向き、歩行の揺れを別々に計算しています。画面へ揺れを足すだけでなく、まず身体の姿勢を変え、その姿勢をカメラへ伝えるようにしました。
CameraScriptでは、手動のlean、横移動のWalklean、障害物に応じたRayLeam、マウス入力によるCAMleanを、LateUpdateで背骨の回転に重ねています。カメラはCamPositionの位置とCamRayRotationの向きを使い、背骨の傾きを画面のロールにも反映します。操作する身体と、そこから撮影する視点をつなぐ部分です。
02 / DESIGN NOTES
自分で覗く動きと、自然に傾く動き
Q・Eキーで左右へ覗き込めるようにしています。手動の傾きは毎秒65度で変化させ、左右15度を上限にしています。横移動ではHorizontal入力に応じた傾きを別に加え、覗くキーを押していないときも身体の動きが画面へ伝わるようにしました。
周囲の障害物も姿勢に使っています。RayRote2で左右のRayを調べ、片側だけが障害物に当たると、その方向へ傾きを変化させます。両側に当たる場合や、どちらにも当たらない場合は中央へ戻します。この補正は左右25度までで、プレイヤーPrefabのRayMaxは1に設定しています。
自分の意思で角の先を覗く操作と、移動中に身体が傾く動きを分けておくことで、両方を同時に使えるようにしています。
03 / DESIGN NOTES
視線・身体・カメラの追従を分ける
振り向いた瞬間に、身体もカメラも同じ角度へ揃うと、取り付けた機器の動きが感じられません。そこで、視線の向き、身体の回転、カメラの回転を別々の処理にしています。
CameraRayScriptがマウス入力から向きを更新し、その方向へRayを飛ばして注視点を置きます。CamRayRotationScriptは注視点へ向く回転をQuaternion.Slerpで補間し、PlayerScriptは別の補間で身体を追従させます。振り向きに応じたロールも加えています。
現在のPrefabでは、カメラ側の追従係数を0.005、身体側を0.06にしています。この値は秒数ではなく、更新ごとの補間係数です。フレームレートによって追従速度が変わる部分なので、動きの調整ではその影響も考慮する必要があります。
04 / DESIGN NOTES
歩く揺れと足音を同じリズムにする
歩行の揺れと足音は、共通の位相から作っています。WalkXを進め、WalkY = WalkB × WalkX² + WalkAという二次式で揺れを求めます。位相が端まで来たら反対側へ戻し、そのタイミングで複数の足音から一つを選んで再生します。
走行中は位相の進み方を2.5倍にしています。揺れだけを強くするのではなく、映像と足音のリズムが一緒に速くなるようにしました。
静止・歩行・走行にはそれぞれCinemachineVirtualCameraを用意し、PlayerScriptから優先度を切り替えます。状態ごとのカメラ設定に、自作の傾きと揺れを組み合わせています。
05 / DESIGN NOTES
レンズと色調で、撮影された映像に近づける
描画にはHDRPを使い、Cinemachineと組み合わせています。この制作データの環境はUnity 2022.3.17f1、HDRP 14.0.9、Cinemachine 2.9.7です。カメラの動きに加えて、レンズと色調でもボディーカメラの見え方を作っています。
プレイヤーが参照するVolume Profileでは、Lens Distortionを0.5、彩度を−30、コントラストを−15、Vignetteを0.28に設定しています。レンズの歪みと周辺減光を加え、彩度を抑えた色調にすることで、録画映像に近い質感を狙っています。
このプロファイルではBloomを使っていません。カメラの傾き、レンズ、色調を組み合わせて、周囲の空間が画面越しにどう見えるかを調整しています。
06 / DESIGN NOTES
見る・集める・持ち帰る
視点の動きが遊びにもつながるように、カメラの先へRayを飛ばし、近くの箱や出口を検知して操作UIを表示します。箱からアイテムを所持品へ移し、出口では持ち帰った品の価値を合計します。
アイテムの名前・画像・価値はItemDataというScriptableObjectに持たせています。ItemDatabaseからデータを参照し、InventoryScriptで箱と所持品を表示、ExitScriptで価値を集計する流れです。
箱や所持品、出口のUIを開いている間は、移動と視点の入力を抑えてカーソルを表示します。周囲を見ている時間と、アイテムを選ぶ時間を切り替えられるようにしました。
07 / DESIGN NOTES
見失っても、すぐには追跡をやめない敵
EnemyFovScriptの検知状態をEnemyScriptへ渡し、敵がプレイヤーを見つけたら追跡の残り時間を10秒に戻します。見失った後はその時間を減らすので、角を曲がって視界から消えた瞬間に追跡が終わるわけではありません。
NavMeshAgentで目的地と残り距離を求め、距離に応じて歩行・走行・攻撃のAnimator状態を選びます。移動にはOnAnimatorMoveのdeltaPositionも使い、アニメーションの歩幅と実際の移動をつないでいます。
射撃時はFlashScriptが銃口からRayを飛ばします。敵に当たれば血のエフェクトと被弾状態、それ以外なら着弾エフェクトを出します。アニメーションから呼ぶ発射処理に、音・閃光・着弾の反応をまとめています。
08 / DESIGN NOTES
オンラインで遊ぶための処理
Photon PUNで接続、ロビー、ルーム作成、名前を指定した参加を実装しています。ルームの上限は4人で、参加者一覧を更新し、マスタークライアントだけが開始操作を行えるようにしています。
開始時はPhotonNetwork.LoadLevelとAutomaticallySyncSceneでシーンを揃え、PhotonNetwork.Instantiateでプレイヤーを生成します。操作とカメラはPhotonView.IsMineで自分のプレイヤーに限定し、敵の主な判断はマスタークライアントに任せています。
複数人で遊ぶ場合は、敵がどのプレイヤーを追うか、同じ箱を開いたときに在庫がどう変わるかも確認が必要です。接続やプレイヤーの生成だけでなく、こうした場面を含めて動作を確かめる必要があります。
09 / DESIGN NOTES
受賞と、現在の制作データ
ReflectionはU-22プログラミング・コンテスト2024の最終審査に選出され、SAJ賞をいただきました。上の実機映像で、身体に取り付けたカメラを意識した見え方をご覧いただけます。
この記事では、手元のスクリプト、Prefab、描画設定をもとに実装を紹介しています。制作途中の設定も含むため、映像を収録した時点とは細部が異なる場合があります。
REFERENCE
