こんばんわー
この記事では自分が個人Unityゲーム開発者をしていて心にとめておいた方が良いと感じたことについて書いておきます。
Unity版リーダブルコードというか、途中知ってたら楽になる、みたいな記事が書けたら良いな。
Unityじゃなくても個人開発者に通ずる、たびたび耳にする教訓みたいなものも書いておくので、ゲーム開発者なら共感する部分もあると思います。
第1章 愛と涙の心得編
この章ではゲーム開発者としてスタート地点に立つための心得を置いておきます。
言葉よりも先に手を動かせ!
残念ながらTwitterなどで「今日からやります!」とか「Unityを勉強します!本買いました!」っていう人ほど消息を絶ちやすい。おそらくこれは「やる気があることを示した」という事実でもう満足してしまっている人だと思う。強い個人開発者はスクショで語る。
とりあえず動けば良い!
ある機能について「理解を完璧にしてから」は無理だし挫折しやすい。「自分の作りたいゲーム」が「動く」ことまで最短距離でダッシュしろ、かかる時間は少なければ少ないほど良い。最悪(常識の範囲内で)コピペでも良い。Googleをフル活用しろ。
リファクタはするな!
これは特に初心者に言いたい。ゲーム開発初心者はコードを書く機会が増えたためプログラミング技術の実感を感じやすく、すぐリファクタしたがる。たしかにそれは上達する良い機会だが、残念ながら初心者のリファクタは間違いが多い。特に変にクラスを作ってしまうとかえって保守性が悪くなる。初心者のうちはUpdate内に直書きしていけ。
アセットを買え!
特に3Dの場合はもはやアセットを買うだけでゲームができてしまう。自分がなぜゲームを作るのか、どんなゲームが作りたいのかと相談してフルスクラッチは最後の手段にしよう。
最初は簡単な動作から作れ!
最初からAPEXやFortniteのようなゲームは作れない。最初は「四角形をプレイヤーが動かせて、四角形が弾を発射するようになって、四角形がキャラクターに置き換わる」のように加算式で開発をしよう。そうじゃないと「動いた」という達成感が得られないため挫折しやすく、どの機能も中途半端なまま終わりやすい。
アイデアをちゃんとまとめろ!
アイデアは出しても良いが、実装の順番をつけよう。必須項目と「あったらいいな」という項目に分けよう。じゃないとどこから手を付けたらいいか分からず、作業開始のモチベーションが低くなる。
デバッグはできるだけするな!
機能ごとのデバッグはその時に必要だが、ゲーム全体のデバッグは後回しにしよう。じゃないとデバッグに時間がかかりすぎてなかなか全体像が見えてこない。一通り実装を終えたあとデバッグすることで後どの程度で完成するのかが実感できる。
第2章 友情のエディター編
この章では「言われないと分かんないよぉ」となったポイントについて解説していきます。
UIはUIを使え!
UIは専用のUGUIが存在する。create→UIからImageやButtonなどを生成できる。UIはCanvasというオブジェクトの子として生成されて分かりにくいが、UI系はすべてこの中に入れるものなんだと理解すれば良い。間違ってもWorld座標のSpriteRendererなどで作らないように(ただし位置が関係するような特別なUIを除く)。特にButtonやScrollViewなどはどのゲームにも必須とも言える。
神のアセットを使え!
TextMeshProやDotweenは誰もが使うような神アセット。あるとないとでは選択肢の幅や難易度に大きな違いが生じる。こういう便利なアセットがあるということを覚えておき、いつでも利用できるようにしておこう。
Vector3は右クリックでコピーしろ!
Vector3やColorなどはエディター上でも右クリックでコピーできる。
裏切りのスクリプト編
ここにはスクリプトを書く際に普段使っているテクニックを残しておきます。
GameObject/コンポーネントのインスタンスはSerializeFieldでアタッチしろ!
GameObjectやコンポーネントをScriptで制御するときFind()してますか?それ[Serialize Field]を変数名の前に付けるだけでstring直書きしなくてもよくなりますよ。
シーン間で値を共有したいときはstaticを使え!
staticはあまり使用が好まれていない(理由は謎)ですがScene間で変数を共有したい時、例えばステージセレクトシーンとゲームシーンがあり、ステージセレクトで選んだボタンによってステージの構造を変えたい場合はStaticを使おう!staticではシーン遷移で値が変更されずかつインスタンスを用いない参照ができるのでクラス名.変数名で簡単にアクセスできる。
UpdateではTime.deltaTimeを掛けろ!
ちなみにFixedUpdateでいいじゃん、っていう人はもう宗派が違うのでそれ使ってください。Updateでは1フレームにかかった時間が違うのでいいスペックのパソコンは速く移動し、悪いスペックのパソコンは移動が遅くなる、ということがありえる。必ずオブジェクトの移動や回転には値 * Time.DeltaTimeをすること。
配列を使うな!リストを使え!
配列とリストの基本的な使い分けは「数が固定なら配列」だが、基本的にすべてリストを使おう。じゃないと自分がリストを再開発することになる。
回転にはLocalEulerAngleを使え!
Quaternionとかあるがこれで回転を設定するのは素人には無理。より簡単なEulerAngleがどっかにあるからそれを使おう!
ネストは浅くしろ!
例えば以下のコードはネストを浅くすることができる。
if(mustBeTrue == True){
aaaa = 0;
}
//は
if(!mustBeTrue) return;
aaa = 0;
三項演算子を使うことも視野に入れよう
whenAbeC = D;
if(value == A) whenAbeC = C;
//は
whenAbeC = value == A ? C : D;
となる。ネストを浅くすることは見やすくなるだけでなく関数化が簡単になったり、より簡潔な表現が見つかる。もし「下にも別の処理が続いてreturnは使えないよ」という方は関心を分離することをお勧めする。
おしまい!
いかがでしたか。ちょっときつい口調で書いてしまったのですが、それによってより当事者意識を持ってくれればなと思っています。まぁこんなの覚える必要はなく、忘れてもらって構いません。記憶の奥の奥に置いておいて、いつかふと思い出す「たしかあんなこと言ってたな」
ぐらいでだいぶ変わると勝手に思っています。
最後に僕の好きなフレーズというか、20年の短い人生で学んだことを一つ置いてお別れのあいさつにしたいと思います。
「人間同じような能力、
同じような思考の奴らが数百万といる。
彼らと自分の違いは
やった か やってない か。」