Unity3D Research Institute utiliza la propia API de Unity para fusionar la malla de escenas por adelantado

Unity viene con la función de fusionar Mesh. La forma más fácil es marcar la opción estática en el nodo Raíz. Su principio es fusionar en tiempo de ejecución. Pero recientemente encontré un problema al desarrollar, porque nuestra escena es muy grande, los vértices de la malla no pueden exceder 65535, por lo que Unity dividirá automáticamente la malla fusionada en muchas sub-mallas, en resumen, los vértices son menores que 65535.

La prueba en IOS es normal, pero algunas máquinas Android tienen problemas en la escena. La representación es incorrecta, por lo que la conclusión es que no puede confiar completamente en la función Mesh fusionada de Unity. Además, si la combinación de Mesh es demasiado grande, tendrá un impacto en el rendimiento. Así que me preguntaba si podría fusionar Mesh estratégicamente. La respuesta es definitivamente factible. Por ejemplo, encontré el MeshRender a 50 metros según la posición del gameObject y luego lo fusioné. Si se trata de una fusión en tiempo de ejecución, para evitar el consumo de rendimiento causado por una gran cantidad de búsquedas, la malla que se fusionará se puede serializar en la escena de antemano en el Editor. Fusiona en Awake donde se carga la escena.

Estoy hablando de otra forma de generar archivos. Lo que quiero decir hoy es fusionar algunas mallas en archivos .asset de antemano y escribirlas directamente en el proyecto de unidad. Encontré algunos otros artículos en Internet, pero todos quieren generar una nueva malla grande y luego ocultar todas las pequeñas mallas anteriores. Creo que no es tan bueno como el método original de Unity, porque si algunos scripts se cuelgan en el gameObject original, ocultar los scripts perderá algo de significado. . Y no es posible mostrar / ocultar una malla específica solo.

Como se muestra en la siguiente figura, el arte coloca todas las mallas debajo del nodo Raíz. Cada MeshFilter debe estar en el FBX creado por el propio artista.

 

Lo que quiero hacer ahora es fusionar algunos MeshFilters para generar una nueva Mesh y modificar directamente la malla en el MeshFilter original. Como se muestra en la figura siguiente, el resultado final.

 

Para evitar la duplicación de nombres, generaré una carpeta en el directorio de nivel de acuerdo con la ruta de la escena actual y colocaré en ella el archivo de malla generado. Y reemplace el archivo de malla en el meshFilter original.

A continuación se muestra mi código.

using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEditor.SceneManagement;
using System.IO;
 
public class CreateMesh  {
 
	[MenuItem("Tools/create")]
	static void Start1 () 
	{
		GameObject root = GameObject.Find("Root");
 
		if(root)
		{
			MeshRenderer [] meshRenderers = root.GetComponentsInChildren<MeshRenderer>();
 
			GameObject [] gos = new GameObject[meshRenderers.Length];
			for(int i = 0; i< meshRenderers.Length;i++)
			{
				gos[i] =meshRenderers[i].gameObject; 
			}
 
			string scenePath = EditorSceneManager.GetSceneAt(0).path;
			string meshScenePath = scenePath.Replace(".unity","_mesh");
			string fullPath = Path.Combine(Directory.GetCurrentDirectory(),meshScenePath);
 
			if(Directory.Exists(fullPath))
				Directory.Delete(fullPath,true);
			Directory.CreateDirectory(fullPath);
			string assetPath = FileUtil.GetProjectRelativePath(fullPath);
 
			StaticBatchingUtility.Combine(gos,root);
			for(int i =0; i< gos.Length; i++)
			{
				Mesh mesh = gos[i].GetComponent<MeshFilter>().sharedMesh;
				string meshPath = AssetDatabase.GetAssetPath(mesh);
 
				if(string.IsNullOrEmpty(meshPath))
				{
					string path = Path.Combine(assetPath,Random.Range(int.MinValue,int.MaxValue) +".asset");
					AssetDatabase.CreateAsset(mesh,path);
				}
 
			}
		}
		AssetDatabase.Refresh();
		EditorSceneManager.MarkAllScenesDirty();
	}
}

StaticBatchingUtility.Combine Este método tiene dos sobrecargas

1. Nodo raíz del parámetro. Esto tiene un uso un poco limitado, porque el arte tiene que colocar la malla que se fusionará en un nodo específico de antemano. Si quiero fusionar un nodo en varias mallas, no funcionará.

2. Los parámetros son una matriz y un nodo de nivel superior. Esto es mucho más cómodo de usar. Puedo poner los gameObjects que necesito fusionar en una matriz y luego asignarles un nodo. (Especifíquelo en el nodo superior del mapa)

Finalmente, todos son bienvenidos a discutir juntos. ¡Por el momento, todavía no estoy seguro de fusionar en tiempo de ejecución y fusionar antes de tiempo! !

Supongo que te gusta

Origin blog.csdn.net/mango9126/article/details/101703496
Recomendado
Clasificación