はじめに
プログラミング経験のない友人がUnityを始めたので、応援記事を書いていきます。
ソースコードは簡略なものにしています。 なお動作確認は .Net Fiddle を利用しています。
ブログで目指すこと
全体を通して目指すこと
本ブログはごくごく親しい友人が「Unityを触りてぇ!」となり、途中で色々と苦心しているようなので、口頭で解説した内容を参照できるようにブログにおこしていくものになります。 多分UnityからC#に入る人も居るだろうし、助けになればいいなと。
筆者はC#を学習したことはあるものの業務で利用したことはないため、細かな作法は正しくない恐れがあります。 *1
なお、Unityの学習には次の本を使っているそうです。 僕も買おうかな。
今回のブログで目指すこと
色々と書いていたら長くなったので、次の1点に絞っていきます。
- コードの基本的な読み方がわかる
処理順のイメージを作る
Main
メソッドから始める
プログラムの動作をイメージする時、「どこからプログラムが実行されていくか」を把握していく必要があります。
今回は Program
クラスの Main
メソッドから始まるプログラムを書きます。
using System; public class Program { public static void Main() { Console.WriteLine("Hello World"); } }
このコードを実行すると、お馴染みの Hello World
がコンソールに出力されます。
めでたい。
Main メソッドは、C# アプリケーションのエントリ ポイントです (ライブラリおよびサービスでは、エントリ ポイントとしての Main メソッドは必要ありません)。アプリケーションを起動すると、最初に Main メソッドが呼び出されます。
C#のアプリケーションの場合 Main
メソッドから処理が始まることになっています。
もしも Main
メソッドが書いているコードにない場合には、そのコードを呼び出している箇所をたどっていくと Main
にたどり着く、と理解してみてください。
ソースコードを上から下に読んでいく
Main
メソッドの中を考えていきます。
次のように2行にわたってコードが書いてあるとき、上から順に実行されていきます。 順々に読んでいけばいいので、理解しやすくて助かります。
using System; public class Program { public static void Main() { Console.WriteLine("No.1"); Console.WriteLine("No.2"); } }
コンソールに表示されるのは、次のような文字列です。 ちゃんと上から下に実行されていることが確認できます。
No.1 No.2
では、次のように書かれている場合を試してみます。
using System; public class Program { private static void topMethod1() { Console.WriteLine("call topMethod1"); } private static void topMethod2() { Console.WriteLine("call topMethod2"); } public static void Main() { Console.WriteLine("start Main"); topMethod1(); bottomMethod(); topMethod2(); Console.WriteLine("end Main"); } private static void bottomMethod() { Console.WriteLine("call bottomMethod"); } }
すると、次のような表示が出ます。
start Main call topMethod1 call bottomMethod call topMethod2 end Main
ごくごく当然のように思えますが、話の整理をしておきます。 このコードから確認できるのは次の3つの話です。
Main
メソッドは一番上に書いてなくても、最初に実行される- ソースコードで書かれているファイルの順番ではなく、
Main
メソッドに書かれている順番に実行される - ソースコード上の余白と、コンソールに出力される余白には関連がない
メソッドを作る
当たり前のように Main()
や bottomMethod()
などを書いていますが、これらの「処理をひとまとめにしたもの」を「メソッド(method)」と呼びます。
メソッドは、一連のステートメントが含まれているコード ブロックです。 必要なメソッド引数を指定してプログラムからメソッドを呼び出すと、メソッド内のステートメントが実行されます。 C# では、実行されるすべての命令がメソッドのコンテキストで実行されます。
メソッドはプログラムを作る人の「意思」で作成できます。 個人的な理解ですが、プログラミングは メソッド の集合体を作る作業であって、その結果出来上がるものが クラス であり ライブラリ や ソフトウェア と呼ばれるプログラムです。
つまり、下記のような事柄はプログラムを書く人(プログラマー)の自由です。
- どのような処理を「メソッド」にするか
- 処理をどのように「メソッド」にまとめるか
- 「メソッド」のインプットとアウトプットをどうするか
「価格を渡すと、消費税込みの金額にする」や「ユーザーがボタンをクリックすると、ダイアログを表示する」などなど、メソッドとして作成されるものは多岐にわたります。
「Yボタンを押すと、キャラクターが向いている方向で"しらべる"操作をする」や「文字入力欄を表示して、入力された なまえ をキャラデータとして保存する」ような、そういった処理もメソッドとして定義されていく、そんなイメージができるのではないでしょうか。
なお、先程は「呼び出すと"call bottomMethod"とコンソールに表示する」メソッドである bottomMethod
を作成していました。
補足としては、 Main
メソッドの1つだけ使う、ということもできます。
実際に、一番最初の例では Main
のみ使っていました。
public static void Main() { Console.WriteLine("No.1"); Console.WriteLine("No.2"); }
一方で、2桁の行数を超えるメソッドを書いてくると、だんだん大変になってきます。
もしも Main
メソッドを分割しないまま開発し、数万行を超えてしまったらどうなってしまうでしょうか?
*2
メソッドの分割は非常に難しく、 正解 がわかりにくい作業です。 基本的には「不必要に大きなメソッドを作らない」ことが正解なのですが、どの程度が「不必要に大きいのか」はわかりにくいため、コードを友人や同僚に見せて議論してみることをお勧めします。
一方で コーディング規約 という「C#のコードならこうやって書きましょう」といった指標が示されています。 C#であればMicrosoftが提案するコーディング規約に従っておけば、C#を読み書きできる人にとって共通のルールとなるので、共有などがしやすくなっていきます。
戻り値
「ファーストネームとラストネームを受け取って、フルネームにする」という処理を考えていきます。
String fullName(String firstName, String lastName) { return firstName + " " + lastName; }
String
の firstName
と lastName
を受け取り、それを半角スペースを含めた結合をして返すメソッドができました。
このように返される値のことを「戻り値」と呼びます。
メソッドは、呼び出し元に値を返すことができます。 戻り値の型 (メソッド名の前に記述されている型) が voidでない場合、メソッドは、return キーワードを使用して値を返すことができます。 return キーワードに続いて変数、定数、または戻り値の型に一致する値が記述されたステートメントは、その値をメソッドの呼び出し元に返します。 戻り値の型が void 以外のメソッドで値を返すには、 return キーワードを使用する必要があります。 また、 return キーワードは、メソッドの実行を中止します。
これを実際に呼び出してみましょう。
firstName
と lastName
から、 name
を作ってコンソールに表示してみます。
using System; public class Program { public static void Main() { String firstName = "Taro"; String lastName = "Yamada"; String name = fullName(firstName, lastName); Console.WriteLine(name); } private static String fullName(String firstName, String lastName) { return firstName + " " + lastName; } }
これで String
型の戻り値をもつメソッドを作ることができました。
戻り値が不要な場合は Main
のように void
で宣言することになります。
続いて、メソッドを拡張してみましょう。
例えば「日本式に lastName
+ firstName
で表示する」こともできるようにしていきます。
using System; public class Program { public static void Main() { String firstName = "Taro"; String lastName = "Yamada"; String name = fullName(firstName, lastName); Console.WriteLine(name); } private static String fullName(String firstName, String lastName) { if (isInJapan()) { return lastName + " " + firstName; } else { return firstName + " " + lastName; } } private static bool isInJapan() { return true; } }
今回は簡易的に isInJapan()
というメソッドを作ってみました。
本来はSystemのロケール情報や、ユーザー設定から取得し切り替えるような情報です。
return true;
と書いてる箇所を差し替えることになります。
処理をメソッドを使って切り分けていくイメージができたでしょうか?
今回はここまで。