お断り
本記事はUnityをdisる意図100%で書かれた記事である。しかし、本記事に書かれている内容は、あなたのマサカリを握る手が萎えるほど、初歩的である。難しい概念や最適化の議論をすればUnityはそれほど悪いものでもなかろう。何事も一長一短である。それを了解した上で本記事で主張したいことは、しかし、初歩的な部分に難があるために、初心者プログラマあるいはUnity初心者にとって短所が多く・むしろ害となりうる、ということである。
本記事は心の叫びを殴り書いたものである。それほど整理もされていないし・文章も冗長である。ご容赦いただきたい。
Unityの良い点
初めに、Unityの良いところを挙げるとしたら、何よりもまず、車輪の再発明をしなくて良いという利点が挙げられる。
趣味とビジネスは違う。ビジネスでゲームを作るならば、ゲームエンジンのメンテナとして割かれる人員を減らせた方が高効率であるに決まっている。確かに、自社製のエンジンを作るメリットとして、独自の機能を追加するだとか・ドメイン特化な最適化を行えるだとかの点が考えられるが、Unityはパフォーマンスを度外視するならば殆ど何でもできるように作られているし・Unityのプロフェッショナルになれば最適化もできよう。これは覆しようのない大きな利点である。
また、オブジェクトの配置を視覚的に行えたり、デバッグプレイ中に一時的にデータを変更できたり、等々、Unityは非常に便利な機能を備えている。試しにゲームエンジン(というより専用エディタ)なしのコード直書きのみでRPGを作ってみればわかるが、やってられないほどコード量が膨れ上がり・非直感的で虚無な作業を強要されることだろう。これを避けるにはエディタを作ることになるが、つまり、Unityは初めからこれを提供しているのである。
Unityの悪い点
バイナリファイル
Unityにおいて、オブジェクトの関係はエディタ上のヒエラルキーやインスペクタから設定する。つまり、コードベースではない。そのため、コードだけ見ていても、オブジェクトの関係を把握できない。あるクラスについていつ・どこで・誰に・なぜ・何が・どのように使われていているのか分からないことが多々ある。また、そもそもUnityにはコンストラクタで動的にインスタンス化するという概念がないので、フィールドの初期値もインスペクタから設定することが多い。そのインスペクタの設定はコード上の宣言部の初期値より優先される。そのため、フィールドの初期値を変えるにはインスペクタを見る必要がある。しかし、そのくせ、あるスクリプトがどのオブジェクトにアタッチされているのか検索できないので、結局ヒエラルキーを人力でトラバースするかエスパーすることになる。
上述した通り、メタ情報はコードベースではなくバイナリファイルで管理されている。そのため、diffを見ても変更内容が分からない。スクリプトもそのコード自体は読めてもそのメタ情報を把握できないのでレビューしづらくて仕方ない。また、バイナリファイルであるがゆえに、同じものを少し編集しただけでもコンフリクトが発生し、しかも、バイナリファイルであるがゆえに、上手くマージできずどちらかの作業をやり直すことになる。特に、シーン上のオブジェクトを配置・編集等するとシーンの.unityバイナリファイルが変更されることになるが、オブジェクトの配置・編集なんて頻繁に起きるので、同じシーンを担当している限り避けようがない。
さらに、そのメタファイルは大量に生成される。1ディレクトリ・1ファイルに1個生成される。追跡ファイルの数が膨れ上がり、diffが見にくくなる。さらに、ディレクトリにも生成されるので、中身がすべてignoreされた結果追跡対象から外れたディレクトリのメタファイルだけが残るという状況が起こり得る。視界の邪魔。また、どうやら内容も似ているらしく、リネーム差分として記録されることも多い。その結果、しっかりとブランチを更新していないと、コンフリクトが起こる可能性が格段に高くなる。
プレハブ
Unityのオブジェクトは動的にコンストラクションするという概念が存在しない。原則必要なパラメータはインスペクタから指定し、そうして「特化」したインスタンスをプレハブとして保存しておく。ゲーム実行時はプレハブ化されたインスタンスをシーンに実体化(Instantiate)する。このように、必要な物を予め作っておくという流儀がある。これは直感的である。理想的である。理想的であるから、無理が生じる。特に、オブジェクトの設計が変わった途端、すべてのプレハブに影響が出る。コードベースではないのでマウスでカチカチ設定し直すことになる。時間の無駄である。かといって、インスタンスを生成した後にセットアップメソッドを呼ぶのは「っぽ」くない。そうせざるを得ないときは、漠然とした罪悪感を抱くことになる。
また、表示数の変わるUIにおいても、予めスロットを作っておいて、それを動的に設定することになる。つまり、例えば、残機数表すバッジを並べたいとき、普通は残機数だけバッジを表示をしたいが、Unityでは予めバッジを表示できるスロットを作っておいて残機数だけスロットを埋めていく、という方針を取る。となると、スロットの数だけマウスカチカチが増える。当然ながら設計が変わればその分増える。ヒエラルキーも汚れる。この方針には一長一短あるが、個人的には嫌いである。
座標系
座標関連にも問題がある。まず、標準設定では画面サイズが固定されていないので、正確にUIを配置できない・かつ簡単にUIデザインが崩れる。画面サイズを固定するには色々方法があるようだが、色々方法があり、大変面倒くさい。実際、「UIが崩れるので画面サイズを変える際はアスペクト比を保ってください」と注意書きが書かれているゲームもある(当然同人ゲームに限る)。
子オブジェクトの座標系も時に牙を剥く。子オブジェクトの座標系は親オブジェクトのTransformに影響を受ける。これは良い、直感的だ。しかし、あるルートオブジェクトのTransformの影響を受けない子オブジェクトを作ろうとすると、しかし、プレハブのルートオブジェクトを変えられないために、新しいプレハブを作るかプレハブを作り直すことになり、大変面倒くさい。また、Canvasオブジェクトにも問題がある。PanelのScaleは親オブジェクトのサイズを基準にするが、ImageのScaleは自身のサイズを基準にする。pxなのか%なのか統一されているか・選択できれば良いのに、なぜ暗黙の了解とするのか。
Unity
重い。Unityエディタ自体が重い。Unity Hubですら起動に時間を要するし、Unity本体は尚要する。Unityを起動する度にイライラする。マシンのスペックが低いから? よしんばそうだとしても、フルスクラッチでゲーム開発すれば理論上メモ帳とターミナルだけで済むので、少なくとも編集画面はずっと高速である。しかも、容量も重い。Unityは頻繁にバージョンアップするくせにパッチバージョンが変わっただけでも警告が出る。すると、複数のUnityをインストールすることになる。1バージョン10GBあるにもかかわらず。ついでに、ゲームも重い。いや、ゲームが重いのはおおよそゲーム開発者が悪いのだが。ちゃんとUnityの最適化の知識を付けていないと、やたらコライダーを作ったり、重いアセットを使ってしまったりと、簡単にゲームが重くなる。
何よりUnityの問題点であるのは、しばしばUnityの良さとして語られる「初心者でもゲームを作れる」という点である。Unityを使えば、本記事に挙げたUnityの問題点を問題点とも思わない技術レベルの初心者でもそれっぽいものが作れてしまう。勿論良いことだ、どんなクソゲーであろうと作った奴が一番偉い。しかし、そして初心者はUnityに籠もってしまうのである。Unityでゲームが作れるなら、わざわざUnity以外に手を出そうと思わないのである。その結果、一向に設計の技術だとか、ともすればプログラミングの技術自体が成長しない――Unityの使い方ばかりを覚えて、ゲーム開発の原理を習得しないのである。これはある課題に対して既存の機能ありきで解決してしまうことを意味する。例えば、遅れて対象を追求するカメラが欲しいとき、しかしUnityがこの追従機能を提供していない限り、不可能だと行き詰まる。つまり、本来「工数を減らすための便利な機能」であるものが「課題を解決するために必須の機能」に変貌しているのである。これはフレームワークやライブラリの意義を大きく曲解している。さらに、そのような初心者たちが新たな初心者を呼び込み、またその初心者が初心者を呼び込み……、Unityだけで閉じた悪質な無駄に大きい無知のコミュニティを形成する。これはカルト宗教と構造が何ら違わない。断じて悪である。
以上
以上のことから、私はUnityが嫌いである。
■