개발 라이브러리 & 툴/유니티

Unity FPS 체크 소스

하늘흐늘 2022. 1. 3. 18:51
반응형

유니티에서 초당 프레임 관련 정보를 보여주는 소스입니다. 위의 이미지와 같이 표시합니다.
기본적으로 한 프레임 실행시간과 한 프레임 실행시간을 기반으로 초당 가능 프레임 수를 표시합니다. 이미지에서 {msec} ms가 한 프레임 실행시간, {frame count} fps가 초당 가능 프레임 수입니다.

여기까지는 보통 인터넷에 존재하는 소스와 비슷합니다. 그런데 이렇게만 표시하면 수치가 너무 빨리 변하여 실제적으로 화면을 보면서 이용하기가 불가능합니다. 그래서 1초 동안 계산된 프레임 중에 최소와 최대 프레임을 같이 표시하도록 만들어 놓았습니다. 이미지에서 {frame count} min fps가 초당 최소 프레임 수이고 {frame count} max fps가 초당 최대 프레임 수입니다.

실제적으로 여기까지 만들어 사용하여도 실제적으로는 큰 도움이 되지는 않았습니다. 그래서 만든 것이 real fps개념입니다. 유니티는 프레임당 update를 한 번씩 호출한다는 것에 착안하여 실제로 초당 호출된 update 개수를 계산하여 real fps로 표시하였습니다. 테스트시 유니티의 프레임 타겟을 60으로 설정하였을 때 PC 개발환경에서 59~60사이로 정상적으로 표시됩니다. real fps 뒤의 가로는 10초당 최소 fps ~ 최대 fps입니다. 10초는 임의로 잡은 시간 간격이며 계속적으로 갱신하여 주어야 게임에서의 프레임 변화를 체크할 수 있게 하기 위하여 주기적으로 갱신하게 만들어 놓았습니다. 이 내용이 이미지에서 {초당 Update 호출 수} real fps ({주기별 최소 real fps} ~ {주기별 최대 real fps})입니다.

이외에 해상도별로 볼만한 사이즈로 폰트 사이즈가 자동으로 변경됩니다. 그 외에 폰트 색상이나 표시 위치 등은 공개된 소스를 수정하여 사용하시면 됩니다. 

개인적으로 만들어 만들고 있는 게임의 최적화에 유용하게 사용하고 있는 클래스로 많은 도움이 되었으면 합니다. 참고로 해당 클래스는 화면 표시를 위하여 IMGUI를 사용하고 있습니다. IMGUI는 성능이 떨어지고 비록 StringBuilder를 사용하여 최적화 하였지만 프레임마다의 화면 표시를 위한 String 연산은 모바일에서는 프레임을 떨어뜨릴 수도 있습니다. 그런 관계로 실제 빌드에서 해당 클래스를 제거하면 프레임이 약간 더 좋아질 수도 있습니다.

소스는 아래와 같습니다.

using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;


public class FPSCheck : MonoBehaviour
{
    float delta_ = 0f;
    float sec_sum_delta_ = 1f;
    float secs_sum_delta_ = 10f;
    int min_fps_ = 200;
    int max_fps_ = 0;
    int real_fps_ = 0;
    int min_real_fps_ = 500;
    int max_real_fps_ = 0;
    int real_fps_counter_ = 0;
    StringBuilder builder_ = new StringBuilder();
    GUIStyle style_ = new GUIStyle();
    Rect rect_;
    int old_width_ = -1;
    int old_height_ = -1;

    void Update()
    {
        delta_ = Time.unscaledDeltaTime;
        sec_sum_delta_ -= delta_;
        real_fps_counter_++;

        if (sec_sum_delta_ <= 0f)
        {
            secs_sum_delta_ += -1f + sec_sum_delta_;
            if (secs_sum_delta_ <= 0)
            {
                min_real_fps_ = 500;
                max_real_fps_ = 0;
                secs_sum_delta_ = 10f;
            }

            min_fps_ = 200;
            max_fps_ = 0;
            real_fps_ = real_fps_counter_;
            real_fps_counter_ = 0;
            sec_sum_delta_ = 1f;
        }
    }

    private void OnGUI()
    {
        float msec = delta_ * 1000;
        int fps = (int)(1f / delta_);

        if (fps < min_fps_)
        {
            min_fps_ = fps;
        }
        if (max_fps_ < fps)
        {
            max_fps_ = fps;
        }

        if (real_fps_ < min_real_fps_)
        {
            min_real_fps_ = real_fps_;
        }

        if (max_real_fps_ < real_fps_)
        {
            max_real_fps_ = real_fps_;
        }

        builder_.Clear();
        builder_.AppendFormat(" {0:000.} ms \n", msec);
        builder_.AppendFormat(" {0} fps \n", fps);
        builder_.AppendFormat(" {0} min fps \n", min_fps_);
        builder_.AppendFormat(" {0} max fps \n", max_fps_);
        builder_.AppendFormat(" {0} real fps ({1} ~ {2}) \n", real_fps_, min_real_fps_, max_real_fps_);

        int width = Screen.width;
        int height = Screen.height;

        if (width != old_width_ || height != old_height_)
        {
            rect_ = new Rect(width * 0.03f, height * 0.05f, width * 0.3f, height * 0.3f);

            style_.alignment = TextAnchor.UpperLeft;
            style_.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
            style_.fontSize = (int)(width * 0.05f);
            var color = style_.normal.textColor;
            color.r = 0f;
            color.g = 0f;
            color.b = 0f;
            color.a = 1f;
            style_.normal.textColor = color;

            old_width_ = width;
            old_height_ = height;
        }

        GUI.Label(rect_, builder_.ToString(), style_);
    }
}

기존 소스가 폰트 문제로 아이폰에서 로딩시 느려지는 문제가 있어 소스 수정하였습니다. 기존 소스 사용하시고 아이폰 처음 스플래시 화면 나오는게 느려지신 분은 수정된 소스와 같이 아래 부분 추가시켜 주시면 됩니다.

style_.font = Resources.GetBuiltinResource<Font>("Arial.ttf");

반응형