UnityC# クラスとインスタンスの作り方・コンストラクタの使い方

クラスについての画像 Unity C#入門講座
クラスは変数やメソッドなど関連性があるものをまとめたものになる。


Unityの本格ゲーム制作講座はこちら
【30日間の全額返金保証付き】

今回の記事ではクラスについて解説していきます。

クラスについては複数回に分けて解説します。今回はクラスとインスタンスの基本的な使い方について解説します。

ちなみに構造体(struct)も大体クラスと同じものになり、ここで解説する用法は構造体でも使えます。

前回の記事:

Unity C#での列挙型と定数の使い方
今回の記事では列挙型と定数について解説していきます。 列挙型を使うとスクリプト上で定数をテキストとして表現でき、より読みやすく設定しやすいコードを書くことができます。 前回の記事: 列挙型(enum)とは 列挙型は値型になり、S...

【Unity入門の森の最新ゲーム開発講座もお届け】

クラスとは

クラスは変数やメソッドなど関連性のある機能をまとめたものになります。

C#はクラスを組み合わせてプログラムを作成していくオブジェクト指向型プログラミング言語になります。

クラスの中で宣言されたものをメンバと呼びます。変数ならメンバ変数、メソッドならメンバメソッドと呼ばれたりします。クラスの中で宣言された変数はフィールド(Field)と呼ばれます。

次のものはクラスの定義の書き方になります。メンバ宣言にはpublicなどアクセス修飾子をつけることができますがこれについての詳細はこれ以降の記事で解説します。

class <クラス名> { <メンバ宣言>... }

クラスとインスタンスの違い

クラスとインスタンスの違いの画像

インスタンスはクラス定義からnew演算子を使って作成される値になる。

クラスを定義しただけではあまり意味はありません。クラスを利用する際にはインスタンスを作成する必要があります。

それぞれの役割を例えると、クラスは設計図になり、インスタンスは設計図をもとに作成された生成物になります。

インスタンスを作成するときはnew演算子を使用します。書き方は以下の様に先にnewを書いてからクラス名を続けます。クラス名の後にはコンストラクタ(※)への引数を書きます。

(※コンストラクタについてはこの後に解説します。)

new <クラス名>(<引数>...)

一度作成したインスタンスにはクラス定義にあるメンバが存在しています。それらメンバを使用したい、アクセスしたいときは.演算子を使用してください

<インスタンス> . <メンバ>

クラスは参照型になります。インスタンスがオブジェクトの属するメンバであるのに対し、クラスのメンバ変数はクラスに属しています。

インスタンスメンバはインスタンスそれぞれが独立した実体(値)を持ちますが、クラスメンバ変数はクラスで一つしか存在できません。全てのインスタンスでそのメンバ変数が共有されます。

コンストラクタについて

コンストラクタについての画像

コンストラクタはnew演算子と一緒に呼び出されるメソッドになる。複数個定義できる。

インスタンスを作成する時には必ずコンストラクタが呼び出されます。コンストラクタはインスタンスの初期化を行う特殊なメソッドになります。

書き方はメソッドと似ており、戻り値を省略したものになります

<コンストラクタ名>(<引数>...) { <処理> ... }

また、コンストラクタはクラスの中に複数定義できます。その際は引数が異なるようにコンストラクタを定義してください。

さらにコンストラクタを実行する前に他のコンストラクタを一つだけ実行することもできます。そのためコンストラクタで行う処理を共通化することが可能になります。

他のコンストラクタを呼び出したいときは以下のように引数と鉤括弧の間に: this(<引数>)と書いてください。

上記コードのpublic A() : this(10) は同じクラス内で別のコンストラクタを実行し、引数として10を与えよという意味になります。

このコードの場合、引数なしでクラスAを呼び出した場合、引数10を与えた初期化コードとして処理されるわけですね。

コンストラクタの注意点

もし、コンストラクタを定義しなかった場合はC#側で自動的に引数なしのコンストラクタが定義されます。

またそれに合わせて注意点として、コンストラクタを一つ以上定義した場合には引数なしのコンストラクタは自動生成されませんそのためインスタンスを作成するときは必ず定義したコンストラクタのいずれかの引数と一致するように値を渡す必要があります。

静的なコンストラクタ

コンストラクタにはstaticキーワードをつけた静的コンストラクタというものが存在します。

静的コンストラクタはこれを定義したクラスが初めて使われるタイミングで自動的に実行されます。主な用途として静的メンバ(※)の初期化などに使われます。

使う場合は

  • static修飾子を付けること
  • 他の修飾子は付けられない
  • 引数も指定できない(のちの記事で出てくるオーバーロードもできない)

という特徴を持ちます。

(※静的メンバはプログラムのどこからでもアクセスできるメンバのことです。詳しくは他の記事で解説します。)

privateなコンストラクタ

privateなコンストラクタとはコンストラクタにprivateというアクセス修飾子(※)をつけたものになります。

このコンストラクタは同じクラスの中からしか呼び出すことができないと指定したコンストラクタになります。そのため、他のクラスの中からインスタンスを作成しようとしてもコンパイルエラーになります。

一見意味のない機能に見えますが以下の用途があります。

  • 静的メンバのみを持つクラスのインスタンスを生成させないようにする

(※アクセス修飾子についてはこれ以降の記事で解説します。)

【実践】Unityでクラスを実際に定義してみよう!

それでは実際にUnityでクラスを定義してみましょう!

これまで何回も書いてきましたがコンポーネントもクラスになるので既にクラス定義については経験済みです。

ただコンポーネントではコンストラクタは必要ではないので、今回のサンプルではコンストラクタ付きクラスをコンポーネントの中に定義して使ってみましょう!

ちなみにクラスの中に定義されたクラスを子クラスなどと呼んだりします。

サンプルコード1の画像

再生前にSpeedに設定した値でGameObjectが左右に移動する。Start()の中でdataメンバにSpeedの値を渡しているので、再生後にSpeedの値を変更しても速さは変わらない。

上のサンプルコードではSampleコンポーネントの中でDataというクラスを定義しています。Start()メソッドの中でDataクラスのインスタンスを作成し、Update()メソッドの中で作成したインスタンスからGetMove()メソッドを呼び出しGameObjectを移動させています。

Start()メソッド内でDataクラスのコンストラクタの引数にInspectorから設定した値を渡しています。そのため、再生後にSpeedの値を変更してもGameObjectの移動速度は変わりません。

上のサンプルコードではコンストラクタを使用したかったため、少々周りくどい手順を踏んでいますが、実はクラスのメンバもInspector上から設定することができます。

クラスのメンバをInspectorから設定できる様にする方法

上のサンプルコードで定義したクラスのメンバをInspector上から設定できる様にするときは以下の様に書いてください。

  • クラス定義の際にSystem.SerializableAttributeを指定すること。

System.SerializableAttributeを指定するとそのクラスがコンポーネントのメンバにある場合Unityエディタが自動的にInspectorから設定できる様にしてくれます。

System.SerializableAttributeを指定しておけば、そのクラスに関してはクラス型のメンバが入れ子で定義されていてもその全てInspector上から設定することができます(※)。

(※クラス定義によっては無限に入れ子を作ることができますが、入れ子の上限は存在しています。)

また、コンストラクタ自体もUnity側から呼び出されるため、わざわざStart()メソッドの中でインスタンス生成する必要はなくなりますので、削除しています。

また、Inspectorから直接Dataクラスのメンバを変更しているのでこちらは再生後にSpeedの値を変更するとGameObjectの移動速度に反映されます。

サンプルコード2Inspectorの画像

クラス定義にSystem.SerializableAttributeを指定するとInspectorから設定できる様になる。こちらのサンプルでは直接Dataクラスのメンバを変更しているので再生後でもGameObjectの移動速度に反映される。

まとめ

今回の記事をまとめると以下になります。

  • クラスは関連する変数、メソッドなどをまとめたもの。
  • コンポーネントもクラスである。
  • インスタンスはクラス定義から作成されたもの。
  • new演算子を使ってインスタンスを作成する。
  • インスタンス作成の時にはコンストラクタという特殊なメソッドが自動的に呼び出される。
  • コンストラクタは他のコンストラクタの処理を一つだけ先に実行することができる。
  • 何もコンストラクタを定義しなかった場合は引数なしのコンストラクタがC#によって作成される。
  • コンストラクタを一つ以上定義した場合はインスタンス生成時に必ず定義したコンストラクタと一致した引数を渡さないといけない。
  • 静的コンストラクタはアプリ実行中一度だけ自動的に呼び出されるコンストラクタ。
  • privateなコンストラクタはそのクラスのインスタンスを生成させないためのコンストラクタ。
  • System.SerializableAttributeをクラスに指定するとInspector上からそのクラスのメンバの値を設定することができる様になる。

それでは次の記事に行ってみましょう!

次回の記事:

UnityC#のフィールド・プロパティ・アクセス修飾子の使い方 スコープの概念を理解する
今回の記事ではクラスのメンバであるフィールドとプロパティをまず解説し、次にアクセス修飾子とスコープについての理解を深めていきます。 ややこしいところですが、頑張っていきましょう! 前回の記事: クラスにフィールドとプロパティを持た...

初心者向けUnityC#入門講座に戻る>>


【Unity入門の森の最新ゲーム開発講座もお届け】

コメント

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