Unityでカメラが壁に遮られキャラクターが見えなくなったらカメラを移動させる

Unity内のステージで広い草原であれば考えなくてもいい事なんですが、ゲームステージに建物や山のような地形があった場合、カメラとキャラクターの間に何らかの障害物が映り、キャラクターが見えなくなってしまう事があります。

こうなるとキャラクターが今どこを動いているのかわからなくなってしまいます。

カメラ12

スポンサーリンク

キャラクターが壁のせいで見えなくなる時の対処

こういう時はカメラが自動で位置を変えキャラクターを表示するか、またはキャラクターが狭い建物に入った時(OnTriggerEnterで判定)にあらかじめ設定してあった別のカメラの表示に切り替えて、キャラクターが見えなくならないようにするという方法があります。

カメラを切り替える方法はメインカメラで表示していたものを固定のカメラに切り替え、メインカメラをOffにするという機能を追加すればいいんですが、
カメラの切り替えに関しては

Unityでカメラをスクリプトから切り替えられるようにする
Unityで使用するカメラを複数設置し、スクリプトからカメラのOn・Offをしてキャラクターを見る視点の切り替え機能を作成します

を参照してください。

今回はある程度自動でカメラの位置を変える機能を追加してみます。

キャラクターとカメラの間に障害物があるかを調べるRayCastスクリプト

カメラとキャラクターの間に障害物があるかどうか判定し障害物があった時はカメラの位置を移動します。

障害物があるかどうか調べる為にPhysics.Linecastを使います。
カメラの位置は変更するので、元のカメラの位置と同じように動く空のオブジェクトを作成し名前をRayCastとして、以下のスクリプトを取りつけます。

プレイヤーキャラクターをpublic変数で指定出来るようにしplayerに入れます。

カメラ14

カメラ15

lookAtPointはpublicにし、カメラの移動する位置を指定します。

lookAtPointは空オブジェクトを作成し、キャラクターの子要素として設置しておきます。
RayCastオブジェクトは常にプレイヤーの角度とプレイヤーの位置からの相対値で移動させます。
キャラクターの向きと同じ向きにしてからキャラクターの向いている方向からカメラの位置を指定します。
player.transform.forwardは前、player.transform.upは上になります。

Physics.Linecastで始点をキャラクターの位置、終点をこのオブジェクトの位置、レイヤーマスクをFieldに設定し、衝突するかどうか判断します。
衝突していたらlookAtPointのローカル座標の位置にカメラを指定します。

カメラの位置を目的地になだらかに移動させるMoveCameraスクリプト

moveCameraはメインカメラに設定しているスクリプトMoveCameraで、SetRotationは角度、SetPositionは位置を変更します。

いきなりカメラの位置を切り替えると位置の把握が大変なので(パッとカメラ位置が変わってしまう為)、Vector3.Lerpを使って、現在のカメラの位置から指定された位置まで少しづつ移動させるようにします。

カメラ13

上のような感じで通常表示されるカメラ位置とは違う位置で表示され、壁でキャラクターが見えなくなる事はなくなりました。

飛ばすレイを視覚的に確認する方法

最後に

Debug.DrawRayを使うと実際にどんな感じでRay(線)が出ているかどうかわかります。
最初の引数が開始地点、次の引数が向き、次が線の色、次が線の数、次はよくわかりません・・・・謎。

自分の向きから相手の向きを算出する時は、相手の位置 – 自分の位置とすると方向が算出出来ます。

これで自動でカメラの位置を変更する事が出来るようになりました。
初期のバイオみたいに、ある部屋はこの視点で、ある通路はこの視点で、みたいのもレトロな感じで面白そうですけどね。

カメラが自動でキャラクターを映す機能を作り終えて

カメラがうまくキャラクターを表示してくれず色々やっていた記憶がありますが、単純に処理を間違えていました・・・(^_^;)
レイを飛ばす方向を

『RayCastゲームオブジェクトからキャラクター』へ飛ばしていましたが、実際に壁が間に入ったかどうかは

『キャラクターからRayCastゲームオブジェクト』へ飛ばす必要があります。

なぜならRayCastからレイを飛ばすとRayCast側の壁を接触場所にしてしまって結局キャラクターを映せないという事になります。
キャラクターからRayCastの方にレイを飛ばせばキャラクター側の壁が接触場所になるので必ずキャラクターを映してくれます。

これでちゃんとキャラクターを映してくれると思います。

以前書いていた不要な処理は混乱を招くので削除しました。

またカメラ位置を単純に接触した壁の位置にするだけでいいなら

Unityのゲームキャラクター操作をすべてマウス操作で行う
Unityのゲームで使用するキャラクターの移動やカメラの回転、カメラのズーム機能、カメラの壁対策、人との会話、敵を攻撃等のすべてをマウス操作で行う為の機能を作成していきます。

の記事で書いてあるカメラの壁対策の部分をご覧頂いた方がわかりやすいかもしれません。