Unityで銃を構えた時バイオハザード風にカメラをキャラに寄せる

今回はUnityで銃を構えた時にバイオハザードのようにカメラを移動させキャラクターに寄せる機能を搭載してみます。

カメラをキャラクターに寄せない場合キャラクターの手元がよく見えないのと、元々のカメラの視点によりますが、カメラがキャラクターの後ろ側にあった場合、キャラクターの少し左側の敵を攻撃しようと狙いを移すと、キャラクターと被って狙っている位置がわかりづらくなります。

そういった事がないように銃を構えた時はカメラをキャラクターのすぐ後ろ辺りに移動し、全体を見渡せるようにします。

スポンサーリンク

今回の機能を搭載する前に作っておかなければいけない機能

今回の機能を搭載するにあたって

Unityでバイオハザード風ガンシューティングの機能を作ってみる
Unityでバイオハザード風のガンシューティングの機能を作成していきます。今回は銃を構えそこからレーザーポインタを表示するようにし敵に当たっている時に攻撃ボタンを押すと敵にダメージを与えます。

を作成しておいてください。

また

Unityのゲームでバイオハザード風に照準を合わせられるようにする
Unityのガンシューティングの機能に上半身だけを動かして狙いを敵に定められるようにする機能を追加します

を作っておくと狙いを定める事が出来ます。

ここまでの機能が出来ていればカメラをキャラクターに寄せる機能はさほど難しくないと思います。

カメラを動かすスクリプトMoveCamera

バイオハザードカメラ1

キャラクターとともに動くカメラMainCameraはキャラクターの子要素に置き、MainCameraにスクリプトMoveCameraを追加します。
MoveCameraスクリプトは以下のようになります。

lockMoveは

Unityでカメラが壁に遮られキャラクターが見えなくなったらカメラを移動させる
Unityのゲームでキャラクターとカメラの間に壁が入ってしまった時、壁でキャラクターが見えなくなるのでカメラ位置を調整しキャラクターを映すようにします。

の機能と併用する時に使用します。

お互いの機能が同じカメラを移動させるので、どちらかが作用していればもうひとつのカメラ移動の機能が働かないようにします。

MoveTarget関数は銃を構えた時にカメラを移動させる関数です。

自身のlockMoveを調べロックされていなければ、カメラの位置を現在地から目的地までなめらかに変更します。

カメラを移動させる時は『Unityでカメラが壁と被ったら移動させてキャラクターを映す』の記事で作成したカメラの移動機能をロックします。

Vector3.Lerpを使うと位置をなめらかに変更する事が出来ます。

Vector3.Lerpの第3引数でTime.deltaTimeに3をかけていますが、この数値を大きくするとカメラの移動が速くなります。

カメラの移動の目的地はUnityの実行時にMainCameraの位置を調整し値を調べておき、それをスクリプトのcameraBaseに入れておきます。

MoveCurrent関数は銃を構えるのをやめた時に呼び出して、元のカメラ位置に戻す機能です。
こちらもなめらかに元の位置に戻していきます。

元の位置に戻ったら『Unityでカメラが壁と被ったら移動させてキャラクターを映す』記事で作成したカメラの移動機能をアンロックします。

rayCast.LockMove関数とrayCast.UnLockMove関数はRayCastスクリプト中に記述した関数で、
ロック変数をOn・Offしているだけです。

if(transform.localPosition != cameraBase) {

と現在のカメラ位置が特定の位置と違う時にカメラを移動し、それ以外の時にRayCastのカメラ移動のロックを解除していますが、場合によってはロックが解除出来ない可能性も否定できません。
もしロックが解除されない場合は

if(Vector3.Distance(transform.localPosition, cameraBase) < 0.1){

等と一定の距離に近づいたらロックを解除した方がいいかもしれません。

カメラの位置はローカル位置で移動させていますが、これはカメラが常にキャラクターの子要素と相対的に動くのでキャラクターから見たカメラの位置を移動させる為に
このようにしています。

ここでtransform.positionでやってしまうと子要素とは関係なくゲーム世界全体の位置として指定してしまう為おかしくなります。

まとめると、

transform.positionはゲーム世界全体から見た位置
transform.localPositionは親要素から見た位置(親要素を持たない場合はtransform.positionと同じ)

となります。

カメラの移動機能を呼び出す個所を追加

これでカメラの移動スクリプトMoveCameraが完成したので、次はこのスクリプトの機能を呼び出す処理を追加します。

今まで作って頂いている方はキャラクターの処理を記述しているMoveスクリプト内に記述します。
それ以外の方はキャラクターを操作しているスクリプト内に記述してください。

キャラクターの状態に応じてカメラを移動させます。
otherEventはわたくしのゲームで使っている変数なので無視してください。(^_^;)

おおまかな処理としては

銃を構えている時はMoveCameraスクリプトのMoveTarget関数を実行しカメラをキャラクターに寄せる
銃を構えていない時はMoveCameraスクリプトのMoveCurrent関数を実行しカメラを元に位置に戻す

という処理を追加しているだけです。

カメラを移動させるかどうかをユーザーが選択出来るようにする

Management.shotCameraは自前のゲームの設定変数で、構えた時にカメラをキャラクターに寄せるかどうか?
をユーザーが選択出来るようにする為、作成しました。

常にカメラに寄せる場合はこの条件はいらないです。

この設定を使う場合はManagementスクリプトを作りその中にstaticのshotCamera変数を宣言する必要があります。
名前はご自分で決めてください。

staticで宣言した変数はゲーム全体から参照出来ますし、シーンを移動した時も変数の値を保持出来ます。

例えばManagementというスクリプトを作成した時に

という記述をしていれば、スクリプト名.staticで宣言した変数名

で値を参照出来ます。今回の場合は

Management.shotCamera

で参照する事が出来ます。

『Unityでカメラが壁と被ったら移動させてキャラクターを映す』の記事で作成したスクリプトRayCastと一緒にMoveCameraを使用する場合は、
RayCastスクリプトでカメラを移動させている個所でMoveCameraのLockMoveとUnLockMove関数を呼び出し、
RayCastスクリプトでカメラを移動している間はMoveCameraスクリプトのカメラ移動機能をロックしておきます。

これらの処理がないとロックしたままと言う事もありえるので、必ず追加する必要があります。

これでUnityで銃を構えた時バイオハザード風にカメラをキャラに寄せる機能が完成しました。

銃を構えた時のカメラ移動と障害物を避けるカメラ機能を同時に使用する時の問題点

今回の仕様では多少違和感が出るんですよね・・・。

カメラが壁とかぶってRayCastスクリプトの機能でカメラが移動している状態で銃を構えた時に
MoveCameraの機能はロックされているのでMoveCameraではカメラ移動は行いません。

銃を構えている時のカメラ位置はRayCastスクリプトで移動したカメラの位置になっているところです。

ですから、通常の銃を構えた時のカメラ位置とは違う視点になってしまうんですよね。

銃を構えた時は強制的にMoveCameraの機能を使おうとも思ったんですが、それだとMoveCameraの機能で移動したカメラが壁と被った場合はどうなるんだ!ってことになって出来なくなる。

それぞれのカメラを別にするのがいいんでしょうか?そうすると今度は切り替える処理が大変そう・・・。
(+_+)

バイオハザードカメラ2

上が実行結果です。
容量の関係でカメラが寄る場面のみになります。

今までの機能と合わせて、これでほぼバイオハザードの出来上がりです!

(;一_一)

まぁ・・・それはないとしてもモドキぐらいのゲームは作れるんではないでしょうか?(^_^;)