【UnityでC#】インスタンスを使ってゲームの物体を捕えよう！

# はじめに

　こんにちは。昨今の世の中には無数のゲームがリリースされています。
　「そんなに簡単に作れるものなの？」
　そう思うかもしれませんが、有名どころのゲームはそんなことはなく何百人月とか余裕でかかっていたりします。私もPythonでドット絵のファイアーエ〇ブレムもどきのゲーム製作でさえも50時間くらいかかりました。また、Unreal Engineというゲームエンジンで優秀なる先人のアセットに頼って見た目だけはよい簡易的な宝探しゲームも50時間くらい製作時間を要しました。そのくらいの覚悟は必要です。
　ただ、すごく楽しいです。
　ゲームはプレイすること自体がすごく楽しいですが、あれを作れるということ、どんなゲームを作って、どのような構成でどのような機能を加えるか、動いた時の感動など計り知れないです。もちろん、向き不向きはあると思いますが数学が得意な人なら夢中になれそうです。（多分）
　
　「今まで、PythonやUnreal Engineでゲームを作っていたのになんでUnityでゲーム作っているの？やることコロコロ変えすぎでしょ？」

　そう言われても仕方ありません。ですが、今ゲーム市場で一番需要が高いのはUnityです。Unityはスマホゲームを作ることができC#で作ることができます。Pythonは高級言語なのでなれのために始め、Unreal Engineはコンシューマーゲーム向けなので使っていました。ただ、Unreal Engineはハイエンドゲームということもありかなりの実力がないとゲーム市場に乗ることはできません。よって、Unityを選んでいます。

　前置きが長くなりましたが、Unityのインスタンスを使ってゲームの物体を操作したいと思います。前提としてUnityはインストールしていて基本的な操作ができている、C#は配列変数、オブジェクト指向もある程度理解している方向けとなります。

# インスタンスとは
　オブジェクト指向があいまいな方もいると思うので始めに説明しておきます。
　インスタンスというのは **「実体」** にあたるもので、class（設計図）をもとにしてインスタンス（実体）を作成し、様々な実体を扱うことによってゲームは構成されます。**実体になるということはメモリに乗る**ということです。
　ところで、実体になっただけでは「そこにあるだけ」ですので、プログラムから制御したり、操作したいときには実体にアクセスしなければいけません。
　インスタンスにアクセスするために、インスタンスを”捕まえる”必要があります。このように実体を捕えて使用できるようにすることを「インスタンスを取得する」といいます。今回は自分でclassのインスタンスを取得したいと思います。

# \<GetComponent\>
　まずは、UnityでヒエラルキーウィンドウよりCubeを作成してください。
　今現在、同じゲームオブジェクト内にくっついているコンポーネントでBox Coliderというものがあると思いますが、これを捕まえてみようと思います。
　以下のように書いてください。

```C#:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        BoxCollider box = null;
        Debug.Log(box);
        box = GetComponent<BoxCollider>();
        Debug.Log(box);
    }

    // Update is called once per frame
    void Update()
    {
    
    }
}
```
```C#:
BoxCollider box = null;
```
でBoxCollider型の変数boxを定義しています。コンポーネントと同じ名前なのでわかりやすいですね。コンポーネントはclassでもあるので、型として定義することができます。そして**null**というものを代入しています。これは何かというと「何もない」という意味です。変数を箱と例えると、この場合カラとも言えます。そして、Debug.Logでboxの中身を表示させています。
```C#:
box = GetComponent<BoxCollider>();
```
　これはゲームオブジェクトについているコンポーネントを取得する命令です。このスクリプトがくっついているゲームオブジェクトのコンポーネントを取得することができます。
　この命令はMonoBehaviourを継承しているため使えます。\<\>の中に取得したいコンポーネントの型を指定します。
```Unity:コンソール実行結果
[07:52:54]Null
UnityEngine.Debug:Log (object)
[07:52:54]Cube (UnityEngine.BoxCollider)
UnityEngine.Debug:Log (object)
```
　最初Nullで何も入っていなかったのが、GetComponentで中身が入っていることがわかります。これでboxの中にインスタンスを入れることができたのでboxからBoxColliderのコンポーネントにアクセスすることができます。

# \<GameObject.Find\>
　上の例ではスクリプトを貼り付けたゲームオブジェクトのコンポーネントのインスタントしかとってこれませんでしたちなみにインスタンスは実体であるので、何もコンポーネントだけがインスタンスを持つわけではありません。ゲームオブジェクトにも実体（インスタンス）があります。ではほかのゲームオブジェクトのインスタンスも取得してみましょう。以下のように書いてみてください。
```C#:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        GameObject g = null;
        Debug.Log(g);
        g = GameObject.Find("Directional Light");
        Debug.Log(g);
    }

    // Update is called once per frame
    void Update()
    {
    
    }
}
```
　削除していなければシーン上にDirectional Lightというゲームオブジェクトがいると思うのでそれを捕まえてみます。GetComponentの時と同じように空の変数を用意します。GameObjectとなっていますね。ゲームオブジェクトもclassから実体化されているので型として持つことができます。そして
```C#:
g = GameObject.Find(ゲームオブジェクトの名前);
```
で指定した名前のゲームオブジェクトのインスタンスを取得することができます。
```Unity:コンソール実行結果
[07:52:54]Null
UnityEngine.Debug:Log (object)
[07:52:54]Directional Light (UnityEngine.GameObject)
UnityEngine.Debug:Log (object)
```
上のようにちゃんと変数の中に入っているのがわかります。ちなみに、DirectionalLightという風にスペースを入れないと失敗します。名前での指定の際はスペースまでちゃんと合わせましょう。


# 最後に
　普段、C#を書いている方も今回の内容は知らなかったかも多いのではなかったでしょうか。UnityのC#になるとUnity独自の機能があるからです。ソースコードの頭にusing UnityEngine;の箇所がありますがあれがUnity独自の機能を使えるようにしているのです。しかし、C#の基礎がわかっているからこそ理解できるものなのでもし、C#勉強していないけどこの記事を読んでいた場合はC#の基礎から勉強することをお勧めします。
　
　
##### 【投稿者】
エンジニアファーストの会社 [株式会社CRE-CO](https://www.cre-co.jp/#top)　田渕浩之

##### 【参考文献】
[→Unity入門【初心者為の使い方講座】【実際にゲームを作って解説】](https://dkrevel.com/makegame-beginner/)