using System; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.SceneManagement; namespace Thousandto.Launcher.ExternalLibs { /// /// 场景资源描述文件 /// [Serializable] public class SceneAssetDescript { #region//私有变量 private SceneAssetsDiscriptFile _script = null; private List _listMatData = new List(32); #endregion #region//公共变量 public Transform Trans = null; //mesh路径 //public string[] MeshPaths = null; //合并后的网格名字 //public string CombinName = string.Empty; //mesh路径索引 //public int[] MeshIndexs = null; //subMesh 索引 //public int SubMeshIndex = -1; //排序extend public float Sort = 0; //render类型 public RendererType RdType = RendererType.None; //node类型 public NodeRootType NType = NodeRootType.Default; //包围盒 private Bounds NodeBounds; //材质属性 public MatrialAssetData[] MatsData = null; //加载优先级 //public NodeRootType RootType = NodeRootType.Default; public bool IsSetAsset = false; public bool IsActive = false; #endregion //场景可视节点名字定义 public static string FarRootName = "[Far]"; public static string MidRootName = "[Mid]"; public static string NearRootName = "[Near]"; private Material _defaultMat = null; private Shader _defaultShader = null; #region//公共接口 public void SetData(SceneNodeCommpent node, RendererType type, SceneAssetsDiscriptFile script) { _listMatData.Clear(); node.IsUseDefaultShader = false; _script = script; if (node != null && node.Trans == null) return; string folderPath = string.Empty; Trans = node.Trans; IsActive = node.IsActive; Material[] mats = null; Material tailMat = null; switch (type) { case RendererType.MeshRenderer: { RdType = RendererType.MeshRenderer; MeshFilter mf = node.Trans.GetComponent(); if (mf == null) return; MeshRenderer mRd = node.Trans.GetComponent(); Mesh ms = mf.sharedMesh; string path = GetMeshPath(ms, ref folderPath); mats = mRd.sharedMaterials; Sort = GetMaxBoundSize(ms.bounds); SaveMesh(ms, path, folderPath); //List list = null; //if (node.RenderType == RendererType.MeshRenderer && !node.IsSetCombinData) //{ // if (node.MatProList.Count != 0) // { // CombinData data = new CombinData(); // data.mesh = mf.sharedMesh; // data.trans = node.Trans; // data.combinName = string.Format("Comb_MatProperty_{0}_Mesh", node.MatProList[0]); // //设置合并后的网格名字 // CombinName = data.combinName; // if (!_script.DicCombinData.ContainsKey(node.MatProList[0])) // { // list = new List(); // list.Add(data); // _script.DicCombinData.Add(node.MatProList[0], list); // } // else // { // list = _script.DicCombinData[node.MatProList[0]]; // list.Add(data); // } // SubMeshIndex = list.Count - 1; // node.SubMeshIndex = SubMeshIndex; // int index = _script.GetCombinMeshPathIndex(CombinName); // MeshIndexs = new int[] { index }; // node.IsSetCombinData = true; // } //} } break; case RendererType.SkinMesh: { RdType = RendererType.SkinMesh; SkinnedMeshRenderer skinnedRender = node.Trans.GetComponent(); mats = skinnedRender.sharedMaterials; string path = GetMeshPath(skinnedRender.sharedMesh, ref folderPath); int index = _script.GetMeshPathIndex(path); //MeshIndexs = new int[] { index }; //MeshPaths = new string[] { path }; Sort = GetMaxBoundSize(skinnedRender.sharedMesh.bounds); SaveMesh(skinnedRender.sharedMesh, path, folderPath); } break; case RendererType.ParticleSystemRenderer: { RdType = RendererType.ParticleSystemRenderer; ParticleSystemRenderer psr = node.Trans.GetComponent(); Mesh[] msArray = new Mesh[psr.meshCount]; psr.GetMeshes(msArray); List pathes = new List(); for (int i = 0; i < msArray.Length; i++) { string path = GetMeshPath(msArray[i], ref folderPath); pathes.Add(path); SaveMesh(msArray[i], path, folderPath); } List list = new List(); for (int i = 0; i < pathes.Count; i++) { int index = _script.GetMeshPathIndex(pathes[i]); list.Add(index); } //MeshIndexs = list.ToArray(); //MeshPaths = pathes.ToArray(); mats = psr.sharedMaterials; Sort = -1; tailMat = psr.trailMaterial; } break; case RendererType.TrailRender: { RdType = RendererType.TrailRender; TrailRenderer tRd = node.Trans.GetComponent(); mats = tRd.sharedMaterials; Sort = GetMaxBoundSize(tRd.bounds); } break; } bool isParticle = type == RendererType.ParticleSystemRenderer ? true : false; for (int i = 0; mats != null && i < mats.Length; i++) { Material defaultMat = null; MatrialAssetData data = new MatrialAssetData(); if (node.IsUseDefaultShader) { continue; } if (mats[i]!= null && string.Equals(mats[i].shader.name, "Gonbest/FallBack/FBWithLightmap")) continue; if (isParticle) { //如果是粒子render //默认第二个材质球是拖尾材质球 data.IsTrail = i == 1 ? true : false; } if (mats[i] == null || (!mats[i].shader.name.Contains("Ares") && !mats[i].shader.name.Contains("Gonbest"))) { if (mats[i] != null) { node.IsUseDefaultShader = true; defaultMat = GetDefaultMat(); UnityEngine.Debug.LogError(string.Format("重要事情说一遍,发现unityShader:{0}---目标节点是:{1}", mats[i].shader.name, node.Trans.name)); } else { continue; } } int index = i; //for (int m = 0; m < mats.Length; m++) //{ // if (string.Equals(mats[i].name, mats[m].name)) // { // index = m; // break; // } //} if (isParticle) { data.SetMatrialAssetData(node, mats[i], defaultMat, _script, true, index); } else { data.SetMatrialAssetData(node, mats[i], defaultMat, _script, false, index); } if (tailMat == null || mats[i] != tailMat) { if (type == RendererType.SkinMesh) { SkinnedMeshRenderer skinnedRender = node.Trans.GetComponent(); int count = skinnedRender.sharedMesh.subMeshCount; if (count != 1 && count == mats.Length) { _listMatData.Add(data); } else { //去除重复 bool isFind = false; for (int m = 0; m < _listMatData.Count; m++) { if (_listMatData[m].Index == data.Index) { isFind = true; } } if (!isFind) { _listMatData.Add(data); } } } else { //去除重复 bool isFind = false; for (int m = 0; m < _listMatData.Count; m++) { if (_listMatData[m].Index == data.Index) { isFind = true; } } if (!isFind) { _listMatData.Add(data); } } } else { _listMatData.Add(data); } if (isParticle) { node.SetSaveSubMatTexIndex(i); } node.IsSaveTexture = true; } if (node.IsSaveTexture) { MatsData = new MatrialAssetData[_listMatData.Count]; for (int i = 0; i < _listMatData.Count; i++) { MatsData[i] = _listMatData[i]; } } } private Material GetDefaultMat() { if (_defaultMat == null) { Shader sh = Shader.Find("Gonbest/FallBack/FBWithMainTex"); Material mat = new Material(sh); _defaultShader = sh; _defaultMat = mat; } return _defaultMat; } private string GetMeshPath(Mesh ms, ref string folderPath) { if (ms == null) return string.Empty; string path = string.Empty; string replaceStr = string.Empty; #if UNITY_EDITOR path = UnityEditor.AssetDatabase.GetAssetPath(ms); #endif string[] strs = path.Split('.'); if (strs != null && strs.Length != 0) { path = strs[0]; } strs = path.Split('/'); replaceStr = strs[strs.Length - 1]; replaceStr = "/" + replaceStr; path = path.Replace(replaceStr, ""); string newName = ms.name; if (string.Equals(newName, SceneManager.GetActiveScene().name)) { newName = string.Format("{0}_{1}", newName, "mesh"); } path = path + "/" + newName; path = path.Replace("Assets/GameAssets/RawResources/scene/", ""); path = string.Format("SplitMesh/{0}", path); folderPath = path.Replace(string.Format("/{0}", newName), ""); return path; } //获取bounds最大的size private float GetMaxBoundSize(Bounds b) { float size = -1; size = b.size.x > b.size.y ? b.size.x : b.size.y; size = size > b.size.z ? size : b.size.z; return size; } //保存mesh private void SaveMesh(Mesh ms, string path, string folderPath) { if (ms == null) return; Mesh nMs = UnityEngine.Object.Instantiate(ms); string meshfolderPath = GetFolderPath(folderPath); if (!Directory.Exists(meshfolderPath)) Directory.CreateDirectory(meshfolderPath); string savePath = GetMeshAssetPath(path); #if UNITY_EDITOR //UnityEditor.AssetDatabase.CreateAsset(nMs, savePath); #endif } //获取mesh的路径 private string GetFolderPath( string path ) { var folderPath = string.Format("GameAssets/Resources/{0}", path); folderPath = Application.dataPath + "/" + folderPath; return folderPath; } //获取mesh资源路劲 public string GetMeshAssetPath(string path) { string assetPath = "Assets/GameAssets/Resources/"; assetPath = assetPath + path + ".asset"; return assetPath; } #endregion public Bounds GetBound() { return NodeBounds; } public void SetBound(Bounds b) { NodeBounds = b; } } //Render类型 public enum RendererType { None, //Mesh渲染 MeshRenderer, //skin SkinMesh, //粒子渲染 ParticleSystemRenderer, //拖尾粒子 TrailRender, } }