条件分岐と繰り返しを学ぶ回。
if(条件式){
trueのときの処理
}
【復習】
intは整数型 floatは実数型 boolは真偽値 stringは文字列
float x = 42.195f; float型はfをつけなければならない。
double x = 42.195; でも同じことが表現できる。
if (){
if () {
}
}
という風に組み合わせると、true値になったときに別の条件チェックが行われるということ。
if (){
}
else if() {
}
というふうに組み合わせると、条件がfalseのときに条件をチェックするという書き方になる。
【演算子で条件を組み合わせる】
条件式**&&条件式 → 条件式がどちらもtrueのときtrueを返す。
条件式||条件式 → 条件式のどちらかがtrue**のときtrueを返す。
switch文を使った分岐
switch文はtrue、falseの2択だけではない、複数に分岐できる構文。
switch文の変数とcaseラベルの値が一致するかで実行される。実行はbreak文まで。
どのラベルにも一致しない場合はdefault文のあとの処理が行われる。
//架空のFileメニューが有り、項目選択時に変数が変数menuに入り、switch文で処理が実行される。(これはテキストのみ)
void Start () {
string menu = "print"; //stringは文字列型
switch(menu){
case "save": //caseラベルは:(コロン)で書く
Debug.Log ("保存します");
break;
case"open": //caseラベルは:(コロン)で書く
Debug.Log ("開きます");
break;
case"print": //caseラベルは:(コロン)で書く
Debug.Log("印刷します");
break;
default: //default文も:(コロン)で書く
Debug.Log("一致する機能がありません");
break;
}
}
caseラベルは変数や式を使うことはできず、数値か文字列だけ。つまり大小ではなく、==か!=かだけ判断できる。
while文
while (条件式) {
繰り返す処理
}
// Use this for initialization
void Start () {
int x = 0;
while (x < 8) { //x<8の限り処理が続く
x = Random.Range (0, 10);
Debug.Log (x);
}
Debug.Log ("終了");
}
do-while文
こちらはブロックが先、条件式が後になる。
do {
繰り返す処理
} while (条件式);
while文との違いは、ブロック内の処理が必ず1回は実行されること。
for文
回数の決まった繰り返しに便利。
for (初期化; 条件式; 反復) {
繰り返す処理
}
for文では回数を数えるための変数(カウンター変数)を用意する。
初期化の部分で変数を宣言し、条件式の部分で回数をチェック、反復の部分で変数を増やす。
for (int i =0; i <10; i++) {
繰り返す処理
}
iをカウンター変数として用意、i<10になるまでやることを設定、iの増やし方を設定。
void Start () {
for (int i = 0; i < 10; i++) {
Debug.Log (i);
}
Debug.Log ("終了");
}
for文で使うbreak文とcontinue文
break文は処理を中止し、ブロックの外へ移動する。例えば、繰り返しの中で処理するべきデータがなくなったときに使う。switch文でもbreak文は出てきたが、どちらもブロックの外へ移動することが目的。
for ( int i = 0; i < 1000; i++){
if (終了条件のチェック) break;
繰り返したい処理
}
for (int i = 0; i <1000; i++){
if(i >= 200) break;
Debug.Log(i);
}
continue文は繰り返し処理を1回スキップする。
例えば、複数のデータチェックで、負の数だけスキップして正の数だけ処理するという挙動にしたい場合につかう。
for (int i = 0; i < 1000; i++){
if (スキップ条件のチェック)continue;
繰り返したい処理
}
for (int i = 0; i <1000; i++){
if(i%2==0) continue;
Debug.Log(i);
}
foreach文
配列変数と組み合わせやすいように改良されたfor文のこと。
foreach (変数 in 配列変数){
繰り返したい処理
}
配列変数
複数のデータを記録できる変数のこと。
クラスのメンバー変数を追加して複数データを記録するのとは異なる仕組み。
メンバー変数はそれぞれが違う変数だが、配列変数は同じ型の変数が複数並んだような感じ。
それぞれに番号がついており、番号を添字(そえじ)、配列変数内の1つ1つの変数を要素という。
配列変数を宣言するには、型の後に[]をつける。
さらに、new演算子をつかって作成したインスタンスを代入する必要がある。
型[] 変数名 = new 型[要素数];
int[] arr = new int[5];
変数arrにインスタンスを代入、メソッドはint型(整数型)を使用。
配列はArray(アレイ)という特殊なクラスのインスタンス。つまり配列変数はArray型インスタンスを参照している
【復習】
クラスのインスタンスはnew演算子を使って作成し、変数に代入する。
(略){
Person p = new Person(); ///クラスPersonのインスタンス作成 pに代入
(中略)
}
class Person{ ///クラスPersonを作成
string name;
}
Personクラスのインスタンスを作成し、pという変数に代入している。
しかし変数にインスタンスが入ってるわけではなく、メモリ上の何処かにあるインスタンスを変数から「参照」している状態である。
組み込み型を代入したときは値がコピーされるが、インスタンスを代入したときは同じものを参照しているということ。
つまり
1つのインスタンスを複数の配列変数で参照したり、宣言後の配列変数に別のインスタンスを参照させたりすることもできる。
(例)
int[] arr = new int[5];
int[] arr2 = arr; //同じインスタンスを代入している。
arr = new int[8]; //別のインスタンスを作成して代入している。
**配列変数の初期化**
複数の値を**{}で囲んで**まとめて書く。要素数は値の数でわかるので省略される。new 型[]すらも省略される。
```:配列変数の初期化
型[] 変数名 = {値1,値2,値3,値4};
int[] arr = {-1, 53, 22, 43, 2};
なお、一度宣言された配列変数に後から数値を記録することはできない。
// Use this for initialization
void Start () {
int[] arr = { -1, 22, 31, 65, 4 };
Debug.Log(arr[2]);
}
void Start () {
int[] arr = { -1, 22, 31, 65, 4 };
arr [2] = 42; ///添字2に42を代入。値は更新される。
Debug.Log(arr[2]);
}
void Start () {
int[] arr = { -1, 53, 21, 16, 4 }; //int型配列変数arrを用意、5つの値で初期化
for (int i = 0; i < 5; i++){ //for文で繰り返し処理
arr [i] = arr [i] * 2;
Debug.Log (arr [i]);
}
}
int型、float型、string型はわかったけど、クラスを配列変数にする場合は?
ちょっと不思議な書き方になる。
// Use this for initialization
//クラス型の配列変数を作る
void Start () {
Person[] parr = new Person[5]; //5つの要素を格納できる配列変数parrを宣言
parr [0] = new Person (); /*1つ目の要素にインスタンスを代入してメンバー変数(クラスが持つ変数のこと)や
メソッドを利用している。new演算子が2つもあるのは、1つ目は格納できる何も入っていない
配列変数のインスタンスをつくるためのもので、2つ目が要素に入れるインスタンスだということ*/
parr [0].firstname = "太郎"; //配列変数parrの要素に入れたPersonインスタンスのメソッドを呼び出している。クラス名.メソッドの順。
parr [0].lastname = "山田";
Debug.Log (parr [0].GetFullName ("★"));
}
クラス型の配列変数でも初期化できる
その場合は**{}の中に要素に入れたいインスタンスを作成する。**
Person[] parr = {new Person () , new Person ()};
parr [0].firstname = "太郎";
parr [0].lastname = "山田";
Debug.Log (parr [0].GetFullName("★"));
なおparr[0]とparr[1]は同じnew Person()が指定されていますが、参照型では別のオブジェクトになります。
Personクラスのインスタンスを2種類new演算子で作って、それぞれparr[0]とparr[1]になってる。
※参考書でなぜ先頭しか使っていないのかはわかりません。配列の使用例としては不適切に思えます。
毎回メンバー変数に代入するの面倒じゃね?ってことで...
クラスにコンストラクターを追加する
これによりインスタンスを作るときに初期値を設定することができる。
これを利用して、配列変数の初期化時にメンバー変数を設定できる。
コンストラクターとはクラスと同じ名前の特殊なメソッド。書き方はメソッドと同じだが、呼び出すときはnew演算子を使う。
public クラス名 (引数の型と名前, 引数の型と名前){
初期化処理
}
// コンストラクターの呼び出し
クラス名 変数名 = new クラス名 (引数,引数);
class Person{
public string firstname;
public string lastname;
public string GetFullName(string separator) {
//戻り値の型はstring(文字列型) 引数付きのメソッドを定義する場合、(引数の型 引数名)を書く。複数の引数ならカンマ(,)で区切る。→(string fn , string ln)
return this.lastname + separator + this.firstname;
}
public Person (string fn, string ln){ //stringは文字列型。
this.firstname = fn; // thisはインスタンス自身を表す特殊な変数。
this.lastname = ln;
}
public Person (){} ///上で2つの引数を取るコンストラクターを定義したので、デフォで用意されていた引数なしのコンストラクター(new Person())が使えなくなったので、**「The type `Person' does not contain a constructor that takes `0' arguments(Person型は引数を0個取るコンストラクターを持っていない)」**というエラーが出るので、引数をとらず何もしないコンストラクターも追加しておく。
このように戻り値と引数が違えば、同名のコンストラクターをつくることが可能。
多次元配列
いままでのは1次元配列(横の並びのみ)だったが、2次元配列(横+縦)などのような多次元配列もある。
2次元配列の場合、[]の間を,(カンマ)で区切って2つの添字を書く。
int[,] arr2d = {
{1,1,1,1,1,1},
{1,0,0,0,0,0},
{1,0,0,0,0,1},
{1,1,1,1,1,1}
};
arr2d [1,0] = 5;
どうやら、添字は最初の数字が縦(縦のどの配列か)、次の数字が横(配列の何番目か、最初は0)を表すようだ。
foreach文(フォーイーチ文)
配列変数と組み合わせしやすいように改造されたfor文のこと。
カッコ内に「変数名 in 配列変数名」とかくと配列変数の要素が順番に変数に入るので、for文よりシンプルに書ける。**ただし、カウンター変数がないので、「奇数のときはスキップ」などのような処理をすることはできない。**汎用性はfor文のほうが高い。
int[] arr = {-1, 52, 22, 31, 4}
foreach (int v in arr){
Debug.Log (v);
}
Array.Sortメソッドで要素を並び替えてラクをしよう
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Lesson5 : MonoBehaviour {
// Use this for initialization
void Start () {
int[] arr = { -4, 33, 21, 53, 4 };
Array.Sort (arr);
for (int i = 0; i < 5; i++){
arr [i] *= 2;
Debug.Log (arr [i]);
}
}
要素数をいじれるListクラス
要素数を変えられるクラスで、Unityでも使えるのがListクラス。
の部分は型パラメータといい、Listのように記録したい型を指定する。
Addメソッド(以下略)→末尾に要素を追加
Clear→すべての要素を削除
Count→現在の要素数を取得
Contains→ある要素がリスト内にあるか調べる
Sort→リストを並び替える(静的メソッドではないので、変数名.Sort()の形で呼び出す)
Insert→指定した位置に要素を挿入
Remove→指定した位置の要素を削除
using System.Collections.Generic;
public class Lesson5 : MonoBehaviour {
// Use this for initialization
void Start () {
List<int> list = new List<int> ();
list.Add (48);
list.Add (985);
for (int i = 0; i < list.Count; i++){
Debug.Log (list [i]);
}
}
名前空間
先程の例で使用したもの。このusingディレクティブは名前空間(ネームスペース)を取り込む指定。冒頭で書いておけば、「System.」の入力を省略できる。
例えばこれまで使ってきたMonoBehaviourクラスも、名前空間を含めた正式名称は「UnityEngine.MonoBehaviour」である。
public class Lesson5 : UnityEngine.MonoBehaviour {
(省略)
using UnityEngine;
(中略)
public class Lesson5 : MonoBehaviour {
(省略)
静的メソッド
変数名.メソッド名
Debug.Log / Random.Range / Array.Sort();など。
クラス名.メソッド名
通常の。
前者が静的メソッド。インスタンスを作らずに呼び出せる。
定義の仕方はstatic(スタティック)修飾子をつけるだけ。
ただし静的メソッドにするとクラス内で特別な扱いになるので、同じクラスでもインスタンスのメンバー変数にアクセスできないなどの制限がある。
public static void Sort (Array array){
Sortメソッドの定義
}