・ゲーム開発編: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); //書き換わっていることを確認
}
}