なぜにいまさら Unity?
うんまあ正直言うと、主観的な感情論を言うと筆者は別に Unity が好きってわけじゃない(でなきゃとっくの昔に勉強始めてた)、というかむしろエンジンの中では好きでない方です。理由はいくつかあって、その中で一番大きいのは「効率が良くない」、ですかね。特に 4.X 系まで(5.X 系は良くなったと信じる)。あと自分が知ってる既存の Unity で作られたゲームの中では、ある特徴があって、みんなシーンの切り替え(例えばゲーム画面からメニュー画面を呼び出すときとか)が非常に遅いのです。これは Unity が悪いのかプログラマが悪いのかは知らないのですが、少なくとも筆者の Unity に対する印象はあまりよろしくないのが否めないのです…
ところが Microsoft が去年 HoloLens を発表しました。素晴らしいです。最近のマイクロソフトさん超絶にイケてます。早くいじってみて何か作ってみたいのです。でも未だに SDK が公開されてません。それに公開されたところで、マイクロソフトさんのことですからフレームワークは .NET でしょうし開発言語も C# でしょう。でも C# なんて触ったことがまったくないし文法すら知らないから仮にいきなり SDK 公開されたところで何もできない。
ここで Unity の出番です。3D 開発の勉強もできてついでに C# の勉強もある程度できるから一石二鳥じゃないか。というわけで早速教材買ってきました。
さてこの記事の目的はというと、Unity やってみたいけど Unity 経験がまったくない Swift 開発者(世の中に果たして何人いるでしょうか…)のために、つまづきやすいポイントをピックアップして、その対策を伝える、もしくは意見を伺うことです。
命名規則がイマイチ慣れない
うんまあこれも我慢するしかないのかな。C# も Unity も初心者どころか今まで触ったことがまったくないのでどっちのせいなのかは知らないのですが C# の命名規則のせいですね、とりあえずどうやら Unity で C# で開発する時、メソッド名もアッパーキャメルケース(UpperCamelCase、略してUCC)です。これ慣れの問題かもしれませんが、ただ正直これソースコード読むと分かりづらい部分あるんですよな…
例えば Swift(以前の Obj-C も同様)の場合、UCC はクラス名、フレームワーク名などと言った「抽象的なものの定義」にしか使わないので、具体的なもの、つまりクラスから生成された具体的なインスタンス名や、そのインスタンスに自然と入るプロパティやメソッドは全て LCC(lowerCamelCase、UCC との区別は 1 文字目が大文字か小文字かです)です。ところが Unity の場合、メソッド名も UCC ですので、一瞬「あれ?これは何かのオブジェクトを作るんだっけ?」って反応になっちゃいます。あ、でも C# だから、オブジェクト作る時 new
のキーワード入るからそれみればいいのか。
IDE の補完がクソすぎる
うんまあこれは多分どうしようもありません。頑張って慣れるしかないのです。
ちなみにどこが一番クソかというと、先頭文字入れて補完リストが出てきたけど、うっかり間違った補完を選んでしまった時。この場合、間違った補完されたテキストだけ消しても補完リストがもう一度出てくれない(Visual Studio と同じ仕様)。なんとかなんないの?
あとはこれはおそらくこれ Unity 5 の改悪ですけど、Swift は 2 から大幅に大域関数を削除してなるべく protocol に入れたっていうのに、Unity 5 がむしろ逆にもともとインスタンスメソッドやプロパティにあったものを大域関数に変更したという。(例えば上記の教科書の Lesson 2 のサンプルコードにオブジェクトの速度ベクトルを取得するコードですが、Unity 4 の時は rigidbody.velocity
で取得できたものを Unity 5 の時 GetComponent<Rigidbody>().velocity
で取得するようになった)。これの何が問題かというと大域関数が多いとなかなか補完がすぐ出て来ないということになるのです。ただでさえ補完がクソなのに。
言語仕様的にオーバーライドが明示的でないからたまにパニックる
これある意味補完がクソの延長線になるものですけど、要するにゲームオブジェクトクラスのサブクラス作るじゃん?んでそのサブクラスで親クラスのメソッドをオーバーライドしたいじゃん?そしたらね、親クラスのメソッド名を入れても補完してくれないのですよ。だからメソッド名を律儀に全部入力しないといけなのですが初心者だからたまに「あれメソッド名ってこれでいいんだっけ?」ってなります。小さなスペルミスのためにいろいろ探し回ったりすることもありました。せめて補完が効いて欲しいですね。その上さらに Swift みたいに明示的なオーバーライド文法ならベストなのですが、まあ何年も前の C# に最新の Swift の仕様を求めるのもひどいしそんなこと言ったら Obj-C だって明示的オーバーライドじゃないじゃん?ってなるから黙っておきます。とにかくこれ仕様だから初心者のうちに様々な既存メソッド名を覚えておくしかないのです。
実行する前に自動保存してくれない
実行する前に忘れずに保存しましょう。Unity は実行前の自動保存機能がない(っぽい)ので実行する前に必ずファイル保存しましょう。
まあでもこれはちょっとなんとかして欲しいところですね、Xcode の癖でちょっと細かいソースコード修正して実行してみたら「あれ?さっきと変わらんぞ??」ってなったことが何回かありました。まあ幸いエディターに保存していないファイルに印をつけてくれているのでこれで少なくとも保存していないファイルのピックアップはできますが…
2016/02/09 追加
「抽象クラス」が便利そう
まあありますよね、子クラスでオーバーライド前提のメソッド。Swift の場合は protocol
は確かに extension
ではなく本体で定義したメソッドは全て実装側できちんと中身定義しないといけないように作られていますが、それはあくまで共通なプロトコル、もしくは C# で言うところの共通のインターフェースというものであり考え方としては全くの別物ですし。まあここら辺は Cocoa の書き直しもかかってるわけですから多分当分の間は難しそうかもしれませんが…
まあとりあえず今の所はこんな感じかな?また何か気づいたら随時追加する予定です。
いや別に Unity を dis るつもりはないのですよ?ただいろいろつまづいたり慣れなかったりするポイントをある程度まとめて Unity やるときにここら辺注意しておこう、というのが目的です。テキストが dis ってるように見えるのはきっと筆者の心が汚れているからでs(ry