8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unityのシーン上でアクティブな3Dモデルの頂点とポリゴンを数えてみる

Last updated at Posted at 2016-10-15

概要

ゲームを快適にプレイするためにはFPSを保つ必要があります。(特に、VR系コンテンツは最低でも60fpsは出したいところ)
FPSが落ちる要因は様々あって一概にこれ!ということは難しいですが、可能性の一つとして3Dモデルの出しすぎや1つのモデルのポリゴン数が多すぎ等が挙げられます。
ということで、シーン上でActiveになっている3Dモデルの頂点とポリゴンを数えてみる方法になります。

Unityのバージョン

5.4.2f1

アクティブな3Dモデルの頂点とポリゴンを数える

サンプルコード

PolygonCounter.cs
using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class PolygonCounter : MonoBehaviour {

	int vertices;
	int polygons;

	[SerializeField]
	int minFps = 60;

	int frameCount = 0;
	float nextTime = 0.0f;

	void Start () {
		nextTime = Time.time + 1;
	}
	
	void Update () {

		frameCount++;

		// 1秒ごとにFPS検証
		if (Time.time >= nextTime) {
			// Debug.LogFormat ("{0}fps", frameCount);
			if (frameCount < minFps) PolygonCount (frameCount);

			frameCount = 0;
			nextTime += 1f;
		}

	}

	[ContextMenu("CountStart")]
	void PolygonCount(int fps = -1){

		vertices = 0;
		polygons = 0;
		foreach (GameObject obj in UnityEngine.Object.FindObjectsOfType(typeof(GameObject))) {

			if (obj.activeInHierarchy) {

				SkinnedMeshRenderer skin = obj.GetComponent<SkinnedMeshRenderer> ();

				if (skin != null) {
					int vert = skin.sharedMesh.vertices.Length;
					vertices += vert;

					int polygon = skin.sharedMesh.triangles.Length / 3;
					polygons += polygon;
				}

				MeshFilter mesh = obj.GetComponent<MeshFilter> ();

				if (mesh != null) {
					int vert = mesh.sharedMesh.vertices.Length;
					vertices += vert;

					int polygon = mesh.sharedMesh.triangles.Length / 3;
					polygons += polygon;
				}
					
			}
		}
		Debug.LogFormat ("Vertices(verts) : {0} , Polygons(Tris) : {1} , FPS : {2} " ,
			vertices , polygons, fps);	

	}

#if UNITY_EDITOR

	[CustomEditor(typeof(PolygonCounter))]
	public class CountStartEditor : Editor {

		PolygonCounter polygonCounter;

		void OnEnable(){
			polygonCounter = target as PolygonCounter;
		}

		public override void OnInspectorGUI ()
		{
			base.OnInspectorGUI ();

			if (GUILayout.Button("カウント開始")){
				polygonCounter.PolygonCount ();
			}
		}

	}

#endif

}

使い方

  • 適当なGameObjectにアタッチしてください。
  • インスペクター上で確認したい場合は、「カウント開始」を押してください(何かの不具合でボタンが表示されない場合は、歯車アイコンから「CountStart」を押してください)
  • ゲームプレイ中に確認したい場合は、minFpsの値を設定してください。FPSがminFpsを下回るとカウントを開始します。
  • コンソールログに、シーン上でアクティブな3Dモデルの頂点とポリゴン数が表示されます。

基礎クラス(PolygonCounter)

  • FPSは1秒間に実行したフレームをカウントしています。
  • 設定したFPSを下回るときに、今回のカウンター処理を呼び出しています。
  • シーン上でアクティブなゲームオブジェクトを全検索します。
  • その中でSkinnedMeshRendererか、MeshFilterをコンポーネントとして持っている場合は頂点数とポリゴン数を加算してます。(頂点数とポリゴン数はメッシュのインスペクターに表示される内容です(下記画像を参照))
  • 最終的にデバッグログとして出力します。

mesh_inspector.png

拡張クラス(CountStartEditor)

  • 基礎クラスのメソッドを呼ぶために、有効時に基礎クラスを設定
  • インスペクターを拡張して、ボタンを配置(押されたらメソッド呼ぶ)

補足

  • あくまでデバッグを目的にしているので、デバッグ時以外は外しておいた方が良いです。(そもそも、シーン上の3Dモデルを全検索する負荷が高そうですし)
  • この記事のサンプルコードについては、「【Unity】3Dオブジェクトのポリゴン数を表示させる」を参考にさせてもらいました。
  • バグだったり、こうした方がスマートなどありましたら、ご指摘ください。
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?