UnityUnityメモ

Unityで他のスクリプトの変数を取得する方法3選!初心者向け解説

Unity

はじめに

Unityでゲームを作っていると、「別のオブジェクトにあるスクリプトの変数を取得したい!」と思うことがよくありますよね。例えば、プレイヤーがアイテムを拾ったときにスコアを増やしたり、敵がダメージを受けたときにHPを減らしたりする場合、別のスクリプトにある変数を取得して使う必要があります。

しかし、初心者のうちは 「どうやって他のスクリプトの変数を取得すればいいの?」 と悩んでしまうことも多いでしょう。実は、他のオブジェクトにあるスクリプトの変数を取得する方法はいくつかあります。

この記事では、 「instanceを使う方法」「Findで取得する方法」「直接アタッチする方法」 の3つの方法をわかりやすく解説していきます! それぞれの方法のメリット・デメリットも紹介するので、自分のプロジェクトに合った方法を選んでみてくださいね。




1. インスタンス(instance)を使う方法

Unityでは、別のスクリプトの変数を簡単に取得する方法の一つとして 「インスタンス(instance)」 を使う方法があります。これは 「シングルトンパターン」 と呼ばれる設計方法の一種で、 オブジェクトが1つだけ存在することを保証しつつ、どこからでもアクセスできるようにする 仕組みです。


① インスタンスとは?

インスタンスとは オブジェクトの実体 のことを指します。C#では通常、new を使ってオブジェクトを作成しますが、Unityでは すでにシーン上にあるGameObjectのスクリプトをインスタンスとして利用する ことができます。

この方法では、static変数 を使って スクリプト内にグローバルなアクセスポイントを作る ことで、どこからでも変数を取得できるようにします。


② インスタンスを使った変数取得の流れ

実際に instance を使って Cubeをクリックすると、Sphereのスクリプトにある変数の値を取得する 仕組みを作ってみましょう。

① Sphereオブジェクト(アクセスされる側)のスクリプト

まず、SphereScript.cs を作成して Sphere にアタッチします。

SphereScript.cs
using UnityEngine;

public class SphereScript : MonoBehaviour
{
    public static SphereScript instance;  // 唯一のインスタンス
    public string sentence;  // 取得する変数

    void Awake()
    {
        // インスタンスがまだ作られていなければ自分を代入
        if (instance == null)
        {
            instance = this;
        }
    }

    void Start()
    {
        sentence = "これはボールです";
    }
}

② Cubeオブジェクト(アクセスする側)のスクリプト

次に、CubeScript.cs を作成し、Cube にアタッチします。

CubeScript.cs
using UnityEngine;

public class CubeScript : MonoBehaviour
{
    void OnMouseDown()
    {
        Debug.Log(SphereScript.instance.sentence);
    }
}



③ 実行手順

  1. Sphere と Cube をシーンに配置
    • Hierarchy ウィンドウで 右クリック → 3D Object → Sphere を作成
    • 右クリック → 3D Object → Cube を作成
  2. スクリプトをアタッチ
    • SphereScript.csSphere にドラッグ&ドロップ
    • CubeScript.csCube にドラッグ&ドロップ
  3. ゲームを実行し、Cube をクリック
    • Console ウィンドウに これはボールです と表示されれば成功!

④ メリット・デメリット

メリットデメリット
どこからでもアクセスできるので便利static を多用すると設計が複雑になりやすい
取得の処理が高速シングルトンの使い方を間違えるとメモリ管理が難しくなる
GameObject.Find() を使わないのでパフォーマンスが良い使いすぎると他のスクリプトとの依存関係が増え、バグが起きやすい

⑤ インスタンスを使うべき場面

シーンに1つしか存在しないオブジェクトのデータを管理したい時

  • 例:ゲームマネージャー(GameManager)やスコア管理(ScoreManager)など

頻繁にアクセスするデータを一元管理したい時

  • 例:プレイヤー情報や設定データ(BGMの音量、プレイヤー名 など)

注意点

  • static 変数は ゲーム中にシーンを変更しても値が残る ため、意図しない動作を引き起こすことがあります。
  • インスタンスが 複数作られるとバグの原因 になるため、Awake()if (instance == null) を必ずチェック しましょう。

この方法は、シンプルでパフォーマンスも良いですが、使いすぎるとコードが管理しにくくなることがあるので、適切な場面で活用してください!




2. GameObject.Find() を使う方法

① GameObject.Find() とは?

GameObject.Find("オブジェクト名") は、 シーン内にあるオブジェクトを名前で検索し、そのオブジェクトにアタッチされているスクリプトを取得する方法 です。

この方法を使えば、 オブジェクトの参照を Inspector で設定しなくても動的にスクリプトを取得 できます。特に、 プレイヤーが操作するオブジェクトや、シーンロード後に動的に生成されるオブジェクトにアクセスする場合 に便利です。

しかし、 GameObject.Find()オブジェクトを文字列で検索するため、名前が変更されたり、オブジェクトが見つからなかった場合にエラーが発生する可能性があります。また、 処理が若干重いため、頻繁に呼び出すのは避けた方がよい です。

では、具体的なコードを見てみましょう!


② コード例

まず、 SphereScriptsentence という文字列の変数を用意し、それを CubeScript から取得するようにします。

SphereScript.cs(アクセスされる側)
using UnityEngine;

public class SphereScript : MonoBehaviour
{
    public string sentence;

    void Start()
    {
        sentence = "これはボールです";
    }
}

解説:

  • sentence という public な文字列変数を作成。
  • Start() で変数に "これはボールです" という文字列を代入。



CubeScript.cs(アクセスする側)
using UnityEngine;

public class CubeScript : MonoBehaviour
{
    private GameObject sphereObject; // Sphereオブジェクトの参照
    private SphereScript sphereScript; // スクリプトの参照

    void OnMouseDown()
    {
        sphereObject = GameObject.Find("Sphere"); // 名前でオブジェクトを検索
        sphereScript = sphereObject.GetComponent<SphereScript>(); // スクリプトを取得

        Debug.Log(sphereScript.sentence); // 変数の値を表示
    }
}

解説:

  1. GameObject.Find("Sphere") で、シーン内の "Sphere" という名前のオブジェクトを探す。
  2. .GetComponent<SphereScript>() で、そのオブジェクトにアタッチされている SphereScript を取得する。
  3. sphereScript.sentenceDebug.Log() でコンソールに表示する。

③ 実行してみよう

このコードを実行するには、以下の手順を行います。

  1. Hierarchy ウィンドウで「Sphere」と「Cube」を作成
    • 「Sphere」の名前を "Sphere" に変更する(Findで検索するため)。
    • 「Cube」の名前はそのままでOK。
  2. 「Sphere」に SphereScript.cs を追加
    • SphereScript.cs を作成し、「Sphere」にアタッチする。
  3. 「Cube」に CubeScript.cs を追加
    • CubeScript.cs を作成し、「Cube」にアタッチする。
  4. ゲームを再生し、Cube をクリックする
    • コンソールに 「これはボールです」 と表示されれば成功!

④ メリット・デメリット

メリットデメリット
static を使わずにスクリプトを取得できるオブジェクトの名前が変わると動作しなくなる
public フィールドを設定する手間が不要GameObject.Find() の処理が重い
シーン内のオブジェクトを動的に取得できるシーンに存在しないとエラーが発生する

⑤ GameObject.Find() を使う際の注意点

❌ 使いすぎに注意! GameObject.Find() は、 毎回シーン内を検索するため、処理負荷が高い です。
例えば、 Update() 内で毎フレーム GameObject.Find() を使うのは パフォーマンスが悪くなる原因 になります。

✅ 解決策:一度だけ取得する Start()Awake() 内で 1回だけ GameObject.Find() を実行し、変数に保存しておくのがおすすめです。

void Start()
{
sphereObject = GameObject.Find("Sphere");
sphereScript = sphereObject.GetComponent<SphereScript>();
}

このようにすれば、 OnMouseDown() が呼ばれるたびに GameObject.Find() を使わずに済む ため、パフォーマンスを向上させることができます。


まとめ

  • GameObject.Find() を使うと、 オブジェクトを名前で検索してスクリプトを取得できる
  • しかし、 処理が重く、名前が変わると動作しなくなるため、注意が必要
  • 使用する場合は、Start() などで一度だけ取得し、頻繁に呼び出さないようにするのがポイント!

この方法は、 プレイヤーのオブジェクトを探したいときや、スクリプト間でデータをやり取りしたいとき に活用できます。
ただし、 最適な方法を選ぶことが重要なので、他の方法(インスタンスや直接アタッチ)とも比較してみましょう!




3. 直接スクリプトをアタッチする方法

① 直接アタッチとは?

他のオブジェクトにあるスクリプトの変数を取得する一番シンプルな方法が「直接アタッチする方法」です。
これは スクリプトの変数をpublicとして宣言し、Inspectorウィンドウで手動で紐づける というものです。

この方法を使えば、パフォーマンスが最も軽く、可読性の高いコード を書くことができます。
ただし、オブジェクトを手動でセットする手間があるので、スクリプトの再利用性を考えながら使いましょう。


② コード例

まず、変数を持つスクリプト(SphereScript.cs)を作成し、Sphereオブジェクト に追加します。

SphereScript.cs

using UnityEngine;

public class SphereScript : MonoBehaviour
{
    public string sentence;

    void Start()
    {
        sentence = "これはボールです";
    }
}

このスクリプトでは、sentence という string 型の変数を定義し、 Start()"これはボールです" という文字列を代入しています。

次に、SphereScript の変数を取得するスクリプト(CubeScript.cs)を作成し、Cubeオブジェクト に追加します。

CubeScript.cs

using UnityEngine;

public class CubeScript : MonoBehaviour
{
    public SphereScript sphereScript;

    void OnMouseDown()
    {
        Debug.Log(sphereScript.sentence);
    }
}

このコードでは、public SphereScript sphereScript; と宣言することで、UnityのInspectorウィンドウから SphereScript を直接アタッチできるようになります。




③ UnityのInspectorでの設定

  1. Cube オブジェクトを選択し、Inspectorウィンドウを開く。
  2. CubeScript のスクリプトコンポーネントを確認する。
  3. SphereScript の変数を持つ Sphere オブジェクトを sphereScript フィールドに ドラッグ&ドロップ する。

これで、CubeScriptSphereScriptsentence 変数を参照できるようになりました。


④ ゲームプレイでの動作確認

  1. ゲームを再生 する。
  2. Cube をクリックする。
  3. コンソールに "これはボールです" と表示される。

これで、直接アタッチしたスクリプトの変数を取得できたことが確認できます!


⑤ メリット・デメリット

メリット

  • 取得処理が最も高速(staticFind を使わない)。
  • コードがシンプルで可読性が高い。
  • 余計なメモリ消費がなく、パフォーマンスが良い。

デメリット

  • Inspectorで手動でセットする手間がある。
  • Prefabで管理する場合、適用漏れに注意が必要。

⑥ どんなときに使うべき?

この方法は 「事前に関連オブジェクトが決まっている場合」 に最適です。
例えば、プレイヤーキャラクターのスクリプトが、特定のUIやエフェクトを管理する場合などに向いています。

一方で、シーン内で動的に生成されるオブジェクトには向かない ので、その場合は Find()instance を使う方が適しています。

この方法はシンプルで理解しやすいので、初心者にもおすすめです!




まとめ

Unityで他のスクリプトの変数を取得する方法として、以下の3つの方法を紹介しました。

方法メリットデメリット
インスタンスを使うどこからでもアクセス可能、高速static を多用すると設計が崩れやすい
GameObject.Find()static を使わずに取得できる名前変更で動作しなくなる、処理が重い
直接アタッチ処理が軽く、コードがシンプルInspector での手動設定が必要

それぞれの方法には特徴があり、状況によって適切な方法を選ぶことが重要です。

どの方法を使うべき?

  • グローバルにアクセスできる変数が必要なら → static を使うインスタンスパターン
  • オブジェクトの名前で取得したいなら → GameObject.Find() を使う
  • シンプルで確実な方法がいいなら → Inspectorでアタッチする

Unityでは開発の規模やコードの管理方法によって適した方法が変わります。まずは基本的なやり方を理解し、状況に応じて使い分けられるようになりましょう!




よくある質問(FAQ)

Q
一番おすすめの方法はどれですか?
A

パフォーマンスと管理のしやすさを考えると、 「直接アタッチ」 がおすすめです。 GameObject.Find() は処理が重く、 static を使う方法はバグの原因になりやすいので、できるだけ避けるのがよいでしょう。

Q
static を使うとバグが起きやすいのはなぜ?
A

static はオブジェクトのインスタンスが破棄されても値を保持し続けるため、不要なデータが残ったり、複数のオブジェクトが同じ static 変数を参照してしまうことがあります。

Q
GameObject.Find() を使うべき場面は?
A

どうしてもオブジェクトを動的に探して参照したい場合に使います。ただし、処理が重いため、Start() で1回だけ取得して、Update() で繰り返し使わないようにしましょう。

タイトルとURLをコピーしました