| この記事の要点 |
|
GetComponent の基本
using UnityEngine;
public class Sample : MonoBehaviour
{
void Start()
{
// ジェネリック版(推奨)
Rigidbody rb1 = GetComponent<Rigidbody>();
// 型引数なし(古い書き方、Cast 必要)
Rigidbody rb2 = (Rigidbody)GetComponent(typeof(Rigidbody));
// 文字列版(遅い、補完効かない、リフレクション)
Rigidbody rb3 = (Rigidbody)GetComponent("Rigidbody");
// 取得できなかったときは null
if (rb1 == null) Debug.LogWarning("Rigidbody missing");
}
}
3 つの書き方の中で、ジェネリック版が最速かつ最も保守的です。文字列版はリフレクションを使うため数倍遅く、リネーム時にコンパイラがミスを検知できません。
TryGetComponent(GC 回避)
Unity 2019.2 以降では TryGetComponent が利用できます。コンポーネント未存在時に null を返す代わりに false を返し、UnityEngine.Object との比較で発生する GC ゴミを回避します。
// ❌ 旧来: null 比較が偽 null 経由で GC を発生させる
var rb = GetComponent<Rigidbody>();
if (rb != null) rb.AddForce(Vector3.up);
// ✅ 推奨: TryGetComponent
if (TryGetComponent(out Rigidbody rb)) {
rb.AddForce(Vector3.up);
}
キャッシュは必須
GetComponent は毎呼び出しで内部リスト走査します。Update で呼ぶと毎フレームのコストが積み重なります。Awake / Start で取得して private フィールドに保持してください。
public class Mover : MonoBehaviour
{
private Rigidbody _rb;
private Animator _anim;
void Awake()
{
_rb = GetComponent<Rigidbody>();
_anim = GetComponent<Animator>();
}
void FixedUpdate()
{
_rb.AddForce(transform.forward * 10f);
_anim.SetFloat("Speed", _rb.velocity.magnitude);
}
}
RequireComponent 属性
「このスクリプトには必ず Rigidbody が必要」と表現したい場合、[RequireComponent] 属性を使います。
- アタッチ時に未存在ならば自動追加
- 該当コンポーネントを Inspector から削除しようとすると警告が出る
- 依存関係を宣言的に表現でき、ドキュメントとしても機能
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(Collider))]
public class Bullet : MonoBehaviour
{
private Rigidbody _rb;
void Awake() { _rb = GetComponent<Rigidbody>(); }
// Rigidbody が必ず居るので null チェック不要
}
子・親からの取得
// 自身+子孫
var aud = GetComponentInChildren<AudioSource>();
// 自身+祖先
var canvas = GetComponentInParent<Canvas>();
// 配列で複数取得
var rends = GetComponentsInChildren<Renderer>();
// 非アクティブも含む
var hiddenAud = GetComponentInChildren<AudioSource>(includeInactive: true);
コンポーネント追加と削除
// 追加
var rb = gameObject.AddComponent<Rigidbody>();
rb.mass = 2f;
// 削除(GameObject ではなく Component を渡す!)
Destroy(rb);
// すぐ削除(Editor 用)
DestroyImmediate(rb);
// 同型を複数つけられないコンポーネント(Rigidbody 等)に重複 AddComponent するとエラー
// 重複は AudioSource など限られた型のみ可
パフォーマンス指針
| 呼び方 | 速度 | 使い所 |
|---|---|---|
| キャッシュ済フィールド | ★★★★★ | Update / FixedUpdate |
TryGetComponent<T> | ★★★★ | 初回 / 条件分岐 |
GetComponent<T> | ★★★ | Awake / Start |
GetComponentInChildren | ★★ | 必要時のみ |
GetComponent("StringName") | ★ | 使わない |
ECS(DOTS)との比較
Unity DOTS の ECS(Entity Component System)では、コンポーネントは IComponentData 構造体としてエンティティに付与されます。MonoBehaviour とは設計思想が大きく異なり、キャッシュフレンドリで CPU SIMD 最適化がしやすい代わりに、API がまったく別物になります。大量オブジェクト(数千〜数万)を扱うときに検討してください。
// ECS の例(IJobEntity)
[BurstCompile]
partial struct MoveJob : IJobEntity
{
public float dt;
void Execute(ref LocalTransform t, in MoveSpeed s)
{
t.Position += new float3(0, 0, s.Value * dt);
}
}
よくあるトラブル
| 症状 | 原因 | 対処 |
|---|---|---|
| NullReferenceException | GetComponent が null を返した | RequireComponent / TryGetComponent |
| FixedUpdate が遅い | 毎回 GetComponent | Awake でキャッシュ |
| 同じ Rigidbody が 2 個ついた | AddComponent を 2 回呼んだ | 事前に TryGetComponent で確認 |
| Destroy(gameObject) しちゃった | Component 削除のつもりが GO ごと消失 | Component 変数を Destroy に渡す |
FAQ
Q: 同じ GameObject に同じコンポーネントを複数付けたい
A: AudioSource は複数可。Rigidbody や Collider 系は不可(特定の Collider のみ可)。複数アタッチが許容されるかは型ごとに違います。
Q: インターフェイス型で取得できる?
A: できます。GetComponent<IDamageable>() でインターフェイスを実装した MonoBehaviour が返ります。
Q: コンポーネント削除のタイミングは?
A: Destroy はフレーム終了時に実行されます。即時必要なら DestroyImmediate(ただしランタイムでは使わない)。
子ページはありません
人気ページ
- 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