UnityのCamera.mainとは? GetComponent<Camera>()との違いを理解しよう
Unityでマウス位置からRayを飛ばすコードを書いていると、次のようなコードを見かけることがあります。
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.value);
ここで初心者の方が気になりやすいのが、
Camera.main
です。
「これは GetComponent<Camera>() と何が違うの?」
「MainCameraという名前のカメラを取っているの?」
今回は、この Camera.main の意味を整理してみます。
Camera.mainは何を取得している?
Camera.main は、シーン内にある
MainCamera タグが付いているGameObjectのCameraコンポーネント
を取得するためのプロパティです。
たとえば、Unityで最初から作成されている Main Camera を選択すると、Inspectorの上部に
Tag: MainCamera
と設定されています。
Camera.main は、このタグを手掛かりにCameraを取得します。
イメージとしては、次のような処理に近いです。
GameObject obj = GameObject.FindGameObjectWithTag("MainCamera");
Camera cam = obj.GetComponent<Camera>();
つまり、
Camera.main
と書くだけで、メインカメラの Camera コンポーネントを取得できます。

GameObjectの名前が「Main Camera」だからではない
ここは特に重要です。
Camera.main は、
GameObjectの名前が「Main Camera」
だから取得しているわけではありません。
確認してみましょう。
GameObjectの名前を、
Main Camera
から
MyCamera
に変更しても、
Tag: MainCamera
のままであれば、
Camera.main
で取得できます。
逆に、GameObjectの名前が
Main Camera
でも、タグを
Untagged
に変更すると、
Camera.main
では取得できません。
つまり判断基準は、
名前ではなくタグ
です。
GetComponent<Camera>()との違い
では、
GetComponent<Camera>()
とは何が違うのでしょうか。
GetComponent<Camera>() は、
このスクリプトが付いているGameObjectからCameraコンポーネントを探します。
たとえば、次のスクリプトをカメラ自身に付けたとします。
using UnityEngine;
public class CameraTest : MonoBehaviour
{
void Start()
{
Camera cam = GetComponent<Camera>();
}
}
この場合は、
CameraTest
↓
同じGameObject
↓
Cameraコンポーネント
を取得します。

Camera.mainは別のGameObjectから取得できる
一方、
Camera.main
は、このスクリプトがどこに付いているかは関係ありません。
たとえば、
Player
にスクリプトが付いていても、
Camera cam = Camera.main;
と書けば、
Player
↓
MainCameraタグを探す
↓
Main Camera
↓
Cameraコンポーネント
という考え方でCameraを取得できます。
2つを比べてみる
違いを簡単に整理すると、次のようになります。
| 書き方 | どこから探す? |
|---|---|
GetComponent<Camera>() |
このGameObject |
Camera.main |
MainCameraタグが付いたGameObject |
つまり、
GetComponent<Camera>()
は
「自分が持っているCameraをください」
という処理です。
一方、
Camera.main
は
「シーンのメインカメラをください」
という処理だと考えると分かりやすいでしょう。
最初のコードをもう一度見てみよう
それでは、最初のコードに戻ります。
Ray ray = Camera.main.ScreenPointToRay(
Mouse.current.position.value
);
まず、
Camera.main
でメインカメラを取得しています。
次に、
Mouse.current.position.value
で現在のマウスカーソルの画面上の座標を取得します。
そして、
ScreenPointToRay()
を使って、その画面上の位置を通るRayを作っています。
つまり、この1行は、
メインカメラから見て、マウスカーソルがある方向へRayを作る
という処理になります。

処理を分けると分かりやすい
初心者のうちは、1行で書かずに分けてみるのもおすすめです。
Camera cam = Camera.main;
Vector2 mousePosition = Mouse.current.position.value;
Ray ray = cam.ScreenPointToRay(mousePosition);
こうすると、
1. Cameraを取得する
2. マウス位置を取得する
3. Rayを作る
という3段階になり、処理が見やすくなります。
「MainCameraだったらGetComponentする」と考えてよい?
学習段階では、
MainCameraタグのGameObjectを探す
↓
そのCameraコンポーネントを取得する
というイメージを持っておけば十分です。
たとえば頭の中では、
GameObject obj =
GameObject.FindGameObjectWithTag("MainCamera");
Camera cam =
obj.GetComponent<Camera>();
のような処理だと考えると理解しやすいでしょう。
ただし、実際に自分でこのコードを書く必要はありません。
Unityが用意している
Camera.main
を使えば、簡潔に書くことができます。
Camera.mainがnullになることもある
注意点もあります。
シーン内に
MainCamera
タグが付いているCameraが存在しない場合、
Camera.main
は null になります。
その状態で、
Camera.main.ScreenPointToRay(...)
を実行するとエラーになる可能性があります。
そのため、
Main Cameraを削除した
タグをUntaggedに変更した
別のCameraを作った
といった場合には、タグ設定も確認してみましょう。
まとめ
今回のポイントは次のとおりです。
Camera.main
は、
MainCameraタグが付いているGameObjectのCameraコンポーネントを取得する
ためのものです。
一方、
GetComponent<Camera>()
は、
このスクリプトが付いているGameObjectのCameraコンポーネントを取得する
ためのものです。
そして、
Ray ray =
Camera.main.ScreenPointToRay(
Mouse.current.position.value
);
は、
メインカメラから見て、マウス位置の方向へRayを作る
という処理になります。
1行のコードでも、
Cameraを取得する
↓
マウス位置を取得する
↓
Rayを作る
と分解して考えると、Unityのコードはぐっと読みやすくなります。
あわせて読みたい
Rayそのものを先に理解したい方は、UnityにおけるRay構造体の解説もどうぞ。画面上の座標については、【Unity】ワールド座標、スクリーン座標、RectTransform座標が参考になります。
【シリーズ】Raycastで弾痕を作りながら学ぶ(1/9)
シリーズ目次 | 次の記事:RaycastHitの中身(point・normal・distance・collider) →











ディスカッション
コメント一覧
まだ、コメントがありません