・p.160「shooterにプレハブを渡す」から
・文法編「インターフェイス」
p.160 shooterにプレハブを渡す
・p.161①で表示される画面が変わっており「Size」表記はなくなっている ・InputクラスはUnityEngineに含まれるクラスで入力システムのインターフェースを提供する https://docs.unity3d.com/ja/2022.2/ScriptReference/Input.html ・Input.GetMouseButtonUp(int)は、その静的メソッドで、マウスボタンを離したフレームの間だけ trueを返す ・InstantiateメソッドはMonoBehaviourクラスから継承したもので、オブジェクトをクローンする。 引数はGameObject、Vector3、Quaternionの3つで、対象、位置、回転を示す ・Quaternion.identityは無回転(元のまま)を指す ・Quaternionは四元数ともいい回転を表す手法 ・実行してクリックし続けるとHierarchyが生成したオブジェクトの洪水になるが、プレイを停止すると消える
p.162 Shooter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour {
float move = 0.05f; //単精度変数を初期化して移動単位とする
public GameObject[] prefabs = new GameObject[4]; //GameObjectの配列[4]を生成
void Update() { //フレーム表示ごとに実行する
Vector3 pos = transform.position; //位置情報を得る
pos.x += move; //得たX座標に移動単位を足し込む(右移動)
if (pos.x < -2.5f) { //左端に達した?
move = 0.05f; //移動単位を正に(次回は右移動に)
}
if (pos.x > 2.5f) { //右端に達した?
move = -0.05f; //移動単位を負に(次回は左移動に)
}
transform.position = pos; //位置情報に書き戻す(実際に移動する)
if (Input.GetMouseButtonUp(0)) { //マウスが左ボタンアップされていたら
Instantiate(prefabs[0], pos, Quaternion.identity); //要素[0]を生成
}
}
void Start() {
}
}
p.164 野菜の種類を順番に切り替える
・変数curvageの値を0,1,2,3,0,1,2,3,0,1,2,3,0,… とするのが目的 ・curvage++; curvage %= 4; は、if文や条件演算子でも記述できるが、割った余りにする方が安全性が高い 例①: if (curvage >= 3) curvage = 0; else curvage++; 例②: curvage = (curvage >= 3) ? 0 : curvage + 1;
p.165 Shooter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour {
float move = 0.05f; //単精度変数を初期化して移動単位とする
public GameObject[] prefabs = new GameObject[4]; //GameObjectの配列[4]を生成
int curvage = 0; //現在の野菜の添字
void Update() { //フレーム表示ごとに実行する
Vector3 pos = transform.position; //位置情報を得る
pos.x += move; //得たX座標に移動単位を足し込む(右移動)
if (pos.x < -2.5f) { //左端に達した?
move = 0.05f; //移動単位を正に(次回は右移動に)
}
if (pos.x > 2.5f) { //右端に達した?
move = -0.05f; //移動単位を負に(次回は左移動に)
}
transform.position = pos; //位置情報に書き戻す(実際に移動する)
if (Input.GetMouseButtonUp(0)) { //マウスが左ボタンアップされていたら
Instantiate(prefabs[curvage], pos, Quaternion.identity); //現在の野菜を生成
curvage++; //次の野菜へ
curvage %= 4; //4で割った余りにすることで4を超えたら1に戻す
}
}
void Start() {
}
}
p.166 プロパティが返す構造体の値は直接書き換えられない
・「transform.position.x += move;」がエラーになる理由は「transform.position」がプロパティであり、 変数やオブジェクトではないこと ・「transform.position.x」はプロパティが返すオブジェクトである構造体のデータメンバ ・このオブジェクトには名前がなく一時的な存在なので、そこに含まれるデータメンバは利用はできるが、 書き換えはできない ・よって、いったん変数で受けると書き換え可能になる 例: Vector3 work = transform.position; work.x += move; 例: Vector3 work = transform.position; work.x = 4.0f;
p.172 箱のゲームオブジェクトを作成する
・①[Create]⇒「+」 ・②[2D Object][Sprite]⇒[2D Object][Sprites][Square] ・③の名前の変更は、戻ってしまうことがあり、⑤の後でリトライすると良い
p.175 UnityUIのCanvasを配置する
・①[Create]⇒「+」
p.176 数を表示するためのTextを配置する
・①[Create]⇒「+」 ・②[UI][Text]⇒「UI」「Legacy」「Text」 ・p.177上の図「Textが配置されます」⇒「Text(Legacy)が配置されます」 ・p.177下の図「Textを移動」⇒「Text(Legacy)を移動し上下に広げる」 ※位置はp.178上の図のように箱よりも上にする ・また、ここで「Canvas Rendarer」の「Cull Transparent Mes」のチェックをオフにする ・p.178の④まで終えたら、「Scene」を「Game」に切り替えることで設定結果が確認できる
p.178 ゲームオブジェクトを複製する
・①「Textを右クリック」⇒「Text(Legacy)を右クリック」 ・p.179上の図「Text(1)」⇒「Text(Legacy)(1)」
文法編「クラスと構造体」「コンストラクタ」「インターフェイス」
p.168 クラスと構造体の違いは
・クラスから生成されたインスタンス=クラスを型とする変数 例: Slime suralin = new Slime(); ・クラスを型とする変数は参照型であり、変数名が持つのは実体ではなく実体の位置情報に該当する ・よって、クラスを型とする変数間で代入すると、位置情報がコピーされ、実体は1つのままで、2つの変数名で扱われる ・つまり、2つ目の変数名は別名のように扱われる 例: Slime suralin = new Slime(); Slime betumei = suralin; //実体はコピーされない ・よって、複雑で大きなクラスのオブジェクトを「場所を教えるから、そっちでも扱ってくれ」という場合に便利
ミニ演習 mini168
・int型のhpとmpを持つSlimeクラスを定義する(public指定にする)
・Startメソッドの中でSlimeクラス型の変数suralinとhoiminを生成する
・suralin.hpに10、hoimin.hpに20を代入
・Slimeクラス型の配列slimesを作り、suralinとhoiminを要素にする
Slime[] slimes = { suralin, hoimin };
・slimes[0].hpと、slimes[1].hpをDebug.Logで出力
・slimes[0].hpと、slimes[1].hpの値を交換する
・suralin.hp、hoimin.hpをDebug.Logで出力
作成例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
class Slime168 { //スライムクラス
public int hp;
public int mp;
}
public class mini168 : MonoBehaviour{
void Start() {
Slime168 suralin = new Slime168(); //スライムオブジェクトを生成
Slime168 hoimin = new Slime168(); //スライムオブジェクトを生成
suralin.hp = 10;
hoimin.hp = 20;
Slime168[] slimes = { suralin, hoimin }; //配列に格納
Debug.Log("slimes[0].hp = " + slimes[0].hp + " [1].hp = " + slimes[1].hp);
var work = slimes[0].hp;
slimes[0].hp = slimes[1].hp; //配列側で2匹のhpを交換
slimes[1].hp = work;
Debug.Log("suralin.hp = " + suralin.hp + " hoimin.hp = " + hoimin.hp); //元も交換されている
}
}
ミニ演習 mini169
・Slime169構造体にして、同様の処理を行って、結果を確認しよう
作成例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
struct Slime169 { //スライム構造体
public int hp;
public int mp;
}
public class mini169 : MonoBehaviour {
void Start() {
Slime169 suralin = new Slime169(); //スライムオブジェクトを生成
Slime169 hoimin = new Slime169(); //スライムオブジェクトを生成
suralin.hp = 10;
hoimin.hp = 20;
Slime169[] slimes = { suralin, hoimin }; //構造体配列に格納(Copyになる)
Debug.Log("slimes[0].hp = " + slimes[0].hp + " [1].hp = " + slimes[1].hp);
var work = slimes[0].hp;
slimes[0].hp = slimes[1].hp; //配列側で2匹のhpを交換
slimes[1].hp = work;
Debug.Log("suralin.hp = " + suralin.hp + " hoimin.hp = " + hoimin.hp); //元は変わらない
}
}
文法編:コンストラクタ
・クラスや構造体において、オブジェクトの生成時に自動的に実行されるのがコンストラクタ
・コンストラクタはシステムが空で用意してくれるので、意識しなくても良い
・しかし、オブジェクトの生成時にやってほしいことがあれば、自分でコンストラクタを書くことで、オブジェクトの生成時に実行してもらえる
・つまり、コンストラクタは一種のメソッドだが、名前はなく、クラス名が名前になる
・例:
class Slime170 {
public Slime170() { Debug.Log("OK"); } //コンストラクタ
}
ミニ演習 mini170
・上記のSlime170クラスのインスタンスを生成するとコンストラクタが動作することを確認しよう
作成例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
class Slime170 {
public Slime170() { Debug.Log("OK"); } //コンストラクタ
}
public class mini170 : MonoBehaviour {
void Start() {
Slime170 suralin = new Slime170(); //生成するとコンストラクタが動作する
}
}
文法編:デフォルトコンストラクタ
・インスタンス生成時に引数を指定しないときに動作するコンストラクタをデフォルトコンストラクタという ・主に、引数のないコンストラクタが該当する ・なお、構造体では引数のないコンストラクタはシステムが用意し、自前の定義はエラーになる
提出:ミニ演習 mini170