講義メモ:後半

文法編:オブジェクトの配列

・整数値や文字列の配列と同様に、オブジェクトの配列を生成・利用できる
・p.160 shooter.csの7行目では、Unityが提供するGameObjectクラスを型とする配列prefabsを要素数4で生成している
 public GameObject[] prefabs = new GameObject[4];
・定義と生成の書式: クラス名[] 配列名 = new クラス名[要素数];
・クラスの代わりに構造体なども利用可能だが、扱いが異なるので注意
・クラスは参照型なので、生成されるのは参照であるため、必要に応じてオブジェクトを生成して与える必要がある
 例:for (int i = 0; i < 要素数; i++) { 配列名[i] = new クラス名(…); }
・構造体は値型なので、オブジェクトが同時に生成される(よって非常に要素数が多い場合は負荷が大きくなる)
・クラスに含まれるメンバを配列の要素から用いるには「配列名[添字].メンバ名」とする

演習 ex0810b.cs

・下記のMonsterクラス型の配列を要素数3で生成しよう
    class Monster { //インナークラスMonsterの定義
        public int hp; //Monsterクラスの持つデータ
        public int mp; //同上
        public void show() { //Monsterクラスの持つメソッド
            Debug.Log(hp + ", " + mp);  //2変数の値を出力
        }
    }
・各要素のhp、mpを設定し、showメソッドで表示して確認しよう

作成例

using UnityEngine;
public class ex0810b : MonoBehaviour{
    class Monster { //インナークラスMonsterの定義
        public int hp; //Monsterクラスの持つデータ
        public int mp; //同上
        public void show() { //Monsterクラスの持つメソッド
            Debug.Log(hp + ", " + mp);  //2変数の値を出力
        }
    }
    void Start()    {
        Monster[] mons = new Monster[3]; //Monster型の配列monsを要素数3で生成(参照のみ)
        for (int i = 0; i < mons.Length; i++) { mons[i] = new Monster(); } //オブジェクトを生成して各要素に与える
        mons[0].hp = 10; mons[0].mp = 20; //各要素のメンバ変数に代入
        mons[1].hp = 11; mons[1].mp = 21; //〃
        mons[2].hp = 12; mons[2].mp = 22; //〃 
        foreach (var mon in mons) { //配列monsの全要素について繰返す
            mon.show(); //作業変数monはMonster型なのでMonsterクラスのメソッドを呼べる
        }
    }
}

訂正「※ 以下確認中」としていた件について

・講義内で「C#では「Monster[] mons = new Monster[3];」でMonsterクラス型の配列が3要素で生成される」と説明しましたが、
 これは誤りでした。
・C#でもUnityでも「for (int i = 0; i < mons.Length; i++) { mons[i] = new Monster(); }」を実行して、
 Monster型のオブジェクトを生成して配列monsに与える必要があります。
・なお、Monsterをクラスではなく構造体にすると「Monster[] mons = new Monster[3];」だけでMonster構造体型の配列が
 3要素で生成されるので、例外は発生しません。
・以上に合わせて上記の説明とプログラム、講義メモを訂正しました。

文法編:オブジェクトの配列と継承

・派生クラスのオブジェクトは基本クラスを型とする配列の要素にできる
・ただし、こうすると、派生クラスで追加したデータメンバやメソッドは利用を制限される
 ①基本クラス型の配列の要素としては基本クラスで定義されたメンバのみ
 ②派生クラス型にキャストすると、派生クラスで追加したメンバも利用可能になる
・また、基本クラス型の配列の要素となった派生クラスのオブジェクトは、派生クラスにキャストすることで、派生クラス型の変数に代入できる
・以上により、多くの派生クラスを持つ基本クラスの配列で、派生クラスオブジェクトをまとめて扱うことができる

演習 ex0810c.cs

・下記のSlimeクラス型の要素をMonster型の配列に格納して試してみよう
    class Slime : Monster { //Monsterを継承するクラスSlimeの定義
        public string name;
    }

作成例

using UnityEngine;
public class ex0810c : MonoBehaviour{
    class Monster { //インナークラスMonsterの定義
        public int hp; //Monsterクラスの持つデータ
        public int mp; //同上
        public void show() { //Monsterクラスの持つメソッド
            Debug.Log(hp + ", " + mp);  //2変数の値を出力
        }
    }
    class Slime : Monster { //Monsterを継承するクラスSlimeの定義
        public string name;
    }
    void Start()    {
        Monster veldra = new Monster();
        veldra.hp = 100; veldra.mp = 200; 
        Monster velgri = new Monster();
        velgri.hp = 101; velgri.mp = 201; 
        Slime rimuru = new Slime();
        rimuru.hp = 102; rimuru.mp = 202; rimuru.name = "リムル"; 
        Monster[] mons = {veldra, velgri, rimuru}; //Monster型の配列monsにSlimeオブジェクトも
        foreach (var mon in mons) { //配列monsの全要素について繰返す
            mon.show(); //作業変数monはMonster型なのでMonsterクラスのメソッドを呼べる
        }
        //Debug.Log(mons[2].name); //派生クラスで追加したメンバは使えないが
        Debug.Log(((Slime)mons[2]).name); //キャストすれば「リムル」が得られる
        Slime rimuru_copy = (Slime)mons[2]; //代入も可能
        Debug.Log(rimuru_copy.name); //「リムル」が得られる
    }
}

文法編:オブジェクトの動的な生成

・プログラムの中でクラスや構造体からオブジェクトを動的に生成する場合、基本的にはnew演算子を用いる
・もう一つの方法は、クラスや構造体を戻り値型とするメソッドを呼ぶことで、返されるオブジェクトを、
 クラスや構造体を型とする変数で受け取れば良い
・Unityでは、これに加えてゲームオブジェクトの複製を生成するInstantiateメソッドがMonoBehaviourクラスにあり、
 Unity用のクラスに継承される
・よって、p.163の説明の通り、プレハブ名、位置情報、回転情報を与えて、ゲームオブジェクトの複製と出現を指示できる

ゲーム開発編:p.160 Shooterにプレハブを渡す

・ゲームオブジェクトの配列を生成して用いる

p.162 shooter.cs(途中での改良分を含む)

//p.162 shooter.cs
using UnityEngine;
public class shooter : MonoBehaviour {
    float move = 0.05f; //単精度実数型のフィールド変数moveの初期化
    public GameObject[] prefabs = new GameObject[4]; //ゲームオブジェクトの4要素の配列を生成
    void Update()    {
        Vector3 pos = transform.position; //構造体Vector3のオブジェクトposをプロパティを利して生成
        pos.x += move; //オブジェクトposの持つ変数xにmoveの値を足し込む
        if (pos.x < -2.5f || pos.x > 2.5f) { //両端に来ていたら
            move = -move; //増分の符号を反転することで逆向きにする
        }
        transform.position = pos; //オブジェクトposをtransformプロパティに渡すと画面に反映
        if (Input.GetMouseButtonUp(0)) {
            Instantiate(prefabs[0], pos, Quaternion.identity);
        }
    }
}

提出:p.162 shooter

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です