今回はゲームでよく聞くフレームとは何かという解説をしていこうと思います。
↑の動画でも解説しています。今回の解説は動画の方がわかりやすいと思うので是非ご活用ください。
<フレームとは>
さて、皆さんはこんな事を聞いたことは無いでしょうか?「映像とはすなわち静止画を連続で映して、あたかも動いているように見えるパラパラ漫画のような物だ」と。
これはゲームでも当てはまります。そりゃそうですよね。ゲームは映像を出力しているのですから。
例えば↓のようなゲームがあったとします。
この映像はつまり
このようにたくさんの画像が連続で表示される事であたかも動いているようにように見せているわけです。
この1枚、1枚の画像をディスプレイに表示させていくわけですが、画像を表示させてから次の画像を表示するまでを1フレームといいます。
<ゲームが1フレーム内でやっている事>
画像を表示させてから次の画像を表示するまでを1フレームといいますが、ただ単に「絵」を出しているわけではなく、様々な計算を行って画像を作成しています。
この点が、他の映像系のものと違う点です。テレビや映画などは予め記録された画像を連続して出していきます。
ゲームは1つ1つの画像を計算によって作成しています。
テレビや映画などと違って、ゲームは先が決まっていないので、その瞬間瞬間で画像を作成してあげる必要があるわけです。
例えば、↓の画像ですが
まず、入力を受け付けて、入力されていたら移動後の座標を計算して、敵のオブジェクトの移動量も計算して、オブジェクトの位置を計算して、座標から前後関係を計算して…etc.etc
と、把握できないくらいたくさんの計算を行っています。
CPUでこの計算を行なった後、GPUに計算結果を渡し、画像として出力するのです。
画像が表示されてから、次の画像を表示するまでの1フレームの間に数多くのことをしているわけですね。
<フレームレートとは>
さて、ゲームをプレイしていてフレームレートという言葉をよく聞くと思います。
フレームレートは○○FPSという風に言われます。
よく聞く60FPSとか言うのは「計算と画像の出力」を1秒間に60回行なったと言う意味です。
FPSはframe per secondの略ですね。フレーム/秒です。
ちなみにCPUとGPUの処理速度でFPSの値は変動します。ただし、ゲームを作る場合、一定のFPS値に合わせる処理を行なってFPSを安定させています。
計算が完了した瞬間に画像を出していては、軽い計算をした時と重い計算した時で、画像の出力タイミングが変わってしまいます。画像の出力タイミングが変わってしまうと画面がチラチラしたりカクついたりして見えるので、画像出力のタイミングを一定に決めてしまって、そのタイミングまで画像出力を待ちます。
ゲームが常に60FPSで動いている場合は60FPS以上のスピードで計算されているのをワザと遅らせて60に合わせているわけです。
では、計算が、この画像を出力する一定のタイミングに間に合わない場合はフレームレートが下がります。
60FPSで合わせられない場合は30FPSで合わせます。それが合わせられないとどんどん下のFPSに合わせられて行って、20、15になり、最終的に0FPSになります。0になると画面がガクッと止まってしまいます。
何故、60がいきなり30になってしまうのかと言うと、ディスプレイのリフレッシュレートの規格に合わせているからです。
ちなみに、画面出力まで待たない方法もありますが、これをするとディスプレイとの同期がとれなくなるので、ズレが出ます。
<UnityのUpdateとは>
Unityでプログラムを組んでいくときにUpdateという特別なメソッドが出てきます。
Updateについては↓で軽く触れています。
UpdateはUnity側から毎フレーム呼ばれるメソッドですが、この毎フレームというのは、↑で言っている計算の部分に該当します。
1フレーム、1フレームの計算のところで毎回呼ばれるメソッドということです。
<ゲームの移動は瞬間移動である>
さて、1フレームの間に計算して、画像を出力するという話をしてきました。
物体の移動は、座標xyzを指定して画面に描画、座標xyzを指定して描画と言うのを繰り返しています。これは↑の計算の部分に該当します。
つまり、あたかも移動しているように見えるものは、その座標に瞬間移動していると言えます。
瞬間移動が短い距離で連続している為、移動しているように見えるわけです。
ちょっと違いますが、イメージとしてはこんな感じです
一瞬いちいち左に戻っているのは無視してください
瞬間移動について考える事
さて、移動が瞬間移動であると考えるべきことがでてきます。
例えば、物理演算を使ったアクションゲームなどで起きやすいのですが、当たり判定をすり抜けたり、何故だかよくわからないけどガクガク変な動きをしたりすることがあります。
移動が瞬間移動であるという事を知らないと、何故このような事が起きるのかがわからないと思います。
瞬間移動が要因でこういったことが起きる要因を見ていこうと思います。
・当たり判定をすり抜ける場合
移動を行う際に、まず瞬間移動で位置を決めます。
その後、瞬間移動するポジションに物理的に干渉するものがあると、移動する位置を再計算します。
この時、物理的に干渉していないと見なされると瞬間移動が成立します。
移動開始位置と移動後の位置が遠かったりすると、物理的に干渉していないとみなされて、当たり判定をすり抜けます。
これは、瞬間移動の移動量が大きいため、間に存在する当たり判定にぶつかっていないと判断されるからですね。
・移動がガクガクする場合
移動がガクガクするのは前回の瞬間移動する際に行われた計算の時間と今回瞬間移動する際に行われた計算の時間が違う時によく起こります。
距離 = 速さ × 時間 です。
時間がフレームによりマチマチになったりズレたりするのでこれを考慮していないスクリプトを組んでしまうとガクガクになりやすいです。
例えば、単純に移動量を足し算したりするとフレームレートが安定しない時、ガクガクとした移動になりやすいです。
こういった様々な問題に対処する為にゲームの移動は瞬間移動であるという基礎知識を身につけておく必要があるという事ですね。
瞬間移動という表現
ちょっと初心者の方を悩ませてしまうのがこの「瞬間移動」という表現です。サイトや本によってマチマチで色々な表現をされているところが厄介です。
基本的に移動に関する全ての事象が瞬間移動であるのですが、「物理演算による再計算を行わない移動」を瞬間移動と言っているサイトや本もありますし、連続した移動に見えない移動を瞬間移動と言っているサイトや本もありますし、空間転移という表現の仕方をしているサイトや本もあります。
ここがまぁ、ややこしい点ですが、基本的に全ての移動は瞬間移動であると覚えておいてください。
滑らかに移動しているように見えても連続の瞬間移動をしているだけです。これを瞬間移動とは言わない人もいますが、正直言葉の表現の差の世界なので各自脳内補完して解釈をうまくしていただけると助かります。