講義メモ ・ゲーム開発編:p.144 transformプロパティ から ・文法編:プロパティ から 文法編:構造体【再掲載】 ・構造体はC言語に元々ある仕組みで、複数の変数をグループ化して扱う手法 ・なお、複数の同じ型と意味の変数をグループ化するのが配列、型や意味が異なる変数をグループ化するのが構造体 ・Vector3構造体の場合、3次元データを表す3つの変数x、y、zをグループ化して扱うためなどに用いる ・構造体はintなどと同様にデータ型として利用できる(クラスにおける変数と同様) ・C#では、C言語で書かれたプログラムの移植時に、クラスにすると効率が落ちるのを避けるために「軽量クラス」として「C#の構造体」が利用可能 ・よって、C言語の構造体とは異なり、「C#の構造体」ではデータ以外にメソッドなども記述でき、継承を行わないクラスなどで用いることが多い ・Vector3構造体はUnityが提供するものだが、プログラマが自前の構造体を定義して用いることも可能 ・書式例: struct 構造体名 { 定義内容 } ・構造体もクラスと同様に、構造体名を型とするオブジェクト名を定義してオブジェクトを生成して用いる 提出フォロー:文法編:構造体の作成例 ex0727b【再掲載】 using UnityEngine; public class ex0727b : MonoBehaviour{ struct Map { //2D座標の構造体の定義 public int x; //Map構造体の持つデータ public int y; //同上 } void Start() { Map player = new Map(); //Mapオブジェクトplayerを生成 player.x = 100; //playerが持つ変数xに代入(プレイヤーのX座標を設定) player.y = 200; //playerが持つ変数yに代入(プレイヤーのY座標を設定) Debug.Log(player.x + ", " + player.y); //playerが持つ変数の値を出力 } } 文法編:プロパティ ・プロパティはクラスや構造体に含むことができるメンバであり、クラス変数(インスタンス変数)やメソッドと同類 ・プロパティは、変数と同様に扱うとアクセッサと呼ばれる内蔵された処理内容が動作する仕組み ・書式: アクセス修飾子 型 プロパティ名 { get { 処理① } set { 処理② } }  処理①には値を返す「return」を含む式など  処理②には値を設定する「value」を含む式など(※valueには外部から与えた値が入る) ・プロパティは基本的にクラス変数(インスタンス変数)へのアクセス手段を提供するもので、アクセスにルールを定めたい場合に便利  例:「値の変更不可」「負の数不可などの条件」「なんらかの前提があれば」 ・書式例  private double weight; //体重(外部からの操作は不可)  public double KG { //プロパティの定義   get { return weight; } //値を返すのは無制限   set { if (value > 0) { weight = value; } } //値を設定するにはルールあり  } ・利用側は変数と同様に、代入や利用が可能  例:  Debug.Log(インスタンス名.KG); // KGのgetが動作してreturnされた値が得られる  ⇒ Debug.Log(インスタンス名.weight); の代わりになる(weightはprivateなのでエラーになる)  インスタンス名.KG = 70.); // KGのsetが動作してvalueに70.2が入って実行される  ⇒ インスタンス名.weight = 70.2; の代わりになる(weightはprivateなのでエラーになる)  インスタンス名.KG = -1; // KGのsetが動作してvalueに-1が入って実行されるが代入されない 演習 ex0803a.cs プロパティの基礎 ・クラスBMI1を定義し、privateなdouble型のインスタンス変数height、weightを定義する ・height用のプロパティHM、weight用のプロパティKGを定義して、正の数のみ格納できるように制限する ・get、setが動作していることを確認しよう 作成例 using UnityEngine; public class ex0803a : MonoBehaviour { class BMI1 { //2D座標の構造体の定義 private double height; //身長(内部用) private double weight; //体重(内部用) public double HM { //heightを扱うプロパティ get { //値を返すのは無条件 Debug.Log("HM.getが動作"); //確認用 return height; } set { //値を設定するにはルールあり Debug.Log("HM.setが動作"); //確認用 if (value > 0) { height = value; } } } public double KG { //プロパティの定義 get { return weight; } //値を返すのは無制限 set { if (value > 0) { weight = value; } } //値を設定するにはルールあり } } void Start() { BMI1 bmi = new BMI1(); //BMI1オブジェクトbmiを生成 bmi.HM = 1.72; //プロパティのset経由で身長を代入 Debug.Log("身長:" + bmi.HM); //プロパティのget経由で身長を得て表示 bmi.HM = -5; //無視される Debug.Log("身長:" + bmi.HM); //プロパティのget経由で身長を得て表示 bmi.KG = 72.5; //プロパティのset経由で体重を代入 Debug.Log("体重:" + bmi.KG); //プロパティのget経由で身長を得て表示 bmi.KG = -5; //無視される Debug.Log("体重:" + bmi.KG); //プロパティのget経由で身長を得て表示 } } p.144 transformプロパティ ・https://docs.unity3d.com/ja/2021.2/ScriptReference/MonoBehaviour.html ・p.144の図ではやや分かりづらいが:  ① 自前のUnity用ソースはMonoBehaviourクラスを継承しているので、MonoBehaviourクラスの持つメンバが引き継がれている  ② MonoBehaviourクラスはBehaviourクラスを継承しており、継承メンバーの中にTransform型のtransformプロパティがある  ③ このプロパティの定義はVisual Studioで見ると「get;」しかないので、代入を不可とするために定義されていることがわかる p.145 変数のように使えるけれどちょっと違うプロパティ ・上記の通りで「外部から自由に使えるpublic」か「外部から全く使えないprivate」しか設定できない変数について、プロパティを経由することで、ルールの設定が可能になる ・transformプロパティの場合、getが可能なので「Vector3 pos = transform.position」というように値を得られる ・しかし、トラブルを避けるためにsetが不可なので、transformではなく、transform.positionに対して代入を行う ・動作としては、shooterの位置情報をtransform.positionからposに取り出して、そのメンバであるX座標を示すpos.xの値を操作してtransform.positionに書き戻すことで、動かしている ゲーム開発編 p.146 画面の端に来たら折り返す ・画面の右端のX座標は2.5、左端は-2.5となっているので、これを超えたら増分であるmoveの符号を反転すると良い p.146 shooter.cs using UnityEngine; public class shooter : MonoBehaviour { float move = 0.05f; //単精度実数型のフィールド変数moveの初期化 void Update() { Vector3 pos = transform.position; //構造体Vector3のオブジェクトposをプロパティを利して生成 pos.x += move; //オブジェクトposの持つ変数xにmoveの値を足し込む if (pos.x < -2.5f) { //左端に来ていたら move = 0.05f; //増分を正にする事で反転する } if (pos.x > 2.5f) { //左端に来ていたら move = -0.05f; //増分を負にする事で反転する } transform.position = pos; //オブジェクトposをtransformプロパティに渡すと画面に反映 } } アレンジ演習:p.146 shooter.cs ・反転するために実数リテラル0.05fを何度も記述するのは保守性が低下する ・変数moveの符号を反転する処理に書き換えよう ・すると、一つのif文にできることを確認しよう 作成例 //アレンジ演習:p.146 shooter.cs using UnityEngine; public class shooter : MonoBehaviour { float move = 0.05f; //単精度実数型のフィールド変数moveの初期化 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プロパティに渡すと画面に反映 } } p.148「自然な動き」を表現するRigidbody2Dコンポーネント ・物体の左右移動に対して、上下移動では引力の影響を加味することが多い ・これをプログラムで記述できるが、Unityが提供しているコンポーネントを用いると便利 ・加えて、衝突による跳ね返りを含む「物理法則に則った動き」を提供するのがRigidbody2Dコンポーネント ・なお、本来「物理法則に則った動き」を実装するには、衝突による変形を加味すべきだが、ゲームにおいては、変形を加味しなくても構わない場合が多く、動作を軽くできる ・この考え方が「剛体(変形しない物体)」で、Rigidbodyは剛体のこと p.148 野菜のゲームオブジェクトを作成する ・p.139の手順を再度行うが、調整が必要なので、下記の手順で行うと良い ・①[Hierarchy]の[+]をクリック ・②[2D Object]の[Sprites]の[Square]をクリック ・③名前を「Vegetable」に変更 ・④[Sprite]の右の◎アイコンをクリック ・⑤画像「Tomato」をダブルクリック ・⑥[Transform]の[Position]の[X]を-1に、[Y]を+1にする ・⑦[Add Component]  ※窓に「Shooter」が残っていたらBackSpaceキーで消す ・⑧[Physics2D][Rigidbody2D] ・⑨[File][Save]してから、プレイボタンで実行 p.148 野菜のゲームオブジェクトを作成する:補足 ・Rigidbody2Dコンポーネントは、Physics2Dというカテゴリーに分類されており、2Dの物理的なオブジェクトを扱う部品群に含まれている ・Rigidbody2Dコンポーネントには、Gravity Scale(重力スケール)や Mass(質量)などの設定項目があり、これらを初期値の1から増減することで落下をコントロールできる p.150 ゲームの背景色を変更 ・①[Hierarchy]の[Main Camera] ・②[Camera]の[Background] ・③中央の〇を左上にドラッグして、RGBの値がすべて255になることを確認 ・④[×]で閉じる ・⑤[File][Save]してから、プレイボタンで実行 p.151 [Color]ダイアログボックス ・Unityでは色に関する設定項目をクリックすると[Color]ダイアログボックスが表示され、直感的に色を選択できる ・[Color]ダイアログボックスの上部にある円環は色相環といい、赤からマゼンタ経由で青へ、青から黄色経由で赤へと似た色を並べていくと連続的な「色合い」の変化になることを表している ・中央にある正方形は明度を表すもので、色相環で選ばれている色から、左上の白か、右下の黒に近づけることで「明るさ」の変化になることを表している ・設定された色はRGBの3色の配合度合いで数値化され、各0から255の256段階になる ・よって、色数としては256の3乗=16,777,216色が表現できる ・なお、企業向けのアプリでは、企業が決めているコーポレートカラーのRGB値を正確に指定することが求められるので注意  例:auは「235, 85, 5」DoCoMoは「204 0 51」 ・Aのスライダで透明度を設定できる(後方にあるオブジェクトの色を透過させる割合で、0であれば非透過) p.152 プレハブを使ってゲームオブジェクトを量産する ・プレハブ:プレ(あらかじめ用意されている)ファブリケーション(構造物)の略で、Unityではゲームオブジェクトの原型になる基礎オブジェクトのこと ・作成済のオブジェクトをプレハブにすることで、このプレハブを継承して類似のオブジェクトを作成できる ・これはコピペではなく継承なので、プレハブに対する変更は、プレハブから作成されたオブジェクトに自動的に反映する ・また、プレハブを継承したプレハブを作成できるので、階層構造で作成や管理が可能(クラスと同様) p.153 プレハブを作成する ・①の前に「Scene」をクリック p.154 プレハブを継承したプレハブを作る ・プレハブのインスタンスになっていることを立方体のアイコンで確認してから、再度、ドラッグ&ドロップ ・ここで表示されるダイアログは、①Original Prefab(プレハブを新規作成)、②Prefab Variant(プレハブを継承して作成)、③キャンセルの三種で、②を選ぶこと ・p.155①「Open Prefab」は「Open」ボタン ・p.157「同じように」の内容を丁寧に行うこと 提出:アレンジ演習:p.146 shooter.cs 次回予告: ・文法編:列挙 から ・ゲーム開発編:p.156 列挙型を利用して野菜の種類を表す型を作ろう から