i-school - 教科書の全体復習

大事なポイントの復習


 最後まで教科書を終了したら、最初から読み直して復習をしてみます。
ソースコードについても模写が基本であるため、あまりエラーもなく処理が実行できます。
そのため「覚えたつもり」になってしまいますので、しっかりと復習をして「処理が読めているか」を確認しましょう。


ピリオドの処理を理解して、読み解く力をつける


 C#のプログラムは、ドット(ピリオド)の位置によって、命令が1つずつ区切られています
また、そのドットの部分の変数が1つの型、あるいはメソッドへの命令文となっています。

 1つの文章に、複数のドットがある場合、それは左側から順番に処理が実行されています。
1行の命令だからといってまとめて読もうとはせずに、必ず、左側から順番に読み解いていくようにしてください。



  GetComponent<Rigidbody>().AddForce();

 上記の場合、GetComponent<>() までが1つのメソッドの命令文です。
このメソッドは Unityの持つコンポーネント取得の命令で、GetComponent メソッドの前にドットがなければ(今回のような場合)
このスクリプトがアタッチしているゲームオブジェクトに、アタッチされている<該当のコンポーネント(スクリプトもOK)>を取得して利用できる状態にする
という処理になります。



 ドットでつながっている処理は、左側から順番に処理されます。そして1つの処理が実行されてから、次のドットの処理に移ります

 このとき、GetComponent メソッドには戻り値という情報があるため、この処理が正常に終了している場合、この部分には取得したコンポーネントの情報が扱える状態、つまり型の情報に内容が置き換わっています。
今回の例であれば、GetComponent メソッドを実行すると、Rigidbody コンポーネントの取得が終了し、Rigidbody コンポーネントの情報が使える状態です。
そのため、GetComponent と記述はありますが、実際にプログラム内で利用される情報は Rigidbody 型になります。



 ドットに続けて記述できる処理は、ドットの前の処理の情報を利用して命令を行っています。

  GetComponent<Rigidbody>().AddForce();

 Rigidbody コンポーネントを利用できる状態になっているということは、インスペクターに表示されている情報を利用できるほかに、
インスペクターからは見えませんが、Unity の用意している、Rigidbody に関連するメソッドも利用できる状態になります。

 そのため上記の例では、Rigidbody コンポーネントの扱っている情報の1つである AddForce メソッドを実行している、という内容になります。
この処理であれば、AddForce メソッドを記述できているのは、Rigidbody コンポーネントの情報が扱えるようになっているためです。
 ドットの前に GetComponentメソッドによって Rigidbody コンポーネントが取得できているので、
これではじめて、Rigidbody コンポーネントの情報を使って、AddForce メソッドへの命令が記述出来るようになっています。

 処理の中身をコンポーネントで記述すると、Rigidbody.AddForce という命令が実行されていることになります。
Rigidbody の部分が、GetComponent メソッドの処理結果の部分になります。



 この処理は、変数にコンポーネントの情報を代入した場合でも同じ処理になっています。

  private Rigidbody rb;

  rb = GetComponent<Rigidbody>();
  rb.AddForce();

 上記の例の場合、Rigidbody 型の rb 変数を用意し、GetComponent メソッドの戻り値を利用して、
取得した Rigidbody コンポーネントの情報を変数に代入しています。

 この rb 変数は先ほどの例と同じように、Rigidbody コンポーネントの情報を扱える状態になりますので、

  rb.AddForce();

 このように、ドットを利用して、Rigidbody コンポーネントの情報を使って、AddForce メソッドを実行するという命令が記述できます。

 さらっと読み飛ばしてしまったり、書き写しているだけだと処理の内容がわかりませんので、必ず、処理を読んで、内容を理解をする、という学習を進めてください。


transform 変数と gameObject 変数について


 この情報は、Unity が用意してくれている変数になります。
頭文字が小文字の場合は変数大文字の場合はクラス(コンポーネント)の情報になります。
混同しやすいので特に注意してください。

 こちらに参考記事があります。 => 間違えやすい点



  transform.position = new Vector3(0, 180, 0);

 このような処理がスクリプトにあった場合、この transform 変数の前にドットがなければ(上記のような処理の場合)
このスクリプトがアタッチしているゲームオブジェクトの、Transform コンポーネントの情報が代入されている変数
 これが、transform 変数の値(中身)になります。

 また、この transform 変数にはドットの処理が続いています。これも先ほどと同じで、左側から順番に処理を読み解きます。

 Transform コンポーネントの管理している情報である、Position の値に右辺の値を代入する、という処理になっています。



 gameObject 変数も同じです。

  gameObject.SetActive(false):

 このような処理がスクリプトにあった場合、この gameObject 変数の前にドットがなければ(上記のような処理の場合)
このスクリプトがアタッチしているゲームオブジェクトの情報が代入されている変数
 これが、gameObject 変数の値になります。



 処理は変数ベースで実行されていくことがほとんどですので、変数に代入されている値がわからないと、処理が分からなくなってしまいます
そのようなときには、Debug.Log()メソッドを利用して、値を確認してください。

  Debug.Log(transform.position);
  Debug.Log(gameObject);
 のように記述することで、指定した変数の値を Console ビューに表示することができるので、変数の値を確認できます。



 もしも、transform 変数や gameObject 変数の前にドットがあった場合には、その前の情報に対しての変数になります。

  GameObject player = GameObject.Find("Player"); 
  player.transform.position = transform.position;

 処理を読めるか、挑戦してみてください。

 2行目の左辺 player.transform.position の処理は、ドットが2つある処理になります。
まずは、player 変数の情報を確認し、その情報を使った transform 変数になるので、
この transform 変数の値は、player 変数に代入されている情報の、Transform コンポーネントの情報、となります。
つまり、この処理を記述してあるスクリプトがアタッチしているゲームオブジェクトの Transform コンポーネントの情報ではありません

 同じく2行目の右辺 transform.position ですが、こちらは、transform 変数の前にドットはありません
そのため、この処理を記述してあるスクリプトがアタッチしているゲームオブジェクトの Transform コンポーネントの情報になります。

 非常に混同しやすく、分かりにくい部分でもありますので、こういう場合には、しっかりと各変数の値を把握しましょう。
そして日本語でコメントを書いておくことを強く勧めます。

  // 左辺に用意した player 変数に
 // ヒエラルキーにあるゲームオブジェクトを、すべて検索し名前が Player であるゲームオブジェクトの情報を GameObject 型として取得して左辺へ代入
  GameObject player = GameObject.Find("Player")

  // player 変数の、 Transform コンポーネントの、 Position の情報に(点の位置がドットの位置と同じ)
 // このスクリプトがアタッチしているゲームオブジェクトの Transform コンポーネントの、 Position の情報を代入
  player.transform.position = transform.position;

 コメントを書く場合にも、上記のように、処理ごとや、左辺と右辺ごとに分けて書いておくと処理の内容が分かりやすくなります
ドットの位置と点(、)の位置を合わせて書いたり、上段のコメントが左辺の処理、下段のコメントが右辺の処理になっています。

 今まで書いてきた処理を見直しながら、処理にコメントを書いてみてください。
しっかりとコメントが記述できるならば、処理が理解できて、読めていることになります。


代入処理による処理の読み解き方


 代入処理は基本処理の1つです。
左辺に右辺の値を代入する処理ですが、必ず双方の型が同じ型であることが条件になります。

transform.position = new Vector3(0, 180, 0);

 上記の命令文であれば、これは、

このスクリプトがアタッチしているゲームオブジェクトの Transformコンポーネントの情報を利用し、(← これがドットの位置になります)
Transform コンポーネントの管理している Position の値に、右辺の情報を代入する

という処理になります。

 この時点で、型が変更になっていることに注目してください



 Transform コンポーネントの型は、その通り、Transform 型です。
それに続けて記述した position 変数、これは、x, y, z の情報を持つ、Vector3 型になります。

 代入処理は、左辺 = 右辺 が鉄則です。
このとき、左辺とイコールで結ばれる右辺は、双方の型を確認して処理の照合を行っています。

 今回の処理であれば、

Transform.Vector3 = Vector3

 という処理になっているため、左辺と右辺の型が、同じ型であることがわかります。
そのため、代入処理が成立しています。
 気づいたと思いますが、ドットによって1つのつながった処理になっている場合、最終的な型は、最後の変数の型になります。

 以上のことから、C#の処理は常に、変数の値と、その型を見極めて読み解いていく必要があります。



 Unityでは、int 、string 、float といったC#全体で利用している型の他に、
自作したスクリプトの型や、Unityが用意してくれている型(Transform、Vector3、Rigidbodyなど)と、非常に多様な型があります。

 ですが、代入処理の基本は、左辺の型 = 右辺の型 です。もしも迷ったら、わかりやすい int 型などの処理を思い出してください。

int x = 0
x = 10;

 この処理も、イコールで結ばれていますので、双方の型が同じであることが分かります。
int 型は整数の情報を扱う型ですので、整数の実数(0とか10とかの数字)、あるいは、整数の代入されている int 型の変数を利用することが出来ます。

int x = 100;
int z = 200;
x = z;

 この処理結果は、x の値に z の値を代入する、という処理になりますので、x の値は 200 になります。
すべてこの処理と同じです。変数や型に惑わされないように、1つずつ、変数の型を確認した上、処理を読んでみてください



 プログラムの処理は読み慣れてくるまでに、非常に時間がかかります
あせらずに復習をして、しっかりと変数、型の情報から、処理を読み解ける学習をしてみてください。
処理が読めるようになってはじめて、処理を書くことも出来るようになります。

 プログラムの学習は大変ですが、近道もありません。
地道に毎日、コツコツとがんばっていきましょう!
必ず結果がついてきてくれます。