在游戏性能优化阶段,对美术性能的优化是必不可少的。
为了给美术一个比较直观的分析结果,故此编写了一个分析工具脚本,只需要将需要分析的特效拖入其中即可。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System;
/// <summary>
/// 循环创建获得特效的数据
/// 设计:每个特效跑10遍,取中间值
/// </summary>
public class ArParticlesTool : MonoBehaviour
{
/// <summary>
/// 特效参数
/// </summary>
class Particles
{
public float loadTime;//加载时间
public float creatTime;//创建时间
public int maxBatches;//最大渲染批次
public int averageBatches;//平均渲染批次
public float maxBatchesTime;//最大渲染批次时间
public int maxTris;//最大顶点数
public int averageTris;//平均顶点数
public int maxVerts;//最大面数
public int averageVerts;//平均面数
}
public List<GameObject> objPool;
// Start is called before the first frame update
void Start()
{
StartCoroutine(CreatParticles());
}
List<Particles> parList = new List<Particles>();
int creatID = 0;//创建特效的ID
string str = "";
List<int> startStats = new List<int>();
bool isDebug = false;
float startTime = 0;
float maxTime = 0;
int maxB = 0;
int maxT = 0;
int maxV = 0;
List<int> batches = new List<int>();
List<int> tris = new List<int>();
List<int> verts = new List<int>();
/// <summary>
/// 创建特效
/// </summary>
/// <returns></returns>
IEnumerator CreatParticles()
{
yield return new WaitForSeconds(5f);
if (startStats.Count == 0)
{
//初始化
str += "特效名,(Win)初次加载时间(微秒),(Win)创建时间(微秒),最大渲染批次,平均渲染批次,最大渲染批次时间,最大顶点数,平均顶点数,最大面数,平均面数\n";
startStats.Add(UnityStats.triangles);
startStats.Add(UnityStats.vertices);
startStats.Add(UnityStats.batches);
}
if (creatID < objPool.Count)
{
isDebug = true;
startTime = Time.time; maxTime = 0; maxB = 0; maxT = 0; maxV = 0;
batches.Clear();
tris.Clear();
verts.Clear();
var _startT = TimeStampLongTicks();
//创建下一个预制体
var _obj = Instantiate(objPool[creatID]);
var _f = GetTimestamp(TimeStampLongTicks() - _startT);
Particles _p = new Particles();
if (parList.Count == 0) _p.loadTime = _f;
else _p.creatTime = _f;
StartCoroutine(EndCreat(_obj, _p));
StartCoroutine(CreatParticles());
}
else
{
SaveStats();
}
}
// Update is called once per frame
void FixedUpdate()
{
if (isDebug)
{
var _dis = UnityStats.batches - startStats[2];
if (_dis > 0)
{
batches.Add(_dis);
var _t = UnityStats.triangles - startStats[0];
tris.Add(_t);
var _v = UnityStats.vertices - startStats[1];
verts.Add(_v);
if (_dis > maxB)
{
maxB = _dis;
maxTime = Time.time - startTime;
}
if (_t > maxT) maxT = _t;
if (_v > maxV) maxV = _v;
}
}
}
/// <summary>
/// 结束创建
/// </summary>
/// <returns></returns>
IEnumerator EndCreat(GameObject _obj,Particles _p)
{
yield return new WaitForSeconds(3f);
isDebug = false;
DestroyImmediate(_obj);
_p.maxTris = maxT; _p.maxVerts = maxV;
_p.averageBatches = GetAverage(batches);
_p.averageTris = GetAverage(tris);
_p.averageVerts = GetAverage(verts);
_p.maxBatches = maxB;_p.maxBatchesTime = maxTime;
parList.Add(_p);
Debug.Log("结束记录" + maxB + " " + maxTime + " " + maxT + " " + maxV);
var _max = 10;
if (parList.Count >= _max)
{
var _l = 0f; var _c = 0f;
var _mB = 0; var _aB = 0; var _mBf = 0f;
var _mT = 0; var _aT = 0;
var _mV = 0; var _aV = 0;
var _a = 0;
//总结
foreach (var idx in parList)
{
if (idx.loadTime > 0) _l = idx.loadTime;
_c += idx.creatTime;
if (idx.maxBatches > 0)
{
_a++;
_mB += idx.maxBatches;
_aB += idx.averageBatches;
_mBf += idx.maxBatchesTime;
_mT += idx.maxTris;
_aT += idx.averageTris;
_mV += idx.maxVerts;
_aV += idx.averageVerts;
}
}
_a = Mathf.Clamp(_a, 1, _max);
str += objPool[creatID].name + ","
+ _l + "," + (int)(_c / (parList.Count - 1) * 100) / 100 + ","
+ _mB / _a + "," + _aB / _a + "," + _mBf / _a + "," +
+_mT / _a + "," + _aT / _a + "," +
+_mV / _a + "," + _aV / _a + "," +
"\n";
parList.Clear();
creatID++;
Debug.LogError(str);
}
}
int GetAverage(List<int> _list)
{
var _t = 0;
foreach (var _i in _list) _t += _i;
var _f = Mathf.Clamp(_list.Count, 1, 10000);
return _t / _f;
}
void SaveStats()
{
AssetDatabase.Refresh();
Directory.CreateDirectory("Assets/TablesOther");
using (StreamWriter writer = File.CreateText("Assets/TablesOther/表格.csv"))
writer.Write(str);
AssetDatabase.Refresh();
Debug.Log(gameObject.name + "转表完毕");
}
/// <summary>
/// 转换时间戳
/// </summary>
/// <returns></returns>
public long TimeStampLongTicks()
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
return (DateTime.Now.Ticks - startTime.Ticks);
}
/// <summary>
/// 获得纳秒
/// </summary>
/// <returns></returns>
public int GetTimestamp(long _t)
{
return (int)_t/10;
}
}
为了比较准确的结果,建议在跑分的过程中,不要开关其他软件,以保证比较稳定的运行环境。
打印结果如下图所示: