小規模なゲーム(個人制作の同人ゲーム)でも数千行以上のスクリプトを書く必要があり、誰でも知っているようなタイトルではそれ以上のスクリプトが必要となり数万行は超えてきます。
Unityだけではなく、1つのスクリプトで1万行もコードを書くと見づらくなりかえって複雑になってしまいます。そこで、複数のスクリプトを用意し関数を呼び出してゲームを完成させます。
例えば、RPGにてキャラクターを移動させるときの関数。敵を倒してスコアを加算する時の関数。セーブする関数などこれらを別のスクリプトの関数として必要な時にだけ呼び出します。
このように2つ以上のスクリプトをつくって他のスクリプトで定義した変数や関数を呼び起こす場面は開発中に何度もあります。
また、別のスクリプトから変数をアクセス(使う)場合はstatic(静的)にする必要がありますが、static変数はゲームを終了して再開しても値を保持できないことやクラス間の依存関係の増加など致命的な問題があります。
したがって、本記事ではstaticを使わずに、別スクリプトの関数を呼び起こす方法を紹介します。
- 他のスクリプトの関数を呼び出したい。
- 他のスクリプトの変数を取得したい。
- static以外で変数にアクセスしたい。
- 「GetComponent<>();」の使い方を知りたい。
参照先のスクリプトを取得する方法
参照先のスクリプトを取得するには「同じGameObjectにアタッチされている」、あるいは「別のGameObjectアタッチされている」2つの場合でコード記述が異なります。
GameObjectとは、名前の通りゲームの物体を意味しHierarchyウィンドウで追加や削除など扱います。通常スクリプトはこのGameオブジェクトにアタッチして実行させます。
アタッチする方法は、Inspectorウィンドウの最下部「Add Component」から追加、あるいはドラッグ&ドロップで追加する方法があります。
一方でGetComponentは、Unityでゲームオブジェクトにアタッチされたコンポーネントを取得するためのメソッドです。取得には、次の通りに書きます。
GetComponent<コンポーネントの型>()
同じGameObjectにアタッチされている場合
初めに、同じGameObjectにアタッチされている別スクリプト(SampleA.csとSampleB.cs)のコード例を紹介します。
左クリックすると、iが加算されるコードです。
SampleA.csがSampleB.csを参照します。
- SampleA.cs (呼び出す側)
SampleB plus = GetComponent<SampleB>();
void Update()
{
if (Input.GetMouseButtonDown(0)) // マウスの左ボタンが押された場合
{
plus.Increment();
Debug.Log(plus.i);
}
}
- SampleB.cs (呼び出される側)
void Increment(){
i++;
}
異なるGameObjectにアタッチされている場合
アタッチするGameObjectはどれにしても同じというわけではないです。
例えば、敵キャラを倒すと加算されるスコアが異なる。HPが違うというようにステータスを変える場合は、それぞれの敵オブジェクトにスクリプトをアタッチしなければいけません。
// "Enemy"という名前のGameObjectにアタッチされていると仮定
GameObject obj = GameObject.Find("Enemy");
SampleB plus = obj.GetComponent<SampleB>();
void Update()
{
if (Input.GetMouseButtonDown(0)) // マウスの左ボタンが押された場合
{
plus.Increment();
Debug.Log(plus.i);
}
}
同じGameobjectと異なることは、「GameObject.Find(“オブジェクト名”)」を記述してGameObjectを探してGetComponentします。
番外:インスペクターで紐づけ
GetComponentを使わないInspectorで紐づけもできます。これは「関数も変数もpublic」にしてオープン状態にしておきます。
- SampleA.cs (呼び出す側)
public SampleB plus;
void Update()
{
if (Input.GetMouseButtonDown(0)) // マウスの左ボタンが押された場合
{
plus.Increment();
Debug.Log(plus.i);
}
}
- SampleB.cs (呼び出される側)
public int i =0;
public void Increment(){
i++;
}
GetCompornentを使わずに他のスクリプトを呼び出すことができますが、必ずInspectorでセットする必要があります。未設定だとNullReferenceExceptionが出てきてしまいます。
GetComponentで別スクリプトの関数を呼び起こす方法

それでは、別のスクリプトから関数を呼び出す方法を解説します。
今回はスクリプト「ScriptA.cs」「ScriptB.cs」の2つを使います。
「ScriptB.cs」にて、スペースキーを押すと、「ScriptA.cs」の関数で変数を加算するコードです。
関連記事:「【Unity】UIボタンを押すごとに数字を増やし、クリックした回数をカウントをする」
ソースコード
関数を渡す側
using UnityEngine;
public class ScriptA : MonoBehaviour
{
int Count;
public void MethodA()
{
Count++;
Debug.Log(Count);
}
}
関数を受け取る側
using UnityEngine;
public class ScriptB : MonoBehaviour
{
private ScriptA scriptA;
private void Start()
{
scriptA = GetComponent<ScriptA>();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Spaceキーが入力されました");
scriptA.MethodA();
}
}
}
UdemyでUnityを学習
Udemyは、オンデマンド式の学習講座です。
趣味から実務まで使えるおすすめの講座を紹介します。
- 【Unity C# ゲーム開発超入門】7つのミニゲームを作っておぼえる!UnityとC#講座
Unityで頻出の機能を実際のゲーム作りで学習。
何か作りたい、今後の開発で役立てたい初心者におすすめ
- 【Unity C# ゲーム開発初心者レベルアップ】7つのトランプゲームを作っておぼえる!UnityとC#講座
トランプやボードゲーム作りに特化している講座。
テーブルゲームを作りたい人におすすめ。
- 【全行程を網羅!最初に学びたい総合学習】Unityワールド制作講座
Unityワールド制作の全工程を学習できる講座。
RPGを作りたい人におすすめ。
- Unity ゲーム開発:インディーゲームクリエイターが教える C#の基礎からゲームリリースまで【スタジオしまづ】
C#の文法やApp StoreとGoogle Playへゲームをリリース方法を解説。
ゲームを出品したい人におすすめ。
解説
初めに、「ScriptA」を解説します。
「Count」はint型変数で、関数「MethodA()」内で「Count」を1ずつ加算します。
int Count;
public void MethodA()
{
Count++;
Debug.Log(Count);
}
つづいて、「ScriptB」を解説します。
scriptAは、クラス「ScriptA」のprivateなインスタンス変数です。
クラス「ScriptA」の新しいインスタンスを作成して、変数「scriptA」に格納します。
よって、別のスクリプト(ScriptB)からScriptAクラスで定義されたメンバー変数、メソッド、プロパティにアクセスすることができます。
private ScriptA scriptA;
また、Start()内で、privateな変数「scriptA」にGetComponentメソッドを使用して、スクリプトで定義されたメソッドや変数にアクセスします。
scriptA = GetComponent<ScriptA>();
最後にUpdate()内で、スペースキーを押すと、スクリプト「ScriptA」内の関数MethodA()を実行させます。
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("Spaceキーが入力されました");
scriptA.MethodA();
}
実演
完成した2つのスクリプトをHierarchyウィンドウにアタッチしてください。
再生ボタンを押して、スペースキーを押すと以下のようになります。

まとめ
今回は、staticを使わず、別スクリプトの関数を呼び起こす方法を紹介しました。
関数を呼び起こすためには、「GetComponent()」を使い、呼び起こしたい関数があるクラスの新しいインスタンスを作成して、privateな変数を定義します。
privateな変数を用意することで、そのスクリプト内のみで変数が有効になるので、別のスクリプトからの干渉を受ける心配はなくなります。