講義メモ

・ゲーム開発編:p.164 野菜の種類を順番に切り替える から
・文法編:プロパティの補足、クラスと構造体、など

p.160 Shooter.cs 補足

・p.160で下記を追記してゲームオブジェクトの4要素の配列を生成している
 public GameObject[] prefabs = new GameObject[4];
・だが、GameObjectはクラスであるため、本来は、この1行のみではオブジェクトへの参照の配列(オブジェクトのない配列)しか生成されない
・しかし、p.168下から3行目に説明がある通り、Unityが提供するMonoBehaviour継承クラスにおいては、
 Unityのシステムによって、自動的にオブジェクトが生成される
・よって、通常のクラスの場合と、Unityが提供するMonoBehaviour継承クラスの場合で、仕様が異なることに注意を。

ゲーム開発編:p.164 野菜の種類を順番に切り替える

・Shooter.csに、現在の野菜の添字を示すint型変数curvageを追加
・初期値は0として、tomatoを意味させる
・マウスボタンが押された時の処理でtomatoを固定で出現させているところを、この変数を用いることで、異なる野菜が出現するように変更
・また、野菜の種類を順番に切り替えるようにしている

p.164&165 Shooter.cs

//p.164&165 shooter.cs
using UnityEngine;
public class shooter : MonoBehaviour {
    float move = 0.05f; //単精度実数型のフィールド変数moveの初期化
    public GameObject[] prefabs = new GameObject[4]; //ゲームオブジェクトの4要素の配列を生成
    int curvage = 0; //【追加】現在の野菜の添字を示す変数(初期値はtomato)
    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[curvage], pos, Quaternion.identity); //【変更】現在の野菜を表示
            curvage++; //【追加】現在の野菜の添字に1加算することで次の野菜へ
            curvage %= 4; //【追加】4で割った余りにすることで0,1,2,3の繰返しになる
        }
    }
}

p.165 Shooter.cs 文法の補足

・prefabs[curvage]により、GameObject型のオブジェクトの配列から、curvage番目のオブジェクトを得ている
・「curvage++」の「++」はp.105の通りインクリメント演算子で「curvage = curvage + 1」と同じ意味になる
・なお、ここではインクリメント(1加算)を単独で行っているので後置を前置にして「++curvage」としても同じ動作になる
・「curvage %= 4」の「%=」はp.103の通り「計算もできる代入演算子(複合代入演算子)で「curvage = curvage % 4」と同じ意味になる
・これにより、curvageの値は4で割った余りである0,1,2,3のどれかになる
・よって、「curvage++」と「curvage %= 4」の組み合わせで、curvageの値は0,1,2,3,0,1,2,3,0,…と順番に変化していくことがわかる
・なお、剰余算は加減算などより処理が重たくなりやすいので、このような処理はif文や条件演算子で記述することも多い
 例: curvage = (curvage >= 3) ? 0 : curvage + 1; //3なら0に、でなければ+1に。

アレンジ演習:p.165 Shooter.cs

・上記の条件演算子による記述にして動作を確認しよう

作成例

//アレンジ演習:p.164&165 shooter.cs
using UnityEngine;
public class shooter : MonoBehaviour {
    float move = 0.05f; //単精度実数型のフィールド変数moveの初期化
    public GameObject[] prefabs = new GameObject[4]; //ゲームオブジェクトの4要素の配列を生成
    int curvage = 0; //現在の野菜の添字を示す変数(初期値はtomato)
    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[curvage], pos, Quaternion.identity); //現在の野菜を表示
            //curvage++; //【削除】現在の野菜の添字に1加算することで次の野菜へ
            //curvage %= 4; //【削除】4で割った余りにすることで0,1,2,3の繰返しになる
            curvage = (curvage >= 3) ? 0 : curvage + 1; //【差替】3なら0に、でなければ+1に。
        }
    }
}

文法編:プロパティの補足

・上記の「プロパティが返す構造体の値は直接書き替えられない」ことを試そう
・まず「プロパティやメソッドは値だけではなく、オブジェクトを返すことができる」を試そう
・下記のMap構造体(座標を示す)を定義した場合
    struct Map {
        public int x; //データメンバ
        public int y;
    }
・この構造体を型とするデータや、型とするプロパティを持つMonsterクラスを定義できる
    class Monster { //インナークラスMonsterの定義
        public int hp; //Monsterクラスの持つint型のデータ
        public int mp; //同上
        public Map xy; //Monsterクラスの持つMap構造体の座標オブジェクト
        public Map XYP{ //座標オブジェクトを返すプロパティ
            get { return xy; } //座標オブジェクトを返す(setがないので外部書替え不可)
        }
    }

演習 ex0824a.cs

・上記を用いて、プロパティ経由で得た座標オブジェクトのデータメンバx、yを書き替えられないことを確認しよう
・表示であれば可能なことを確認しよう
・また、座標オブジェクトをプロパティで得て、Map型の変数に代入すれば:
 ① Map型の変数のメンバであるデータの書き替え
 ② Map型の変数を元の座標オブジェクトに書き戻す
 ことが可能なことを確認しよう

作成例

using UnityEngine;
public class ex0824a : MonoBehaviour {
    //Map構造体(座標を示す)
    struct Map {
        public int x; //データメンバ
        public int y;
    }
    //この構造体を型とするデータや、型とするプロパティを持つMonsterクラス
    class Monster { //インナークラスMonsterの定義
        public int hp; //Monsterクラスの持つint型のデータ
        public int mp; //同上
        public Map xy; //Monsterクラスの持つMap構造体の座標オブジェクト
        public Map XYP{ //座標オブジェクトを返すプロパティ
            get { return xy; } //座標オブジェクトを返す
        }
    }
    void Start() {
        Monster veldra = new Monster(); //Monsterのveldraを生成
        //veldra.XYP.x = 10; //プロパティで得た座標オブジェクトのデータは書替え不可
        //veldra.XYP.y = 20; //プロパティで得た座標オブジェクトのデータは書替え不可
        Debug.Log(veldra.XYP.x + ", " + veldra.XYP.y); //表示は可能
        Map vmap = veldra.XYP; //veldraの座標オブジェクトをプロパティで得て代入
        vmap.x = 10; //受け取ったオブジェクトのコピーのデータは書替えOK
        vmap.y = 20; //受け取ったオブジェクトのコピーのデータは書替えOK
        veldra.xy = vmap; //書替え結果を書き戻すことはOK
        Debug.Log(veldra.XYP.x + ", " + veldra.XYP.y); //書き換わっていることを確認
    }
}

コメントを残す

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