1st term 6th week - dsuz/csharp GitHub Wiki
ゲームを作ったりプログラミングをしていると、とにかくエラーがたくさん出ます。エラーは必ず解決しなければいけません。エラーを解決する時は、闇雲にプログラムを修正して動いたとしても、それは良いことではありません。エラーメッセージには何が悪いのかが示されています。エラーメッセージを理解し、プログラムの挙動をよく観察して、何が悪かったのかを理解してからどう修正すればよいか考えるようにしましょう。つまり、トラブルシューティングを論理的にできなければなりません。今回はそれをする方法について学びます。
- CSharp1-6.unitypackage をダウンロードしてプロジェクトにインポートする
Unity では Console にエラー(※)が表示された時には注意が必要である。エラーには種類があり、それぞれ適切な対応をしなければならない。
(※)マークと共に表示されるメッセージが「エラー」である。なお、
は「警告」、
は「情報」である。「警告」は「問題であるとは限らないが、問題かもしれない」程度の意味であり、これが表示されていても「実行できない」ということはない。
Unity のエラーには大きく分けて「コンパイル エラー」と「ランタイム エラー」がある。これらの違いは必ず知らなくてはならない。
コンパイル エラーは、C# の文法エラーである。Unity が C# で書かれたスクリプトに対してコンパイルという解釈する作業をした時に、文法に誤りがあるために解釈できないことで起きるエラーである。見分け方としては、エラーに "error CSxxxx"(xxxx は4桁の数字)という文字列が含まれる。このエラーが起きている間は、シーンを実行することができない。実行しようとすると "All compiler errors have to be fixed before you can enter playmode!" と表示され、実行できない。解決するにはメッセージの通り、文法エラーを修正しなければならない。
エラーの意味を知りたい時は、エラー コードである CSxxxx(xxxx は4桁の数字)を検索する。エラーメッセージを機械翻訳しても、大抵の場合はその意味を理解することはできないでしょう。
なお、このエラーは Console の Clear ボタンをクリックしても消すことはできない。Clear ボタンをクリックしてもエラーが消えない場合は、そのエラーを解決する必要がある。
下のパネルに表示されているエラーの情報は、選択してコピーすることができる。エラーについて人に質問する時は、ここに表示されている情報を全てコピーして伝えること。
「エラーが出た」というだけで何が悪いのか判断できることはありません。何というエラーが出て、それが何という処理に対して出たのかわからなければ、何が悪いのか判断できません。
最近(2022年6月現在)の Unity 2021 のアップデートで、コンパイル エラーを日本語で表示させる機能が追加されました。
ランタイム(Runtime、実行時)エラーとは、プログラムを実行中に例外がスローされ、それが Unity によってハンドルされて記録されるエラーである。見分け方としては、先頭に〇〇Exception と表示される。
下のパネルに表示されているエラーの情報は、選択してコピーすることができる。エラーについて人に質問する時は、ここに表示されている情報を全てコピーして伝えること。
その他に出るエラーとしては、アプリケーションをビルドした時のビルドエラーや、Unity の内部的なエラー(ウィンドウレイアウト機能の不具合など)、パッケージから出力されるコンパイルエラーなどがある。これらも厳密には上記のどちらかに含まれるが、違いとしては Unity の不具合(つまり自分が作ったプログラムを修正しても意味がない)である可能性がある。これらのエラーについては、そのエラーメッセージから判断し、内容に応じて対応する必要がある。従ってエラーメッセージの内容をしっかり理解しなければ解決できない場合がほとんどである。
paiza ラーニングの演習問題 をやりましょう。
ここで覚えておかなければならないのは以下のことです。
- try ブロックには「例外をスローされる可能性がある処理」を書く
- catch ブロックには「例外をキャッチした時に実行する処理」を書く
- finally ブロックには「例外が起きた・起きないに関わらず、try ブロックの後に実行したい処理」を書く
例外は、実行時に正常状態ではない時に発生します。例えば、以下のような場合に「スロー (throw)」されます。
- 変数が null なのにメソッドを呼んだりプロパティを取得しようとした時 (NullReferenceException)
- ゼロで割り算しようとした時 (DivideByZeroException)
- 開こうとしたファイルが存在しない時 (FileNotFoundException)
一般的な(Unity ではない)アプリケーション開発では、例外がスローされた時にキャッチしないとアプリケーションは異常終了します。Unity では異常終了はしません。Unity によりキャッチされているからです。では Unity では例外処理をしなくてもよいかというと、そんなことはありません。例外がスローされると、「メソッド内のそれ以降の処理が実行されなくなる」からです。
- 『独習 C#』9.2 例外処理
問題が起きた時にプログラムの内容を調べて問題の原因を調べることを「デバッグ」という。この時、Console.WriteLine() や Debug.Log() を使ってプログラムのどこが実行されたか調べたり、変数の内容を出力して想定通りに動いているか調べることを「print デバッグ」と言う。これはもっとも原始的なデバッグの方法である。
Visual Studio を使っている場合は「デバッグ実行」することによりブレークポイントでプログラムの実行を一時停止したり、一時停止中に変数の中身を覗いたり、ステップ実行により一行ずつプログラムの実行を進めることができる。これは C# で Windows アプリケーションを作る時にも、Unity でゲームを作る時にも非常に役立つので、積極的に使っていきましょう。
- Assets/1-6/Exception シーンを開いて実行し、エラーが出る事を確認する
- Generator スクリプトを開き、例外をスローする可能性がある処理を try ブロックの中に入れ、catch ブロックを追加する
- もう一度実行する(まだ例外は解決していない)
- catch ブロック内にブレークポイントを設定し、デバッグ実行する
- ブレークしたら、何が問題で例外がスローされたのか調べる
- ステップオーバー (F10) をくり返し、プログラムが一行ずつ実行される様子を観察する
- 『独習 C#』1.3.3 デバッグの基本
- Unity + Visual Studio でのデバッグ機能(動画)
- Unity でのデバッグ実行
- Windows アプリケーションを作る時のデバッグ実行
paiza ラーニングの演習問題 をやりましょう。引き続き この問題 もやりましょう。
ここで覚えておかなければならないのは以下のことです。
- Dictionary は、キー (key) と値 (value) のペアのリストである
- Dictionary は、List のように要素を追加・削除・挿入することができる
- Dictionary は、キーを配列のインデックスのように指定することで(例: dictionary[key])値を指定することができる
- キーと値には任意の型を使うことができる
- キーは重複することができない
- foreach を使って全ての要素をループすることができる
- 『独習 C#』6.4.1 Dictionary(ディクショナリ)
クラスの完全修飾名を毎回指定するのは面倒なので、コードの先頭に
using 名前空間;
と指定することにより、クラスを単純名で記述することができる。
例えば、以下の2つのコードは同じ意味である。
using UnityEngine;
using System.Collections.Generic;
public class UnityComponent : MonoBehaviour // 単純名
{
List<int> iList = new List<int>();
// (略)
}
public class UnityComponent : UnityEngine.MonoBehaviour // 完全修飾名
{
System.Collections.Generic.List<int> iList = new System.Collections.Generic.List<int>();
// (略)
}
Visual Studio の以下の機能を知っておくとよい。
- あるクラスの完全修飾名を知りたい時、Visual Studio を使っていれば、クラス名にマウスポインタを合わせてしばらく待つと、完全修飾名が表示される
- Visual Studio 上では、使われていない using 命令は薄く表示される
- using 命令がないためにクラスが認識できない場合、エラーにマウスを合わせてしばらく待つと、Visual Studio によりどのように修正したらよいか提案される(自動修正機能)
- 『独習 C#』
- 1.3.2 ソースコードの全体像
- 9.1 名前空間
- 9.1.2 名前の解決
- paiza ラーニングの C#入門編9: Dictionaryの基礎, C#入門編10: 例外処理を理解しよう の演習を全て正解する
- 合計 16 問あります
- 受講する(動画を見る)必要はありませんが、演習が解けない場合は動画を見て学んでもよいでしょう
- 動画は見ていなくても受講済みにしてしまって構いません