UnityUnityメモ

Unityで他のスクリプトの関数を実行する方法!初心者向け解説

Unity

1. はじめに

Unityでゲームを作っていると、「別のスクリプトの関数を呼び出したい!」という場面がよくあります。たとえば、プレイヤーがジャンプする Jump() 関数を Player スクリプトに書いたけど、ゲーム全体を管理する GameManager スクリプトからジャンプさせたい…なんてことありますよね。

しかし、初心者の方にとっては、「別のスクリプトにある関数をどうやって実行すればいいの?」と悩むことも多いはずです。GetComponent を使うのか? それとも FindObjectOfType を使えばいいのか? どの方法が正しいのか分からず、エラーにハマってしまうこともあります。

そこで、この記事では 他のスクリプトの関数を実行する方法 を分かりやすく解説していきます! 初心者の方でもスムーズに理解できるように、 「基本編」「応用編」「おすすめのやり方」 の順番で紹介していくので、ぜひ最後まで読んでみてくださいね!




2. 他のスクリプトの関数を実行する基本

Unityでゲームを作っていると、「あるスクリプトの関数を別のスクリプトから呼び出したい!」という場面がよくあります。例えば、プレイヤーのスクリプトにJumpという関数があり、それをゲームマネージャーのスクリプトから実行したいとしましょう。

でも、いざコードを書いてみると、

  • 「関数が見つからない!」
  • 「エラーが出て動かない!」
  • 「どうやって呼び出せばいいかわからない…」

と悩んでしまうこともありますよね。

そこで、まずはスクリプト間で関数を呼び出すための基本をおさえておきましょう!


スクリプト間で関数を呼び出す仕組み

Unityでは、C#のオブジェクト指向の考え方に基づいてスクリプトが動作します。つまり、関数を実行するには、そのスクリプトがアタッチされたオブジェクトを取得する必要があります。

例えば、次のようなPlayerスクリプトがあったとします。

public class Player : MonoBehaviour
{
public void Jump()
{
Debug.Log("ジャンプ!");
}
}

このJump関数を別のスクリプト(例えばGameManager)から実行するには、Playerスクリプトを持つオブジェクトを取得し、その関数を呼び出すという手順が必要になります。


関数のアクセス修飾子に注意

C#では、関数のアクセス修飾子(publicprivate)によって、他のスクリプトから呼び出せるかどうかが決まります。

修飾子他のスクリプトから呼び出せる?説明
public✅ 呼び出せる他のスクリプトからアクセス可能
private❌ 呼び出せない同じスクリプト内でのみ使用可能
protected❌(継承時は可)継承したスクリプト内でのみ使用可能

例えば、以下のようにJump関数をprivateにしてしまうと、他のスクリプトから実行できません。

public class Player : MonoBehaviour
{
private void Jump()
{
Debug.Log("ジャンプ!");
}
}

この状態でGameManagerから呼び出そうとするとエラーになります。
他のスクリプトから呼び出したい関数はpublicにすること!


スクリプトを取得する方法

では、具体的にPlayerスクリプトのJump関数を呼び出す方法を見ていきましょう。基本的な方法は以下の3つです。

  1. GetComponentを使う方法(同じオブジェクト内)
  2. FindObjectOfTypeを使う方法(シーン内のオブジェクトを探す)
  3. SerializeFieldを使って直接指定する方法(Inspectorで設定)

次のステップでは、それぞれの方法について詳しく解説していきます!




3. GetComponentを使った関数の実行(基本編)

Unityで他のスクリプトの関数を実行する一番基本的な方法が GetComponent<T>() を使う方法です。
これは 同じGameObjectにアタッチされたスクリプトを取得 するのに最適なやり方です。


🔹 GetComponent<T>()とは?

GetComponent<T>() は、特定の コンポーネント(スクリプト)を取得するためのメソッド です。
例えば、Player というスクリプトがアタッチされている場合、別のスクリプトから Player を取得して、その関数を実行することができます。


🔹 実際にやってみよう!

まずは、プレイヤーのジャンプ処理を持つ Player スクリプトを作成します。

1️⃣ Player.cs(ジャンプするスクリプト)

using UnityEngine;

public class Player : MonoBehaviour
{
public void Jump()
{
Debug.Log("ジャンプ!");
}
}

この Jump() 関数を別のスクリプトから呼び出してみましょう!


2️⃣ GameManager.cs(別のスクリプトから関数を実行)

using UnityEngine;

public class GameManager : MonoBehaviour
{
private void Start()
{
// Player スクリプトを取得
Player player = GetComponent<Player>();

// Player の Jump 関数を実行
player.Jump();
}
}

このコードを実行すると、コンソールに 「ジャンプ!」 と表示されます。


🔹 GetComponentの重要なポイント

同じGameObjectにアタッチされているスクリプトしか取得できない!
上記の例では、PlayerGameManager同じGameObject にアタッチされている必要があります。
もし 別のGameObjectにあるスクリプトを取得したい場合 は、後述する FindObjectOfTypeSerializeField を使う方法を試しましょう。

GetComponent<T>() は Start や Awake で実行するのが一般的!
スクリプトが有効になるタイミングでスクリプトを取得することで、安全にアクセスできます。


🔹 GetComponentでエラーが出る場合

もし、NullReferenceException(ヌル参照エラー)が出る場合は、以下の点をチェックしましょう。

🔸 スクリプトが正しくアタッチされているか?
GameObject に Player スクリプトが アタッチされていない 場合、GetComponent<Player>()null になります。
対処法: Unityの InspectorPlayer スクリプトがしっかりついているか確認!

🔸 別のGameObjectのスクリプトを取得しようとしていないか?
GetComponent<T>()同じGameObject にアタッチされているスクリプトのみ取得できます。
対処法: 別のGameObjectのスクリプトを取得したい場合は FindObjectOfType<T>() を使う方法を試そう!


🔹 まとめ

  • GetComponent<T>() を使うと、同じGameObject内のスクリプト を取得できる
  • public な関数なら、取得したスクリプトから関数を呼び出せる
  • GetComponent<T>() を使うには、スクリプトが正しくアタッチされているか確認が必要
  • 別のGameObjectのスクリプトを取得する場合は、FindObjectOfType<T>() などの方法を使おう

GetComponent<T>() は Unity の基本機能なので、しっかり理解しておくとスムーズに開発できるようになります!次は FindObjectOfType<T>() を使って、異なるGameObjectのスクリプトを取得する方法 を解説していきます! 🚀




4. FindObjectOfTypeを使った関数の実行(応用編)

異なるGameObjectにあるスクリプトを呼び出したい場合

UnityのGetComponentは、基本的に同じGameObjectにアタッチされたスクリプトを取得するためのものですが、
別のGameObjectにあるスクリプトを実行したい場合には使えません。
では、異なるオブジェクトにあるスクリプトの関数を実行したいときはどうすればいいのでしょうか?
そこで使えるのが FindObjectOfType<T>() です!

このメソッドを使うと、シーン内の指定したスクリプトを持つオブジェクトを検索し、そのスクリプトを取得できます。
例えば、Playerスクリプトがプレイヤーキャラのオブジェクトにアタッチされている場合、
どこからでもこのスクリプトを取得し、関数を実行することができます。


実装例

では、実際にFindObjectOfTypeを使って、別のスクリプトの関数を呼び出してみましょう。

Playerスクリプト(関数を呼び出される側)

using UnityEngine;

public class Player : MonoBehaviour
{
public void Jump()
{
Debug.Log("プレイヤーがジャンプしました!");
}
}

Playerスクリプトには、Jumpという関数があり、この関数を別のスクリプトから呼び出します。


GameManagerスクリプト(関数を呼び出す側)

using UnityEngine;

public class GameManager : MonoBehaviour
{
private void Start()
{
// シーン内のPlayerスクリプトを持つオブジェクトを探す
Player player = FindObjectOfType<Player>();

// 見つかった場合のみ関数を実行
if (player != null)
{
player.Jump();
}
else
{
Debug.LogError("Playerオブジェクトが見つかりません!");
}
}
}

このスクリプトをGameManagerオブジェクトにアタッチしておくと、
シーン内に存在するPlayerスクリプトが自動で検索され、そのJump()関数が実行されます。


注意点

FindObjectOfTypeは処理が重いので頻繁に使わない FindObjectOfType<T>()は、シーン内のすべてのオブジェクトを検索するため、
頻繁に呼び出すとゲームのパフォーマンスが低下する可能性があります。
特にUpdate()内で毎フレーム実行すると、無駄な処理が増えるので注意しましょう。

nullチェックを忘れずに! 検索しても対象のスクリプトが見つからなかった場合、FindObjectOfType<T>()nullを返します。
そのまま関数を実行しようとするとエラーが発生するので、if文でnullチェックをしてから実行するのが安全です。

③ シーン内に複数のオブジェクトがある場合は、最初に見つかったものだけ取得 FindObjectOfType<T>()は、シーン内で最初に見つかった1つのオブジェクトしか取得しません。
もし複数のオブジェクトの関数を実行したい場合は、FindObjectsOfType<T>()を使うとすべてのオブジェクトを取得できます。


まとめ

  • FindObjectOfType<T>()を使うと、異なるGameObjectにあるスクリプトの関数を実行できる!
  • ただし、処理が重いので頻繁な使用は避けるべき。
  • nullチェックを忘れずにして、エラーを防ぐ。
  • シーン内に複数のオブジェクトがある場合は、最初に見つかった1つのオブジェクトしか取得されないので注意!

次のステップとして、より効率的な方法でスクリプトを参照するSerializeFieldの活用方法を学んでみましょう!




5. SerializeField や public を使って参照する方法

他のスクリプトの関数を実行する方法として、SerializeFieldpublic 変数を使って直接スクリプトを参照するやり方もあります。この方法は、事前にInspector(インスペクター)でオブジェクトを紐づけるため、安全で効率的です。


🟢 Inspectorでスクリプトを紐付ける方法

この方法では、事前にスクリプトがアタッチされたオブジェクトをInspector上で設定するため、ゲームの起動時にスクリプトを探す処理が不要になります。FindObjectOfType よりもパフォーマンスが良く、エラーが発生しにくいのが特徴です。


💡 実装例

まず、プレイヤーのスクリプト(Player.cs)を作成します。

🔹 Player.cs(関数を持つスクリプト)

using UnityEngine;

public class Player : MonoBehaviour
{
public void Jump()
{
Debug.Log("プレイヤーがジャンプしました!");
}
}

この Jump() 関数を GameManager スクリプトから呼び出してみましょう。

🔹 GameManager.cs(関数を呼び出すスクリプト)

using UnityEngine;

public class GameManager : MonoBehaviour
{
[SerializeField] private Player player; // PlayerスクリプトをInspectorでセットする

private void Start()
{
player.Jump(); // PlayerスクリプトのJump()関数を実行
}
}

🛠 やり方(手順)

  1. スクリプトの作成
    • Player.csGameManager.cs を作成する(上記のコードを使用)
  2. オブジェクトの準備
    • Hierarchy(ヒエラルキー)ウィンドウPlayer オブジェクトを作成
    • Player.csPlayer オブジェクトにアタッチ
  3. GameManagerをセット
    • 新しいGameObject(例: GameManager)を作成
    • GameManager.csGameManager オブジェクトにアタッチ
  4. Inspectorで紐付け
    • GameManager オブジェクトを選択
    • Inspectorの player 欄に Player オブジェクトをドラッグ&ドロップ
  5. 実行して動作確認
    • GameManagerStart() が実行され、 PlayerJump() が呼び出される
    • Consoleに プレイヤーがジャンプしました! と表示される

🔹 public を使った場合

SerializeField ではなく、public を使う方法もあります。

public class GameManager : MonoBehaviour
{
public Player player; // publicにすることでInspectorで参照可能

private void Start()
{
player.Jump();
}
}

違いとして、public の場合は他のスクリプトからも自由にアクセスできるため、予期しない変更が発生するリスクがあります。基本的には SerializeField を使うのがおすすめ!


🎯 この方法のメリットとデメリット

方法メリットデメリット
SerializeField・Inspectorで設定しやすい
・スクリプトの変更が制限されて安全
・Inspectorで手動設定が必要
public・外部スクリプトからアクセス可能・意図しない変更が起こるリスクがある

🔹 まとめ

  • SerializeField を使えば Inspectorでスクリプトを紐づける ことで簡単に関数を呼び出せる!
  • public も使えるが、安全性の面では SerializeField のほうが推奨される
  • FindObjectOfType よりもパフォーマンスが良く、エラーも起こりにくい ので、積極的に活用しよう!

この方法を使えば、スクリプト同士の関数呼び出しがシンプルになり、管理もしやすくなります。Unity開発では非常に便利なテクニックなので、ぜひ試してみてください!🚀




6. まとめ

Unityで他のスクリプトの関数を実行する方法はいくつかあります。それぞれの特徴を理解し、適切な方法を選ぶことが大切です。

GetComponent(同じオブジェクト内のスクリプト)

  • メリット:処理がシンプルで分かりやすい
  • デメリット:同じGameObject内のスクリプトしか取得できない
  • おすすめの使い方:同じGameObject内にあるスクリプトの関数を呼び出すとき

FindObjectOfType(シーン内のスクリプトを検索)

  • メリット:異なるGameObjectにあるスクリプトを取得できる
  • デメリット:毎回検索するため、処理が重くなる可能性がある
  • おすすめの使い方:スクリプトが1つしかない場合や、頻繁に呼び出さない場合

SerializeFieldpublic で直接参照

  • メリット:Inspectorで事前に設定でき、パフォーマンスが良い
  • デメリット:事前に手動でセットしないとエラーが出る可能性がある
  • おすすめの使い方:特定のオブジェクトのスクリプトを確実に参照したい場合

どの方法を使うかは、「呼び出したいスクリプトがどこにあるか」で決まります。
特にFindObjectOfTypeは使いすぎると処理が重くなる
ので、SerializeFieldを使ってInspectorで指定するのが理想的です。

スクリプト間の連携をしっかり理解すれば、よりスムーズな開発ができます。ぜひ今回の知識を活かして、自分のプロジェクトでも試してみてください!




よくある質問(FAQ)

Q
NullReferenceExceptionが出るのはなぜ?
A

GetComponentFindObjectOfTypeでスクリプトが正しく取得できていない可能性があります。スクリプトがアタッチされているか確認してください。

Q
FindObjectOfTypeを使うと動作が遅くなる?
A

FindObjectOfTypeはシーン内のオブジェクトを検索するため、頻繁に実行するとパフォーマンスに影響します。SerializeFieldを使うのがベター。

Q
別のスクリプトの関数を実行できるけど、パラメータを渡すには?
A

public void Jump(float height) のように引数を追加し、呼び出す際に player.Jump(3.0f); とすればOK!

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