何を考えながらゲームプログラムをしているの?
どうもいーだと申します。
現在2つのチームでゲームプログラマ(自称Unityエンジニア)を担当しています。(@necromance_chan,@Snym_Games)
ふとプランナーの一人に『どうやってプログラム組んでいるのか』と問われたことをきっかけに、本記事を筆記しようと思いました。
(最初に断りますが、本記事はあくまで個人の見解であり完璧なものではありません。また、ここでのゲームプログラムはUnityで開発ということです。ご了承お願いします。)
では本題に入ります。ゲームプログラム、特にUnityやUE4での開発は文字ベースのコーディングとは少し異なり、コンポーネントと言う考えでゲームを構成されています。コンポーネントは簡単に言えば部品です。(詳しくは下のリンクのスライドに詳しく書いてあります)
『コンポーネント指向を理解する必要あった?』
と思うかもしれませんが、ゲームプログラムでの機能の実装はこのコンポーネントとC#の組み合わせから作られるもので大事なことです。
コンポーネント指向を理解した上で次に進みます。
ゲームプログラマとして何か実装したい時に必ず考えることが三つあります。
(1) そもそも実装できそうか
(2) 拡張性のある実装か
(3) 負荷のかからない実装か
実際にできるかどうかは置いといて、少なくともゲームプログラマであれば同じようなことは考えていると思います。ただ『考えるだけ』と言ってはこの記事の意味がないので、それぞれをもう少し掘り下げていきます。
一つ例にとって解説していきます。
プレイヤーから弾を発射する
を例にそれぞれ当てはめていきたいと思います。
ここでは具体的な処理の仕方やコード内容については言及しません。(要望があればやりますが)あくまで流れを知って欲しいです。
(1)そもそも実装できそうか
開発のフローを例に当てはめると次の通りです。
1. 仕分け
必要そうなプログラムを仕分していきます。
・弾の処理
・プレイヤーの動き(エイム)
・発射するメインの機構
大きく分けるとこんな感じでしょう。
実装する前は、まず何が必要なのか仕分けすると後々楽になります。
2.必要そうなコンポーネントを把握
仕分けが終わったらどんなコンポーネントを使おうか考えます。
・弾のプレハブ
・弾のTransform
・プレイヤーの Transform
・プレイヤーの動き用のスクリプト
・発射命令用のスクリプト
(スクリプトをどう分けるかは個人の自由です)
...etc.
とりあえず動き自体に必要なものだけピックアップしました。慣れていくと頭の中で「これ(コンポーネント)を使おうかなぁ・・・」と解っていきます。
3.コーディング(プログラム)
ここで詰まることが多いですが、どこがわからないのかを1で仕分けたものよりさらに細分化しましょう。細分化した後は天下のGoogle先生に投げつけましょう。[わからないこと + unity] で調べれば大体のことはでてきます。
また調べる時に『何を取得すればいいのか』などを意識して調べていくと正解や、それに近いものを見つけることができると思います。(調べ方についてはまた別の機会でまとめます)
後何か詰まったら言語化とビジュアル化するとわかりやすくなります(割とオススメ)
ホントは参考画像を載せたいのですが、内容が内容なのと汚いので割愛させてください。
4.動作確認
不具合がないかを確認します。
1~4の流れを基本に仮組みの実装を行なっていきます。
(2)拡張性のある実装か
正直『(1)そもそも実装できるか』が終わってからがプログラマの仕事かと思います。
『拡張性、拡張性って動けばいいんじゃない?』
ゲームプログラムは機能を一回実装したら終わりということは少なく、基本的には上乗せしていく感じで拡張していくものです。
もし、拡張性を低く作ってしまうと、新しい実装をしたい時に前のスクリプトを元に書き直さなくればならないことが発生します。
(プログラマなら誰でも通る道...なはず)
最初から拡張性を意識すると、こういった問題は少なくなるはずです。
またチーム開発をするのであれば尚更、拡張性ある実装が好ましいですよね。
では弾の発射の機構を例に簡単ですがまとめてみましましょう。
・弾の種類を変えられるようにする
・弾の発射の出方を変えられるようにする
・発射間隔を変えられるようにする
...etc.
といったところでしょうか。ゲームのパラメーターを変化させる感じですよね。・・・正直骨が折れます。
究極はプログラマ以外の人でも簡単に変えられるようにすることです。
余談ですが、UnityのInspectorに日本語でどんな変数なのかを添えてあげるとinspectorをいじる人もニッコリ、同時に3ヶ月の自分もハッピーになります。(怪しいやつではありませんよ?)
(3)負荷のかからない実装か
拡張性と同じくらい重要なことです。ゲームが重くては快適に遊ぶことはできません。(嫌ですよね、カクカクのゲームをプレイするのは)
FPSとUnityであればprofilerとにらめっこしながらプログラムします。もちろん限界はあります。
弾の発射の機構を例にしてどこを最適化すればいいのかをあげてましょう。
・弾のオブジェクトプール
と他にもありそうですが...。中々負荷を減らすにはどれを最適化すればいいのか探すのは大変です。
話を戻しまして、弾のオブジェクトプールの実装についてですが、一言で言えば弾の使い回しです。この技術は大量にオブジェクトが発生するゲームにはほとんど使われている技術です。
詳しくは下のリンクで見てみてください。
(特に昔のゲームはメモリが足りないから使い回でそれぽく見せて頑張ってました)
負荷のかからないように最適化できていくと必然とプログラムは洗練されていきます、プログラマの人は頑張りましょう。(自戒)
__________________________________
以上が普段実装する時に考えていることの一連の流れでした。
まとめ
コードの話などは省いてしまい逆にわかりづらくなってしまった気もしますが、いかがだったでしょうか
。
何かわからないこと、質問があれば質問箱まで。300文字超えるようでしたらnoteでまとめます。
ここまで読んでいただきありがとうございました。