Unityで別のゲームオブジェクトのスクリプトにアクセスする方法
はじめに
Unityでゲームを作るとき、あるゲームオブジェクトのスクリプトから、別のゲームオブジェクトのスクリプトにアクセスしたいことがよくあります。
例えば、「プレイヤーのHPを管理するスクリプト」に「敵のスクリプト」からアクセスして、ダメージを与えるといったケースです。
このチュートリアルでは、基本的な方法から実践的な方法まで、わかりやすく解説していきます!
1. GameObject.Find
を使う方法
どんなときに使う?
- シーン内に 必ず1つだけ存在するオブジェクト にアクセスしたいとき。
- ゲームの 開始時(
Start
やAwake
) に1回だけ取得する場合。
コード
1.1. 準備
まず、対象となる2つのオブジェクトを用意します。
① プレイヤー側(Playerオブジェクトにアタッチ)
using UnityEngine;
public class Player : MonoBehaviour
{
public int health = 100; // HP
public void TakeDamage(int damage)
{
health -= damage;
Debug.Log("プレイヤーの残りHP: " + health);
}
}
② 敵側(Enemyオブジェクトにアタッチ)
using UnityEngine;
public class Enemy : MonoBehaviour
{
void Start()
{
GameObject playerObject = GameObject.Find("Player"); // "Player" という名前のオブジェクトを探す
if (playerObject != null)
{
Player playerScript = playerObject.GetComponent<Player>(); // Playerスクリプトを取得
playerScript.TakeDamage(10); // 10ダメージを与える
}
}
}
ポイント
✅ GameObject.Find("オブジェクト名")
でシーン内のオブジェクトを検索
✅ GetComponent<スクリプト名>()
でスクリプトを取得
注意点
⚠️ 毎フレーム Find
を使うとパフォーマンスが悪くなる → Start
などで 1回だけ 使うのが良い。
2. GameObject.FindWithTag
を使う方法
どんなときに使う?
Find
だと 名前を変えると取得できなくなる → タグを使えば名前が変わっても大丈夫!- プレイヤーが複数シーンで共通 する場合、タグで検索すると便利。
コード
1.1. タグの設定
- Playerオブジェクトを選択
- Inspectorウィンドウ → 「Tag」 → 「Add Tag…」をクリック
- 「+」ボタンを押して「PlayerTag」を追加
- Playerオブジェクトのタグを「PlayerTag」に変更
1.2. FindWithTag
を使う
GameObject playerObject = GameObject.FindWithTag("PlayerTag");
if (playerObject != null)
{
Player playerScript = playerObject.GetComponent<Player>();
playerScript.TakeDamage(10);
}
メリット
✅ 名前を変更しても検索可能(タグで識別するため)
✅ Find
よりも 管理しやすい
デメリット
⚠️ タグを設定しないと機能しない
3. SerializeField
で手動設定(おすすめ!)
どんなときに使う?
- 最もパフォーマンスが良く、安定した方法
- Inspector でドラッグ & ドロップするだけ!
コード
3.1. 敵側(Enemyオブジェクトにアタッチ)
using UnityEngine;
public class Enemy : MonoBehaviour
{
[SerializeField] private Player player; // Inspector で設定できる変数
void Start()
{
if (player != null)
{
player.TakeDamage(10);
}
}
}
3.2. Inspectorで設定
- Enemyオブジェクトを選択
- Inspectorで「Player」フィールドが表示される
- シーン内のPlayerオブジェクトをドラッグしてセット!
メリット
✅ パフォーマンスが良い!(毎回検索しないので高速)
✅ オブジェクト名やタグを気にしなくて良い
デメリット
⚠️ 手動でInspectorにセットする手間がある
4. GetComponentInChildren
/ GetComponentInParent
を使う
どんなときに使う?
- 親子関係があるオブジェクトのスクリプトを取得する場合
コード
4.1. 子オブジェクトのスクリプトにアクセス
Player playerScript = GetComponentInChildren<Player>();
4.2. 親オブジェクトのスクリプトにアクセス
Player playerScript = GetComponentInParent<Player>();
5. FindObjectOfType
を使う
どんなときに使う?
- シーン内に 1つだけ特定のスクリプトがある場合
- デバッグ用に サクッと取得したいとき
コード
Player playerScript = FindObjectOfType<Player>();
if (playerScript != null)
{
playerScript.TakeDamage(10);
}
注意点
⚠️ シーン内に 複数のPlayerスクリプトがあると意図しないオブジェクトが取得される
⚠️ シーン全体を検索するため、パフォーマンスが悪い
6. Singleton
パターンを使う(高度な方法)
どんなときに使う?
- プレイヤーなど シーン全体で1つだけ存在するオブジェクト にアクセスするとき。
- どこからでも簡単にアクセスしたいとき。
6.1. Singleton
を作る
public class Player : MonoBehaviour
{
public static Player Instance { get; private set; }
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else
{
Destroy(gameObject);
}
}
public void TakeDamage(int damage)
{
Debug.Log("プレイヤーの残りHP: " + health);
}
}
6.2. Singleton
を使う
if (Player.Instance != null)
{
Player.Instance.TakeDamage(10);
}
メリット
✅ どこからでも簡単にアクセス可能!
✅ 毎回検索する必要なし
デメリット
⚠️ シングルトンの設計を間違えるとバグの原因になる
まとめ
方法 | 使いどころ |
---|---|
Find | シーン内に1つだけのオブジェクト |
FindWithTag | 名前が変わってもOK |
SerializeField | 最もおすすめ! |
GetComponentInChildren | 親子関係あり |
FindObjectOfType | デバッグ用 |
Singleton | どこからでもアクセス |
→ ゲームの状況に合わせて最適な方法を選ぼう!
ディスカッション
コメント一覧
まだ、コメントがありません