ディザリング透過や壁を考慮したカメラワーク [ゲーム開発ログ 2020-09-21]

2020-09-21

テスト用マップ

ゲームに使えるちゃんとしたカメラを実装しようと思い、まずはテスト用のテスト感あるマップを作った。

工作用紙っぽい見た目。 子供の頃に工作用紙で色々と紙工作していた思い出が蘇ってきて、なつかしい気持ちになった。

ちなみに 1 マスが Unity 上で 1 メートルのスケールになっている。 木以外のオブジェクトは Unity のエディタ上で ProBuilder を使って作成。 Unity はホント便利だ。ありがとう Unity。

それっぽいカメラワークと、ディザリング透過シェーダ

壁際に来たときにカメラが寄る挙動を実装した。3D ゲームでは定番のやつ。 これはこうしたいというより、カメラが壁にめり込んで壁の裏側を見せてしまわないようにするため、 仕方なくこうしなければならないという感じの実装。

カメラは遠くなった時に見下ろすような形、近くなった時に見上げるような形になるように視点の補正をかけている。 これも右スティックでカメラを操作するサードパーソン視点のゲームではよくある挙動かと思う。

カメラの実装はこんな感じ。パラメータで細かい挙動をいじれる:


キャラは、カメラに近づきすぎたら疑似透過で半透明を経てからフッと消えるような処理をシェーダに実装。 3D ゲームではよく使われている手法かと思う。

同じ原理で、壁じゃないちょっとした障害物(木)はカメラの近くにきたら早くからフェードアウトを始める。 ポケモン剣盾 のワイルドエリアでも似たような処理が施されていたので、 実装にあたって久しぶりにポケモン剣盾を起動してよく観察した。

この疑似透過はいわゆる ディザリング抜き とか呼ばれるやつで、不透明の描画パスで擬似的に半透明を表現する定番処理。 見栄えはいまいちだが、軽い… というより半透明描画パスが重いので、半透明を使わないためによく採用される手法。

実装は以下のような雰囲気:

void DitheringByCameraDistance(Varyings input)
{
    float2 screenPos = input.positionCS.xy / _ScreenParams.xy;
    float2 ditherCoord = screenPos * _ScreenParams.xy * _DitherPattern_TexelSize.xy;
    float dither = tex2D(_DitherPattern, ditherCoord).r;

    float ditherRange = _DitherCameraDistanceFrom - _DitherCameraDistanceTo;
    float alpha = (input.cubicColor.w - _DitherCameraDistanceTo) / ditherRange;
    alpha = max(_DitherMinAlpha, alpha);
    clip(alpha - dither);
}

ディザリングパターンのテクスチャには、Bayer Matrix で検索すると出てくるような小さな市松模様の画像を指定する。

アスペクト比と画角について考える

2020 年現在、この地球で使われているモバイル端末には、大体 4:3 から 21:9 くらいまでのアスペクト比のバリエーションがある。

横持ちのゲームを Unity で素朴に作ると上下の画角が固定され、 「横長の端末ほど広い範囲が見える」ことになる。 4:3 の iPad が一番見える範囲が狭くなる。

まあカメラを自由に左右に回せるゲームなら別にこれでも許容かなという気もするが、 16:9 より「長い」端末が多い昨今、やはり iPad の視界が狭く見える感は否めない。

「4:3 の時は画角を 10 %広くする」みたいな処理を入れるかもしれない。

自前実装のバーチャルパッド

モバイルゲームのバーチャルパッドは操作感悪い印象が強くてあまり好きではなかった。 実際、Unity の Standard Assets に入っているようなものをそのまま使うとかなり操作しづらい。

自分で納得のいくものは自分で実装しないと手に入らなそうだったので、実装してみた:

左手で移動、右手でカメラのよくある操作。 自分で実装して細かい調整をしたら「全然これでいいな」という気持ちになったので、 この操作方法でいこうと思う。

基本的に移動だけでどうにかするゲーム(攻撃ボタンやジャンプボタンを置かない UI)にしようと考えているので、 誤操作の心配も少なそう。

余談

操作感を試してもらうのに友人達にもさわってもらったのだが、 手のでかい友人が「この一番長い端末、左右に指を置いてもプレイエリアが広く見えて快適だな」 と言っていてなるほどと思った。

21:9 の Xperia 10 はこんなに長くてどうするんだ… みたいに思ってたけど、 たしかに横持ちのバーチャルパッドで操作するゲームは遊びやすそう。 (音ゲーはやりづらそうだけど……)