今回はUnityで銃を構えた時にバイオハザードのようにカメラを移動させキャラクターに寄せる機能を搭載してみます。
カメラをキャラクターに寄せない場合キャラクターの手元がよく見えないのと、元々のカメラの視点によりますが、カメラがキャラクターの後ろ側にあった場合、キャラクターの少し左側の敵を攻撃しようと狙いを移すと、キャラクターと被って狙っている位置がわかりづらくなります。
そういった事がないように銃を構えた時はカメラをキャラクターのすぐ後ろ辺りに移動し、全体を見渡せるようにします。
今回の機能を作成すると、
↑のような感じで銃を構えた時にカメラをキャラに寄せる事が出来ます。
以前作成した壁対策用のカメラの移動機能と併用出来るようにスクリプトに処理を追加していきます。
カメラをキャラに寄せるようにした場合はキャラクターの上半身の移動は左には動かさず下は以前よりも制限を加えた方がいいかもしれませんね。
まったく見えない場所を攻撃出来るようになってしまいます。(^_^;)
今回の機能を搭載する前に作っておかなければいけない機能
今回の機能を搭載するにあたって
を作成しておいてください。
また
を作っておくと狙いを定める事が出来ます。
今回はキャラクターを写すカメラの間に壁が入った時のカメラの動き
の記事で作成したCheckObstaclesスクリプトに処理を追加する形になりますが、CheckObstaclesを使わない場合は別途スクリプトを作成し修正する事でも同じように出来ます。
ここまでの機能が出来ていればカメラをキャラクターに寄せる機能はさほど難しくないと思います。
カメラを動かすスクリプト
キャラクターとともに動くカメラMainCameraはキャラクターの子要素に置き、CheckObstaclesに処理を追加します。
カメラを動かす概要と設定項目
壁がカメラとキャラクターとの間に合った場合、カメラを壁の位置に動かしている機能を使っている場合は、銃を構えた時にカメラを動かすとどちらも機能する為、動作がおかしくなります。
そこで銃を構えている時にフラグを立て、壁対策のカメラの動きをしないようにします。
銃を構えるのをやめた時はフラグを下ろし、壁対策のカメラが機能するようにします。
1 2 3 4 5 6 |
// 銃を構えた時のカメラの位置 private Vector3 cameraTargetPosition = new Vector3(0.3f, 1.5f, -0.5f); // 銃を構えているかどうか private bool isWaitShotMove = false; |
銃を構えた時にカメラの移動する位置(カメラのローカル座標)をあらかじめフィールドとして用意しておきます。
isWaitShotMoveは銃を構えているかどうかで、銃を構えている時は壁対策用のカメラの動きはしないようにします。
Updateメソッドでカメラを動かす処理
Updateメソッド内に実際にカメラを動かす処理を記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
void Update () { // 壁との接触時の移動処理 if (!isWaitShotMove) { // カメラが障害物と接触してたら障害物の場所に移動 if (Physics.Linecast (player.position + Vector3.up, transform.position, out hit, LayerMask.GetMask ("Field", "Enemy", "EnemyHit"))) { transform.position = Vector3.Lerp (transform.position, hit.point, cameraMoveSpeed * Time.deltaTime); // 障害物と接触してなければ元のカメラ位置に移動 } else { // 元の位置ではない時だけ元の位置に移動 if (transform.localPosition != cameraPrePosition) { transform.localPosition = Vector3.Lerp (transform.localPosition, cameraPrePosition, cameraMoveSpeed * Time.deltaTime); } } // レイを視覚的に確認 Debug.DrawLine (player.position + Vector3.up, transform.position, Color.red, 0f, false); // 銃を構えた時のカメラの移動 } else { if(transform.localPosition != cameraTargetPosition) { transform.localPosition = Vector3.Lerp(transform.localPosition, cameraTargetPosition, cameraMoveSpeed * Time.deltaTime); } } } |
isWaitShotMoveがfalseの時は銃を構えていない状態なので通常の壁対策ようのカメラの動きを行います。
壁と接触していない時は元の位置に戻るように作成していました。
isWaitShotMoveがtrueの時は銃を構えている時の処理で今回追加した部分です。
壁対策のカメラの処理と同じでカメラの位置を徐々にターゲットの位置に動かしているだけです。
isWaitShotMoveがfalseになればifの最初の処理が実行されるので、カメラを元に戻す処理を新たに記述する必要はありません。
SetWaitShotMoveメソッド
isWaitShotMoveフラグのセットをするメソッドを追加します。
1 2 3 4 5 6 |
// 銃を構えているかどうかのセット public void SetWaitShotCamera(bool flag) { isWaitShotMove = flag; } |
bool値を受け取って設定するだけです。
カメラの移動機能を呼び出す個所を追加
これでカメラの移動スクリプトが完成したので、次はこのスクリプトの機能を呼び出す処理を追加します。
主人公キャラクター操作スクリプト等で銃を構える、銃を構えるのをやめるという処理がUpdateメソッドにあると思いますが、そこでCheckObstaclesスクリプトのSetWaitShotCameraでフラグを切り替えるだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// 銃を構えた状態 } else if (state == MyState.WaitShot) { // マウスの右ボタンを離したらノーマル状態へ遷移 if (!Input.GetButton ("Fire2")) { animator.SetBool ("WaitShot", false); shot.SetDisableLight (); shot.SetDisableRaserPointer (); SetState (MyState.Normal); checkObstacles.SetWaitShotCamera (false); // 構えた状態 } else { shot.SetAbleRaserPointer (); // 銃を撃つ if (Input.GetButtonDown ("Fire1")) { shot.JudgeShot (); } checkObstacles.SetWaitShotCamera (true); } } |
↑のように銃を構えている状態の処理で銃を構えるのをやめたらcheckObstacles.SetWaitShotCamera(false)で銃を構えるのをやめた事を知らせ、
銃を構えた状態の時はcheckObstacles.SetWaitShotCamera(true)で銃を構えている状態であることを知らせます。
キャラクター操作スクリプトではこの切り替えをするだけです。
上が実行結果です。
容量の関係でカメラが寄る場面のみになります。
今までの機能と合わせて、これでほぼバイオハザードの出来上がりです!
(;一_一)
まぁ・・・それはないとしてもモドキぐらいのゲームは作れるんではないでしょうか?(^_^;)