【Unity】プレイヤーにカメラを追従させよう!(3D)|Camera入門④
前回の連載記事はCamera入門③「カメラをマウスに連動させて回転させよう!」でした。
連載の第四弾となる今回は、3Dゲームのプレイヤーにカメラを追従させる方法をご紹介します。
ノンプログラミングによる追従・スクリプトによる追従を解説していきます。
※本記事の被写体には「Unity-Chan(ユニティちゃん)」を使用しています。
© Unity Technologies Japan/UCL
参考ページ)ユニティちゃん公式サイト
ノンプログラミングで追従(3D)
3Dゲームにおいてノンプログラミングでカメラを追従させる方法を解説します。
方法の流れを説明すると、
- カメラを追従させるプレイヤー(ユニティちゃん)の設置
- メインカメラの位置調節
- メインカメラをプレイヤーの子オブジェクトに設定
以上の流れでノンプログラミングによるカメラの追従を実現させます。
プレイヤー(ユニティちゃん)の設置
まずは動くプレイヤー(ユニティちゃん)を以下のように設置してください。
本記事では被写体としてユニティちゃんを使用しますが、動かすプレイヤーはどのキャラクターでも問題ありません。
↓動くユニティちゃんを設置
動くユニティちゃんの設置方法は以下記事をご参考ください。
またこのとき、ユニティちゃんの位置はX,Y,Zそれぞれ「0」に設定してください。
↓ユニティちゃんのTransform
メインカメラの位置調節
次にメインカメラの位置を調節します。
今回は第三者視点にカメラ位置を調節します。
ヒエラルキービューでMainCameraを選択して、インスペクタービューのTransformを設定します。
↓メインカメラのTransform
↓ゲームビュー
このとき、画角など細かく設定したいときは以下記事をご参考ください。
参考記事)カメラの基本設定を理解しよう!
この状態のまま実行すると、メインカメラは固定されたままになるのでプレイヤーを追従してくれません。
↓カメラが追従してくれない
原因はユニティちゃんの座標もメインカメラの座標もワールド座標を基準としているからです。
ワールド座標では世界の中心を(X,Y,Z)=(0,0,0)と考えます。そのためユニティちゃんが動いても、メインカメラのワールド座標の位置は当然変わりません。
この問題をローカル座標を使用して解決します。
ローカル座標では、親オブジェクトの座標を中心(X,Y,Z)=(0,0,0)として子オブジェクトの座標を考えます。
つまり、プレイヤーがワールド座標で動くとその動いたプレイヤーの位置が中心となります。(座標ごと移動するイメージ)
座標について詳しく知りたい場合は以下記事をご参考ください。
参考記事)Transformを使って3Dオブジェクトを移動させる
メインカメラをプレイヤーの子オブジェクトに設定
最後にメインカメラをプレイヤーの子オブジェクトに設定します。
先ほど説明した通り、メインカメラをプレイヤーの子オブジェクトに設定することでプレイヤーを中心とした座標を指定することができます。
メインカメラをプレイヤーの子オブジェクトに設定する方法はとても簡単です。
ヒエラルキービューでMainCameraをunitychanにドラッグ&ドロップしてください。
↓メインカメラをプレイヤー(ユニティちゃん)にドラッグ&ドロップ
これだけでメインカメラをプレイヤーの子オブジェクトに設定することができました。
それでは実際に実行して確認してみましょう。
↓カメラ追従成功
このような方法を用いることで、簡単にプレイヤーにカメラを追従させることができます。
スクリプトで追従(3D)
続いて3Dゲームでスクリプトを用いてプレイヤーにカメラを追従させる方法を解説します。
結論から述べると、スクリプトによる追従は第三者視点での追従はUnity初心者には向いていません。
理由は後ほどプログラムを記述しながら説明します。
ですので今回はスクリプトで一定距離からプレイヤーを追従する方法のみをご紹介します。
方法の流れを説明すると、
- カメラを追従させるプレイヤー(ユニティちゃん)の設置
- メインカメラの位置調整
- スクリプトの作成
- スクリプトの設置
以上の流れでカメラの追従を実現させます。
1〜2までの流れは先ほどと同じですので、「ノンプログラミングで追従」をご参考ください。
また、次に作業を始める前にメインカメラをユニティちゃんの子オブジェクトから外してください。
スクリプトの作成・スクリプトの設置
この章ではスクリプトの作成から始めます。
まず、赤枠のプロジェクトビュー→Create→C# Scriptを選択してスクリプトを作成してください。
↓スクリプト作成
作成したスクリプトの名前は任意ですが、ここでは「CameraSample」とします。
スクリプトを以下のように変更してください。
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 26 27 28 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraSample : MonoBehaviour { private GameObject player; //プレイヤー情報格納用 private Vector3 offset; //相対距離取得用 // Use this for initialization void Start () { //unitychanの情報を取得 this.player = GameObject.Find("unitychan"); // MainCamera(自分自身)とplayerとの相対距離を求める offset = transform.position - player.transform.position; } // Update is called once per frame void Update () { //新しいトランスフォームの値を代入する transform.position = player.transform.position + offset; } } |
プログラムの内容を簡単に説明します。
まずはじめにStart関数でユニティちゃんのpositionの値を取得して、メインカメラのpositionとの差分offsetを求めます。
次にUpdate関数で求めた差分offsetとプレイヤーの現在の値の合計をメインカメラの新しいpositionの値として代入しています。
これによって常に同じ距離でプレイヤーを追従します。
このスクリプトだけでは先ほどのように常に第三者視点の追従は実現できません。どのような追従になり、なぜそのような追従方法になるのか想像しながら実行してみてください。
次に作成したスクリプトをメインカメラに設定します。
プロジェクトビューから作成したCameraSampleスクリプトをヒエラルキービューのMainCameraにドラッグ&ドロップしてください。
↓スクリプトを適用させる
これでスクリプトの設定は完了です。
では実際に実行して確認してみましょう。
↓スクリプトによる追従
先ほどとの違いはユニティちゃんを真後ろから追従してくれない点です。
ユニティちゃんとメインカメラのpositionの値のみを参照しているため、向き(rotation)を参照していないことが原因です。
では、次に向きまで参照してくれるようにスクリプトを書き換えましょう。
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 26 27 28 29 30 31 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraSample : MonoBehaviour { private GameObject player; //プレイヤー情報格納用 private Vector3 offset; //相対距離取得用 // Use this for initialization void Start () { //unitychanの情報を取得 this.player = GameObject.Find("unitychan"); // MainCamera(自分自身)とplayerとの相対距離を求める offset = transform.position - player.transform.position; } // Update is called once per frame void Update () { //新しいトランスフォームの値を代入する transform.position = player.transform.position + offset; //ユニティちゃんの向きと同じようにカメラの向きを変更する transform.rotation = player.transform.rotation; } } |
追加部分を黄色で強調してあります。
positionと同じようにメインカメラのrotationの値をユニティちゃんのrotationの値に変更しています。
実はこの書き方ではうまくいきません。
実際に実行して確認してみましょう。
↓ユニティちゃんのrotationをそのままメインカメラに代入
本来ならばユニティちゃんを中心に回転しなければならないところを、ユニティちゃんと同じように回転してしまっているためにうまく追従できなくなっています。
このようにユニティちゃんを中心に回転させるためにはもう少し具体的な計算が必要になります。
そのため、今回のCamera入門では扱いません。
追従+回転
最後に応用として、追従しながら左右のシフトキーで回転させながら追従する方法をご紹介します。
回転には「RotateAround()」を使用します。詳しい使い方はリンクをご参考ください。
RPGなどでフィールドを移動させる時などは、ほとんどこの方式なのではないでしょうか。
まずはじめに先ほどメインカメラに取り付けたスクリプトを外してください。
↓スクリプトの外し方
次にメインカメラをプレイヤー(ユニティちゃん)の子オブジェクトに設定します。(やり方は先ほどと同じです)
新しくスクリプト「CameraRotate」を作成します。
スクリプトの内容を以下のように編集してください。
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 26 27 28 29 30 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraRotate : MonoBehaviour { private GameObject player; //プレイヤー格納用 // Use this for initialization void Start () { //unitychanをplayerに格納 player = GameObject.Find("unitychan"); } // Update is called once per frame void Update () { //左シフトが押されている時 if (Input.GetKey(KeyCode.LeftShift)) { //ユニティちゃんを中心に-5f度回転 transform.RotateAround(player.transform.position, Vector3.up, -5f); } //右シフトが押されている時 else if(Input.GetKey(KeyCode.RightShift)) { //ユニティちゃんを中心に5f度回転 transform.RotateAround(player.transform.position, Vector3.up, 5f); } } } |
プログラムの説明は省略しますが、これでユニティちゃんの周りをカメラが回転するスクリプトを作ることができました。
それでは実際にメインカメラに取り付けてから実行してみましょう。
↓スクリプトの取り付け
↓実行結果
シフトを押すと回転することがわかると思います。
前回の連載と被る部分もありますが、組み合わせることでよりゲームらしくなります。
まとめ
いかがでしたでしょうか。
Unityカメラの連載(Camera入門)第四弾として、3Dゲームのカメラ追従についてご紹介してきました。
基本的な追従であれば、子オブジェクト化するのが楽ですが、オリジナリティを出したい場合はスクリプトの記述をお勧めします。
次回は2Dゲームにおけるカメラの追従方法についてご紹介する予定です。
↓他の連載記事もぜひご参考ください。
Camera入門①)カメラの基本設定を理解しよう!
Camera入門②)カメラの切り替えをスクリプトで実現しよう!
Camera入門③)カメラをマウスに連動させて回転させよう!
↓Unity関連記事はこちらをご参考ください
Unity関連記事)【入門】Unityを使ったアプリ開発ができるようになる!Unityの基本からARへの応用まで
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!