| この記事の要点 |
|
GameObject 取得の主要 API
| API | 戻り値 | コスト | 用途 |
|---|---|---|---|
GameObject.Find("Name") | GameObject | ★★★(重い、シーン全走査) | 起動時 1 回限定 |
GameObject.FindGameObjectWithTag("Tag") | GameObject | ★★(Find より速い) | タグ付け済オブジェクト取得 |
GameObject.FindGameObjectsWithTag("Tag") | GameObject[] | ★★ | 同タグ複数取得 |
FindObjectsOfType<T>() | T[] | ★★★(極重) | シーン横断検索 |
FindFirstObjectByType<T>() | T | ★★ | Unity 2022.3+ 推奨 |
[SerializeField] T field | T | ★(直接代入) | 推奨 |
サンプル: 各取得方法
using UnityEngine;
public class FindSample : MonoBehaviour
{
// ★ 推奨: Inspector でアサイン
[SerializeField] private GameObject player;
[SerializeField] private Camera mainCam;
void Start()
{
// 名前で検索(重い、起動時のみ)
var enemy = GameObject.Find("Enemy");
// タグで検索(マシだが it も重い)
var goal = GameObject.FindGameObjectWithTag("Goal");
// 全タグ一致を配列取得
var enemies = GameObject.FindGameObjectsWithTag("Enemy");
// 型から検索(最も重い)
// Unity 2022.3 以降は FindFirstObjectByType を使う
var manager = FindFirstObjectByType<GameManager>();
// ★ Camera.main は内部キャッシュ済(GameObject.Find より速いが過信注意)
var cam = Camera.main;
}
}
Component 取得の主要 API
| API | 探索範囲 | 備考 |
|---|---|---|
GetComponent<T>() | 同じ GameObject | 基本 |
GetComponentInChildren<T>() | 自身+子孫 | 非アクティブ含めるオプションあり |
GetComponentInParent<T>() | 自身+祖先 | 同上 |
GetComponents<T>() | 同 GO の T 全部 | 配列で返る |
GetComponentsInChildren<T>() | 自身+子孫の全 T | UI のリスト取得に便利 |
TryGetComponent<T>(out T x) | 同 GO | 未存在で null を返さず bool。GC ゼロ |
キャッシュ推奨パターン
Update 内で毎フレーム GetComponent を呼ぶのは厳禁です。Awake / Start で取得して private フィールドに保持してください。
public class PlayerController : MonoBehaviour
{
// ★ 1. SerializeField で Inspector からアサインが最速・最安全
[SerializeField] private Rigidbody rb;
[SerializeField] private Animator anim;
// ★ 2. 同 GameObject 内ならコードで Awake キャッシュも可
private AudioSource _audio;
void Awake()
{
// null チェックは TryGetComponent が便利
if (!TryGetComponent(out _audio)) {
Debug.LogWarning("AudioSource not found, adding one.");
_audio = gameObject.AddComponent<AudioSource>();
}
}
void Update()
{
// ✅ キャッシュ済を使う
rb.AddForce(Vector3.up);
anim.SetFloat("Speed", rb.velocity.magnitude);
// ❌ NG: 毎フレーム取得
// GetComponent<Rigidbody>().AddForce(Vector3.up);
}
}
子孫からの取得
// 自分含む子の AudioSource を 1 つ取得
var aud = GetComponentInChildren<AudioSource>(includeInactive: true);
// 子孫の Renderer を全部
var renderers = GetComponentsInChildren<Renderer>();
foreach (var r in renderers) r.enabled = false;
UnityEvent と デリゲートでイベント連携
毎回 Find で参照する代わりに、イベント駆動にすると依存が逆転し、テストも容易になります。
using UnityEngine;
using UnityEngine.Events;
public class Health : MonoBehaviour
{
[SerializeField] private UnityEvent onDead;
public void TakeDamage(int dmg)
{
// ...
if (dmg >= 100) onDead.Invoke();
}
}
// → 受け取り側を Inspector でアサインしておけば Find 不要
パフォーマンス比較(概略)
| 呼び方 | 相対コスト | 毎フレーム呼んで良い? |
|---|---|---|
| 直接 SerializeField 参照 | 1 | はい |
| キャッシュ済の参照 | 1 | はい |
GetComponent<T> | ~10 | 避ける |
GetComponentInChildren | ~30 | 避ける |
FindGameObjectWithTag | ~50 | NG |
GameObject.Find | ~200 | NG |
FindObjectsOfType | ~500+ | 絶対 NG |
Camera.main の注意
Camera.main は Unity 内部で "MainCamera" タグ付きカメラを返します。初回呼び出しはキャッシュ生成があるため、頻繁にアクセスするなら自分でキャッシュしてください。
private Camera _cam;
void Awake() { _cam = Camera.main; }
void Update() {
var world = _cam.ScreenToWorldPoint(Input.mousePosition);
}
シングルトンと DI の検討
頻繁に「ゲーム全体で 1 つ」のオブジェクトにアクセスするなら、シングルトンや DI コンテナ(VContainer / Zenject)を使うほうが、Find より高速かつテストしやすくなります。
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; private set; }
void Awake()
{
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
}
}
// 利用側
GameManager.Instance.AddScore(10);
FAQ
Q: GameObject.Find が動かない
A: 非アクティブなオブジェクトは Find できません。タグ検索(FindGameObjectWithTag)でも同様です。FindObjectsOfType(true) の引数で includeInactive を渡してください。
Q: SerializeField と public、どちらを使う?
A: [SerializeField] private が推奨。外部から書き換えられず、Inspector では編集可能というカプセル化が両立します。
Q: Find は何回までなら許容?
A: 1 シーンの起動時に数回程度なら問題なし。Update / FixedUpdate 内では絶対 NG です。
子ページ
子ページはありません
同階層のページ
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38