今天测试反馈了个刷屏的警告”Particle System is trying to spawn on a mesh with zero surface area“根据翻译判断是使用了体积为0的mesh,但是当我在网上查找资料的时候,网上说的是因为 ParticleSystem 中 ShapeModule 要求引用的 Mesh 必须开启 Read/Write 选项.
经过我的实验和调试发现并不是这么回事,简单的就是因为某个特效的shape类型选择了mesh然而没有指定一个mesh给他,而且选择的Mode为Edge,如下:

满足以上几个箭头所指的条件后就会不断刷如下警告:

要想去掉这些警告,可以改变shape的类型或者指定一个mesh给它,也可以改变Mode的类型为Vertex都可以去掉这些烦人的警告,具体方法需要根据自己的特效情况设置.
如果需要查找项目中有问题的特效可以使用以下编辑器脚本:
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
public static class MeshToolForParticle
{
[MenuItem("Tools/ParticleSystem/FindScenes", false, 20)]
public static void FindScenes()
{
var guids = AssetDatabase.FindAssets("t:Scene");
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
var scene = EditorSceneManager.OpenScene(path, OpenSceneMode.Single);
var roots = scene.GetRootGameObjects();
bool found = false;
foreach (var go in roots)
{
found |= Find(go);
}
if (found)
{
Debug.Log(path);
}
}
}
[MenuItem("Tools/ParticleSystem/FindPrefabs", false, 20)]
public static void FindPrefabs()
{
var guids = AssetDatabase.FindAssets("t:Prefab");
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
Find(prefab);
}
}
private static bool Find(GameObject go)
{
bool found = false;
var particles = go.GetComponentsInChildren<ParticleSystem>(true);
foreach (var particle in particles)
{
if (particle.shape.enabled && particle.shape.shapeType == ParticleSystemShapeType.Mesh &&
particle.shape.mesh == null)
{
string prefabPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(particle);
Debug.LogWarning(string.Format("Path: {0}\nPrefab: {1}", particle.gameObject.GetGameObjectPath(), prefabPath));
found = true;
}
}
return found;
}
}
把上面的脚本放到项目的Editor目录下然后点击菜单Tools/ParticleSystem/FindPrefabs,即可打印出有问题的特效名称.