進化:グラフィックスと力学





今年1月、ゲーム部門はモバイルゲームEvolution:The Battle for Utopiaをリリースしました。 ゲームは好評で、人々はそれを好んでプレイしました。 地下鉄にEvolutionを持っている人をよく見ます。 プレイヤーの間に自分自身を見つけたときでさえ、願い事をし始めました。 そして、KRI 2014での私のレポートに従って作成されたこの投稿では、開発プロセスと「進化」の特徴について詳しくお話したいと思います。



最近、大規模なコンテンツアップデート「Black Legion」をリリースしました。 当然、多くの新しいプレイヤーを惹きつけましたが、最も重要なことは、すでにメインストーリーを通過したほとんどのプレイヤーを返しました。 この記事では、開発プロセス中にゲームメカニクスがどのように開発されたかについて説明します。 使用したサードパーティツールについて簡単に説明します。 そして、グラフィックの「チップ」にさらに注意を払い、弱いデバイスで実際の動的な影と動的な照明を取得する方法について説明します。



ゲームの仕組み



開発の最初の概念では、「進化」は現在とはまったく異なって見えました。 2台のカメラと分割画面があり、2つの軍隊が表示されていました。 それらの間のこの距離はまったく感じられませんでした。 たとえば、ある軍が手g弾を投げます。 画面の中央に到達し、しばらく消えてから、画面の2番目の部分に表示されます。 プレイヤーにとっては不便でした。 私たちはいくつかの研究を行い、さまざまな図を描き、ブレーンストーミングを行い、新しいメカニズムとゲームプレイを思いつきました。 その後、ゆっくりと、これらすべてを実装し始めました。







以前のバージョンでは、自動発砲さえありませんでした。 選択した対戦相手を撃つために、プレーヤーに常に適切なボタンをクリックするように強制しました。 さらに、反動中の弾丸の分散をシミュレートするスコープがありました。あなたが撃つと、スコープが離れて移動し、徐々に収束し始めます。 点灯していなくても、ダメージは少し少なくなります。 筋金入りのオーディエンスでさえ、それはあまりにも複雑でした。 この時点で、ゲームは「Dead Trigger 2」です。 これは、通常の一人称シューティングゲームです。 しかし、驚いたことに、このゲームでは自動射撃が導入されました。 私たちは、同様の制御スキームをEvolutionに導入しようとし、今日のゲームで紹介されているメカニズムに到達しました。







プロジェクトを開発することを恐れないでください。 これは、開発者として支払う必要がある元のゲームプレイの価格です。 オリジナルのゲームの仕組みがある場合は、実際の人で確認する必要があります。何かを拒否しなければならない場合があります。何かを追加する必要があります。



サードパーティツール



私たちのゲームでは、すべてのゲームメカニズムのほぼ80%がGUIを中心に構築されています。 Juggernautでは、独自の設計のGUIシステムを使用しましたが、GUIシステムはまだそこで動作しています。 しかし、Evolutionを設計するとき、市場で提供されているものに注目しました。 それで、NGUIを見つけて、その機能を私たちが持っていたものと比較しました。 その後、彼らは、システムを数か月間完成させるか、既成のソリューションを採用できるかのいずれかであるという結論に達しました。



NGUIバージョン2.2.3を使用していますが、これにはいくつかのバグがありました。 その中に多くのパッチを適用しました。 たとえば、さまざまな解像度の自動スケーリングと、画面を変更するときに大きなテクスチャをアンロードする特別なアトラスマネージャーを作成しました。 このため、画面の切り替え時にラグが消え、メモリクラッシュが停止しました。







これらの建物を見てください、ゲームではそれらはアニメーション化されます。 これは通常のフラッシュアニメーションです。 インポートするために、 uniSWFという別のツールを使用しました 。 彼らはNGUIとうまくやり取りします。



Evolutionで使用したもう1つのすばらしいフレームワークはPlayMakerです。 Evolutionの設計を開始したとき、アニメーション用、および実際にはステートゲーミングマシン(Finiteステートマシンまたはステートマシン)に何らかの技術が必要でした。 当時のMecanimテクノロジーはまだ初期段階にあり、私たちにとって非常に必要なこと、つまりアニメーションセットを切り替えることができませんでした。 プレイヤーは2種類の武器-ピストルとより重いもの:マシンガン、ショットガンなどの戦闘に参加できます。 その開発の状態のMecanimはこれを許可しませんでした。 そのため、PlayMakerテクノロジーをベースとして採用しました。これにより、アニメーションに適したステートマシンを記述することができるだけでなく、スクリプトからロジックを追加することもできます。



照明システム



Evolutionについては、独自の照明システムを作成しました。 一般に、エンジンですべての準備が整っている場合、それを受け取って使用するのはなぜですか? 問題は、Unityに組み込まれたシステムが非常に普遍的であることです。 これらのシステムを保守するには、パフォーマンスを支払う必要があります。 特に、ターゲットデバイスのパフォーマンスが低い場合。 本質的に、FPSでユニバーサル照明システムに料金を支払う必要があります。 したがって、我々は、いわゆるDynamic Light Probeを支持してこのアプローチを放棄しました。 また、Unityにある通常の動的光源も完全に放棄しました。 すべての静的ジオメトリをライトマップで照らします。 キャラクターには、特別なライトプローブと独自のシェーダーを使用します。



ライトプローブは、指定されたポイントの照明に関する情報を含む球面ハーモニカです。 ステージには、このようなライトプローブが多数あります。 エンジンは、キャラクターに最も近い4つのライトプローブを選択し、それらを1つに補間します。 次に、特別な動的光源からの光を追加します。 したがって、動的光プローブ-つまり 動的光を追加した球面調和関数。 その後、キャラクターは球面調和関数で動作できるシェーダーから始まります。







球面調和関数を単純化した方法で想像すると、その機能は立方体テクスチャー(立方体マップ)に似ています。 シェーダーでは、球面調和関数からベクトルを選択します(キューブマップに似ています)。 拡散照明の場合は、表面ベクトルの法線を使用し、鏡面反射の場合は反射された外観ベクトルを使用します。



拡散照明は頂点シェーダーで考慮され、ピクセルで反映されます。 したがって、1つのDraw Callに対して、複数の光源からの動的な照明を使用してキャラクターモデルをレンダリングします。





Mail.Ru Groupに参加する前に、私は数年間エンジンを開発し、ほぼすべてのシャドウおよびライティングレンダリングアルゴリズムを実行することができました。また、Unityレンダリングとシャドウがどのように機能するかを理解しています。 シャドウマッピング、またはPSSM-並列分割シャドウマッピングを使用します。 このような手法を使用して、弱いデバイスで高いFPSを取得することは不可能です。



そのため、私は3つのシステムを開発して、どちらのシステムがより生産的になるかを試しました。 彼は平面影アルゴリズム、または平面上に描かれた影で停止しました。 これは最も単純なアルゴリズムですが、最も生産的なアルゴリズムでもあります。



平面シャドウとは何ですか? これは同じモデルのレンダリングであり、ある軸に沿ってゼロまで平坦化されます。 スケーリング軸の選択は、光源の角度に依存します。



インターネットでは、このようなスケーリングマトリックスを計算する方法の例を多数見つけることができます。 私は他の側面についても説明したいと思います。 1つ目はシャドウブレンディングです。 直接ブレンドすると、次の図のようなアーティファクトが得られます。







複数のポリゴンが交差する場所では、複数回ブレンドされます。 そして、いくつかの場所で影が暗くなります。 これに対処する方法は? これらすべての影を最初にステンシルバッファーに描画し、バックバッファーへの書き込みを無効にします。 次に、すべての影がステンシルバッファに入力されると、ステンシルマスクを考慮して、画面全体を目的の色で塗りつぶす最終レンダリングパスを作成します。 正しいダイナミックシャドウを取得します。これは決して(!)FPSに影響を与えません。 第二に、平面の影は平面上にのみレンダリングできます(理由なく平面の影はレンダリングできません)。







私たちの意見では、これと戦うことは意味がありません。 常に連続した平面に影が置かれるように、コンテンツを再設計しました。



ポストエフェクト



すべてのUnityの例で使用されているポストエフェクトの標準ソリューションは、 OnRenderImageメソッドを使用することです。 その本質は次のとおりです。プログラマーがUnityで作業するだけでなく、ゲームデザイナー、アーティスト、アニメーター、およびその他の専門家も作業します。 それらはすべて異なる資格を持ち、Unity開発者は普遍的な決定を行うことを余儀なくされており、ユーザーは単純にエンジンを取り出して、多少なりとも作業後のプロセスを得ることができます。 この汎用性のため、Unityは次の手法に頼りました。バックバッファーを別のテクスチャにコピーし、処理のために提供します。 ここで問題は何ですか? iPad 2でバックバッファーをテクスチャにコピーすると、FPSの半分以上が削除されます。 OnRenderImageメソッドをさらに処理せずに単純に呼び出しても、パフォーマンスは2倍以上低下します。 これに対処する方法は? カメラを別のレンダリングテクスチャに向け、 OnPostRenderメソッドで処理します。 さらに行う必要があるのは、バックバッファーに結果を描画することだけです。







また、可能であれば、このような強力なピクセルポストプロセスをいくつかのジオメトリックエフェクトに置き換える方法を理解できれば、ジオメトリックエフェクトの方が明らかに高速であるため、これは価値があります。







ジオメトリックポストプロセスについてもう少し説明します。レンダーテクスチャでシーン全体をレンダーするので、後で必要に応じて使用できます。 この場合、狙撃スコープを描画するとき、特別に準備されたメッシュにテクスチャを適用し、そのメッシュのテクスチャ座標は、エッジで屈折の印象が作成されるように引き伸ばされます。 ダイナミクスでは、レンズを通して見ているように見えます。 この後処理はFPSにまったく影響しません。



これらの方法とトリックを使用して、iPad 2およびiPhone 4Sで30 FPS(およびそれ以上)を取得しました。 いくつかの努力により、パフォーマンスの動的な照明と影の点でほとんど自由になりました。 私たちは開発に長い道のりを歩んできました。多くのメカニズムとアプローチを変えて、今見ているゲームを手に入れました。 ご質問がありましたら、コメントでお答えします。



CWIによるプレゼンテーション:





アレクサンダー・チェルニャコフ

ITテリトリープログラマー、Mail.Ru Group Studios



All Articles