masked雑記

IT関連の記事を書く

Unity製ゲームで解像度設定によって速度が変わる

www.nicovideo.jp

www.nicovideo.jp

の駄菓子兄貴リスペクトのゲーム(Unity製)を見ていて

両者に共通する解像度設定によって速度が変わるという事象

について解析してみようと思った。
そんな事しなくていいから(良心)

事象の確認

まずは事象を観察すると以下の2点が挙げられる。

  • グラフィックボードの性能をあげると高速ディフェンス
  • グラフィクス設定をFastestにすると高速移動

したがって「フレームレートが上がるとそれに伴い加速度が増える」というのが見えてくる。

Unityのフレーム単位での処理について

Unityでは更新処理に使われる関数が複数存在するが、主に使われるのはUpdate関数かFixedUpdate関数だろう 関数の違いについて簡単に説明する。

Update

フレーム単位ごとに呼び出される。フレームレートが90なら1秒間に90回呼び出される。 主に入力系やカメラの移動などの記述をする。

FixedUpdate

独立したタイマーから呼び出される。デフォルト設定だと0.02秒に1回呼び出される。 この関数の直後に物理演算を実行するので、物理演算(Rigidbody)に関するものはこちらに記述する。


おそらくFixedUpdateでなくUpdateでオブジェクトに力をかけて加速させている。

検証

f:id:lambdakura:20171012005528p:plain

黄色い板に乗っている間だけ加速するようなゲームを作った

基底クラスBaseAccelerator

using UnityEngine;

public abstract class BaseAccelerator : MonoBehaviour {

    public float power = 50f;
    public bool isEnter = false;
    protected Rigidbody playerRig;

    public int addCount = 0;

    void OnCollisionEnter(Collision collision) {
        var obj = collision.gameObject;
        if (obj.CompareTag ("Player")) {
            playerRig = obj.GetComponent<Rigidbody> (); 
        }
        isEnter = true;
    }

    void OnCollisionExit(Collision collision) {
        isEnter = false;
    }
}

BaseAcceleratorを継承し、FixedUpdateで加速処理をするFUpdAccelerator

using UnityEngine;

public class FUpdAccelerator : BaseAccelerator {
    void FixedUpdate(){
        if (isEnter) {
            playerRig.AddForce (Vector3.right * power);
            addCount++;
        }
    }
}

BaseAcceleratorを継承し、Updateで加速処理をするUpdAccelerator

using UnityEngine;

public class UpdAccelerator : BaseAccelerator {   
    void Update(){
        if (isEnter) {
            playerRig.AddForce (Vector3.right * power);
            addCount++;
        }
    }
}



結果

FixedUpdateは全ての画面解像度とQuality設定で同一の地点で止まった f:id:lambdakura:20171012005946p:plain

一方Updateは画面解像度が下がるほど、Quality設定を下げるほど制動距離は伸びた。
640 x 480 Quality:VeryLow f:id:lambdakura:20171012010250p:plain

1366 x 768 Quality:Ultra f:id:lambdakura:20171012010449p:plain



結論

物理演算をさせるときはUpdateではなくFixedUpdateを使おう

参考

Unity - マニュアル: イベント関数の実行順

Unity - Update と FixedUpdate