クラス
C#の純粋クラス vs MonoBehaviour
お気づきかもしれないが、通常のC#クラスとUnityの「MonoBehaviour」クラスにはいくつかの違いがある。基本的に、どちらのクラスもプロパティ(クラス変数)とメソッドを持てる。しかし、大きな違いもある。
- 通常のC#クラスはUnityエディターでは使用できない。GameObjectにアタッチできるのは
MonoBehaviourのみである。 - 通常のC#クラスは
newキーワードを使ってインスタンス化するが、MonoBehaviourは直接インスタンス化できない。
| 通常のC#クラス | MonoBehaviour |
|
一般 C# のものであり、Unity 以外でも使える |
Unity専用のキーワードである(Unity以外に使えない) |
|
「
|
「
|
|
|
|
|
UnityでGameObjectにアタッチ不可
|
UnityでGameObjectにアタッチ可能
|
どれを使う?
では、どちらをいつ使うべきか?基本的な目安として、GameObjectに機能を追加したい場合はMonoBehaviourを使う。例えば、プレイヤーの入力に基づいてGameObjectを制御したい場合や、画面上のスコアを更新したい場合は、その処理に専念するMonoBehaviourを作ればよい。
ゲーム内で通常表示されない内部処理にはC#クラスを使うパターンはよくある。例えば、プレイヤーのインベントリを管理するC#クラスや、ファイルのセーブ・ロードを制御するC#クラスを作ることができる。
アクセス修飾子
基本的な目安として、データを保護しクラスの外部から誤って値を変更しないよう、クラスのメンバー変数は常に「private」に設定する。
クラスの外部から値にアクセスする必要がある場合は、publicメソッドまたはpublicゲッター(下記の例を参照)を使うことができる。
MonoBehaviourの場合、Unityがエディターで変数を変更できるようにする必要がある。これは変数をprivateのままにし、変数に[SerializeField]を追加することで実現できる。
- やりたいこと:Unityにある数値を公開し、エディター(Inspector)で編集できるようにしたい 例:車の速度
| NG | 正しい方法 |
|
上記の例と同様に、Unityに限らず、どこからも編集できる変数なので、大変危ない!
|
|
- やりたいこと:ある数値を別のクラスで読みたい。
例:プレーヤーを持っているお金
| NG | 正しい方法 |
|
public(公開)にすると、Player以外からアクセスでき、誤って数値を消したり可能性があるので、「public」を避けよう。
|
1.まず、メンバー変数を非公開にし(
2.もう少し賢い方法は、「ゲッター」を使うこと:
|
- やりたいこと:ある数値を別のクラスで更新した。
例:プレーヤーの体力。
| NG | 正しい方法 |
|
この場合は、攻撃や回復アイテムで現在の体力の数値を別のクラスから変えたい場合もあると思い、「public」にした。
ただ、ここは大きなお落とし穴がある。次の例を考えてください: ・最大耐力 ・現在の体力 ・回復アイテムを使用し、+100を回復
とすると、
同様に 80 の攻撃を受け取るとしたら: マイナス体力になってしまった! |
1.まず、メンバー変数を非公開にし(
これで、SetHPでは、体力が必ず
2.もう少し賢い方法は、「ゲッター」と「セッター」を使うこと:
|
練習課題
単純なインベントリを作成してみましょう:
やりたいこと:ある数値を別のクラスで更新した。例:プレーヤーの体力。アイテムを表すクラスを作る(ファイル名:Item)- アイテム名を代入と取得できるようにする
C#の純粋クラス
Item coin = new Item();
coin.Name = "コイン";
coin.Count = 20;
答え
// 何かのアイテムを表すクラス
class Item
{
// アイテム名(非公開)
private string name;
// アイテムの数(非公開)
private int count;
// アイテム名(公開)
public string Name {
get { return name }
set { name = value; }
}
// アイテムの数(公開)
public string Count {
get { return count }
// マイナスアイテムは無意味なので、必ず0以上にする
set { name = Mathf.Max(0, count); }
}
}
Inventory」クラスを作成(ファイル名:Inventory)
Inventory inv = new Inventory();
inv.Add(coin); // 先作ったコインを追加
inv.Print(); // Debug.Logで中身を表示する:「コイン:20」
答え
// アイテムを管理する
class Inventory
{
// アイテムのリスト
private List<Item> items = new List<Item>();
// 追加メソッド
public void Add(Item item)
{
items.Add(item);
}
// 表示メソッド
public void Print()
{
foreach(Item i in items)
{
Debug.Log($"{i.Name} : {i.Count}");
}
}
}
RunTest)
答え
// 確認用のスクリプト
class RunTest : MonoBehaviour

