using System; using System.Collections.Generic; using UnityEngine; namespace Thousandto.Launcher.ExternalLibs { /// /// 场景地图区域数据 /// public class SceneAssetsDiscriptFile : MonoBehaviour { #region//私有变量 private int _multiLevel = 0; private List _listMeshPath = new List(); private List _listCombinMeshPath = new List(); //texture路径字典 private List _listTexName = new List(); private List _transList = new List(); //材质球属性字典 private Dictionary _dicMatProperty = new Dictionary(); //mesh合并数据 //private Dictionary> _dicCombinData = new Dictionary>(); private List _refrenceList = new List(); private List _cacheSceneTexs = new List(); private SceneMultiTexScript _multiTexScript = null; //场景纹理multi等级数据块 float[] _multiLevels = null; #endregion #region//公共变量 //格子行列(这里默认行列相等) //public int RowCol = 0; public int[] RC = null; //格子宽 public int[] CW = null; //public int CelWidth = 30; //地图最小坐标 public Vector2 Min = Vector2.zero; //地图最大坐标 public Vector2 Max = Vector2.zero; public RegionPart[] PBig = null; public RegionPart[] PMidle = null; public RegionPart[] PSmall = null; //所有物件纹理的路径 public string[] TexNames = null; //所有物件mesh的路径 //public string[] MeshPaths = null; //合并后的mesh路径 //public string[] CombinMeshPath = null; //所有物件mat属性 public MatAssetsProperty[] MatP_Dic = null; public static bool IsShowLine = true; //是否显示划线 #endregion #region// MonoBehaviour重载函数 private void Start() { //Core编译会报错,先屏蔽掉 dinghuaqiang //Code.Center.SceneRestoreProxy.SetSceneRestoreHandle(); RestoreMats(); } private void OnDestroy() { //移除特效贴图 SceneRestoreRunTimeUtils.ReleaseTexture(); #if !UNITY_EDITOR //移除场景贴图 for (int i = 0; i < _cacheSceneTexs.Count; i++) { Resources.UnloadAsset(_cacheSceneTexs[i]); _cacheSceneTexs[i] = null; } _cacheSceneTexs.Clear(); #endif //干掉材质球 var enumer = _dicSceneMat.GetEnumerator(); try { while (enumer.MoveNext()) { var mat = enumer.Current.Value; if (mat != null) { SceneRestoreRunTimeUtils.FreeMaterial(mat); } } } finally { enumer.Dispose(); } } #endregion #region//公共接口 private Dictionary _dicSceneMat = new Dictionary(); public void RestoreMats() { if (MatP_Dic != null && MatP_Dic.Length > 0) { SetParts(PBig); SetParts(PMidle); SetParts(PSmall); } } private void SetParts(RegionPart[] parts) { for (int i = 0; i < parts.Length; i++) { SetPartRender(parts[i]); } } private void SetPartRender(RegionPart part) { if (part == null) return; for (int i = 0; i < part.Descripts.Length; i++) { var descrip = part.Descripts[i]; if (descrip.Trans != null) { if (descrip.MatsData != null && descrip.MatsData.Length > 0) { SetMaterial(descrip.MatsData, descrip.Trans, descrip.RdType); } } } } private void SetMaterial(MatrialAssetData[] dataArray, Transform trans, RendererType type) { var trailIndex = -1; Material[] mats = new Material[dataArray.Length]; for (int i = 0; i < dataArray.Length; i++) { Material mat = null; if (!_dicSceneMat.TryGetValue(dataArray[i].Index, out mat)) { mat = RestoreMaterail(dataArray[i]); _dicSceneMat.Add(dataArray[i].Index, mat); } if(dataArray[i].IsTrail) { trailIndex = i; } mats[i] = mat; } switch (type) { case RendererType.MeshRenderer: { MeshRenderer mRd = trans.GetComponent(); mRd.sharedMaterials = mats; } break; case RendererType.SkinMesh: { SkinnedMeshRenderer sRd = trans.GetComponent(); sRd.sharedMaterials = mats; } break; case RendererType.ParticleSystemRenderer: { ParticleSystemRenderer pRd = trans.GetComponent(); if(trailIndex >= 0) { pRd.sharedMaterials = mats; Material mat = null; if (_dicSceneMat.TryGetValue(dataArray[trailIndex].Index, out mat)) { pRd.trailMaterial = mat; } } pRd.sharedMaterials = mats; } break; case RendererType.TrailRender: { TrailRenderer tRd = trans.GetComponent(); tRd.sharedMaterials = mats; } break; } } private Material RestoreMaterail(MatrialAssetData data) { if (data == null) return null; if (data.Index == -1) return null; MatAssetsProperty property = GetMatProperty(data.Index); if (property == null) return null; Shader sh = ShaderFactory.Find(property.ShaderName); if (sh == null) { Debug.LogError("RestoreMaterial:not find shader;;" + property.ShaderName); return null; } Material mat = SceneRestoreRunTimeUtils.NewMaterial(sh); //设置需要动态加载的纹理 if (property.TexIndexs != null) { //_isMatLoadFinished = false; for (int i = 0; i < property.TexIndexs.Length; i++) { Texture tex = null; //if (property.TexIndexs[i].MultiIndex != null && property.TexIndexs[i].MultiIndex.Length > 0) //{ // var length = property.TexIndexs[i].MultiIndex.Length; // for (int m = 0; m < length; m++) // { // var multiData = property.TexIndexs[i].MultiIndex[m]; // if (_multiLevels == null) // { // _multiLevels = GonbestGMemory.AllocFloatBlock("SceneMultiLevel", 1); // } // _multiLevel = (int)_multiLevels[0]; // //_multiLevel = 3; // if (_multiLevel == multiData.MultiIndex) // { // if (_multiTexScript == null) // { // _multiTexScript = GetMultiTexScript(); // } // if(multiData.Index< _multiTexScript.MultiTexs.Length) // tex = _multiTexScript.MultiTexs[multiData.Index]; // } // } //} //else //{ // tex = property.TexIndexs[i].tex; //} tex = property.TexIndexs[i].tex; if (property.TexIndexs[i].Index == -1) { mat.SetTexture(property.TexIndexs[i].Name, tex); _cacheSceneTexs.Add(tex); } else { string texName = property.TexIndexs[i].Name; string texPath = GetTexturePath(property.TexIndexs[i].Index); #if FUNCELL_LAUNCHER SceneRestoreRunTimeUtils.SetTexture(texPath, texName, (t)=> { mat.SetTexture(texName, t); }); #else #if UNITY_EDITOR texPath = ConstDefines.CN_RAW_VFX_TEXTURE_DIR + texPath; tex = UnityEditor.AssetDatabase.LoadAssetAtPath(texPath, typeof(Texture)) as Texture; mat.SetTexture(property.TexIndexs[i].Name, tex); #endif #endif } mat.SetTextureOffset(property.TexIndexs[i].Name, property.TexOffset[i]); mat.SetTextureScale(property.TexIndexs[i].Name, property.TexScale[i]); } } //设置四元值 if (property.Vec != null) { for (int i = 0; i < property.Vec.Length; i++) { mat.SetVector(property.Vec[i].Name, property.Vec[i].Value); } } //设置颜色 if (property.Color != null) { for (int i = 0; i < property.Color.Length; i++) { mat.SetColor(property.Color[i].Name, property.Color[i].Value); } } //设置float值 if (property.Float != null) { for (int i = 0; i < property.Float.Length; i++) { mat.SetFloat(property.Float[i].Name, property.Float[i].Value); } } //设置renderQueen if (property.Rdq == 0) { mat.renderQueue = sh.renderQueue; } else { mat.renderQueue = property.Rdq; } return mat; } public void Initialized() { RC = new int[(int)CellType.Count]; for (int i = 0; i < (int)CellType.Count; i++) { RC[i] = 1; } CW = new int[(int)CellType.Count]; CW[0] = (int)CellWideType.Wide_0; CW[1] = (int)CellWideType.Wide_1; CW[2] = (int)CellWideType.Wide_2; RefrenceSize size1 = new RefrenceSize(CellType.Level_0, RefrenceSize.RootType.Big, 45, int.MaxValue); RefrenceSize size2 = new RefrenceSize(CellType.Level_1, RefrenceSize.RootType.Mid, 3, 45); RefrenceSize size3 = new RefrenceSize(CellType.Level_2, RefrenceSize.RootType.Small, 0, 3); _refrenceList.Add(size1); _refrenceList.Add(size2); _refrenceList.Add(size3); } public void SetRegion(Vector2 min, Vector3 max, CellType type) { RC[(int)type] = 1; Min = min; Max = max; float wide = max.x - min.x; float high = max.y - min.y; float celWide = wide / RC[(int)type]; SetPart(celWide, wide, type); celWide = wide / RC[(int)type]; float celHigh = high / RC[(int)type]; int count = (int)Mathf.Pow(RC[(int)type], 2); var parts = NewParts(type, count); for (int i = 0; i < count; i++) { RegionPart part = new RegionPart(i, RC[(int)type], celWide, celHigh, Min); parts[i] = part; } } public int GetTexturePathIndex(string name, string path) { int index = 0; if (path.Contains(ConstDefines.CN_RAW_VFX_TEXTURE_DIR)) { path = path.Replace(ConstDefines.CN_RAW_VFX_TEXTURE_DIR, ""); } if (_listTexName.Contains(path)) { for (int i = 0; i < _listTexName.Count; i++) { if (string.Equals(_listTexName[i], path)) return i; } } else { _listTexName.Add(path); return _listTexName.Count - 1; } return index; } public void ConvertTexPath() { TexNames = _listTexName.ToArray(); _listTexName.Clear(); _listTexName = null; } public string GetTexturePath(int index) { if (index <= TexNames.Length - 1) { return TexNames[index]; } return string.Empty; } public void ConvertMeshPath() { //MeshPaths = _listMeshPath.ToArray(); } public void ConvertCombinMeshPath() { //CombinMeshPath = _listCombinMeshPath.ToArray(); } public int GetMeshPathIndex(string path) { int index = _listMeshPath.IndexOf(path); if(index < 0) { _listMeshPath.Add(path); return _listMeshPath.Count - 1; } return index; } public string GetMeshPath(int index) { //if (MeshPaths !=null && index < MeshPaths.Length) //{ // return MeshPaths[index]; //} return string.Empty; } //获取合并后mesh 的路径索引 public int GetCombinMeshPathIndex(string path) { int index = _listCombinMeshPath.IndexOf(path); if (index < 0) { _listCombinMeshPath.Add(path); return _listCombinMeshPath.Count - 1; } return index; } //获取合并后的mesh路径 public string GetCombinMeshPath(int index) { //if (CombinMeshPath != null && index < CombinMeshPath.Length) //{ // return CombinMeshPath[index]; //} return string.Empty; } //获取物件的index public int GetObjIndex(Transform trans) { int index = -1; if (trans == null) return index; index = _transList.IndexOf(trans); if (index < 0) { _transList.Add(trans); return _transList.Count - 1; } return index; } public int GetMatPropertyIndex(MatAssetsProperty property) { var name = property.name; int index = 0; var enumer = _dicMatProperty.GetEnumerator(); try { //shander 参数是设置相等 bool isEqual = true; //是否找到同名shander或者 ReName的同名shander bool isFind = false; while (enumer.MoveNext()) { if (string.Equals(enumer.Current.Key, name) || enumer.Current.Key.Contains(string.Format("{0}_ReName", name)))// { isEqual = true; isFind = true; MatAssetsProperty mp = enumer.Current.Value; for (int i = 0; i < mp.Vec.Length; i++) { if (mp.Vec.Length != property.Vec.Length) isEqual = false; else { if (!string.Equals(mp.Vec[i].Name, property.Vec[i].Name)) isEqual = false; if (mp.Vec[i].Value != property.Vec[i].Value) isEqual = false; } } if (mp.TexIndexs.Length != property.TexIndexs.Length) isEqual = false; else { for (int i = 0; i < mp.TexIndexs.Length; i++) { if (mp.TexIndexs[i].tex != property.TexIndexs[i].tex) isEqual = false; else { if (mp.TexIndexs[i].tex == null) { if (mp.TexIndexs[i].Index != property.TexIndexs[i].Index) isEqual = false; } } } } for (int i = 0; i < mp.Color.Length; i++) { if (mp.Color.Length != property.Color.Length) isEqual = false; else { if (!string.Equals(mp.Color[i].Name, property.Color[i].Name)) isEqual = false; if (mp.Color[i].Value != property.Color[i].Value) isEqual = false; } } for (int i = 0; i < mp.Float.Length; i++) { if (mp.Float.Length != property.Float.Length) isEqual = false; else { if (!string.Equals(mp.Float[i].Name, property.Float[i].Name)) isEqual = false; if (mp.Float[i].Value != property.Float[i].Value) isEqual = false; } } for (int i = 0; i < mp.TexOffset.Length; i++) { if (mp.TexOffset.Length != property.TexOffset.Length) isEqual = false; else { if (mp.TexOffset[i] != property.TexOffset[i]) isEqual = false; } } for (int i = 0; i < mp.TexScale.Length; i++) { if (mp.TexScale.Length != property.TexScale.Length) isEqual = false; else { if (mp.TexScale[i] != property.TexScale[i]) isEqual = false; } } if (mp.Rdq != property.Rdq) { isEqual = false; } if (isEqual) { //如果找到想的设置参数的shader 直接返回索引 return index; } } index += 1; } if (isFind) { if (!isEqual) { //如果shader设置不相等 添加进Dic 重置名字 string key = string.Format("{0}_ReName_{1}", name, _dicMatProperty.Count - 1); _dicMatProperty[key] = property; property.name = ""; return _dicMatProperty.Count - 1; } } else { //如果没有找到 直接添加进dic _dicMatProperty[name] = property; property.name = ""; return _dicMatProperty.Count - 1; } } finally { enumer.Dispose(); } return -1; } public MatAssetsProperty GetMatProperty(int index) { if (MatP_Dic != null && index < MatP_Dic.Length) { return MatP_Dic[index]; } return null; } public void ConvertMatProperty() { List list = new List(); var enumer = _dicMatProperty.GetEnumerator(); try { while (enumer.MoveNext()) { list.Add(enumer.Current.Value); } } finally { enumer.Dispose(); } MatP_Dic = list.ToArray(); _dicMatProperty.Clear(); _dicMatProperty = null; } public RegionPart[] GetParts(CellType type) { RegionPart[] parts = null; switch (type) { case CellType.Level_0: parts = PBig; break; case CellType.Level_1: parts = PMidle; break; case CellType.Level_2: parts = PSmall; break; } return parts; } public RefrenceSize GetRefSize(CellType type) { for (int i = 0; i < _refrenceList.Count; i++) { if (_refrenceList[i].Type == type) return _refrenceList[i]; } return null; } public SceneMultiTexScript GetMultiTexScript() { if (_multiTexScript == null) { _multiTexScript = transform.GetComponent(); } return _multiTexScript; } #endregion #region//私有函数 private void SetPart(float celWide, float wide, CellType type) { if (celWide > CW[(int)type]) { RC[(int)type] += 1; celWide = wide / RC[(int)type]; SetPart(celWide, wide, type); } } private RegionPart[] NewParts(CellType type, int count) { switch (type) { case CellType.Level_0: return PBig = new RegionPart[count]; case CellType.Level_1: return PMidle = new RegionPart[count]; case CellType.Level_2: return PSmall = new RegionPart[count]; } return null; } private void OnDrawGizmos() { if (!IsShowLine) return; CellType type = CellType.Level_2; Gizmos.color = Color.red; var parts = GetParts(type); if (parts == null || RC == null || RC.Length < 3) return; int tolCl = parts.Length / RC[2]; //总行数 int tolRl = RC[2]; //总列数 for (int i = 0; i < tolCl; i++) { Gizmos.DrawLine(parts[i * RC[2]].GetMin() + new Vector3(0f, 27, 0f), parts[i * RC[2] + (RC[2] - 1)].GetMin() + new Vector3(parts[i * RC[2] + (RC[2] - 1)].GetBounds().size.x, 27f, 0f)); } Gizmos.DrawLine(parts[(tolCl - 1) * RC[2]].GetMin() + new Vector3(0f, 27f, parts[(tolCl - 1) * RC[2]].GetBounds().size.z), parts[(tolCl - 1) * RC[2] + (RC[2] - 1)].GetMax() + new Vector3(0f, 27, 0f)); Gizmos.color = Color.blue; for (int i = 0; i < tolRl; i++) { Gizmos.DrawLine(parts[i].GetMin() + new Vector3(0f, 27, 0f), parts[RC[2] * (tolRl - 1) + i].GetMin() + new Vector3(0f, 27f, parts[RC[2] * (tolRl - 1) + i].GetBounds().size.z)); } Gizmos.DrawLine(parts[tolRl - 1].GetMin() + new Vector3(parts[tolRl - 1].GetBounds().size.x, 27f, 0f) , parts[RC[2] * (tolRl - 1) + (tolRl - 1)].GetMax() + new Vector3(0f, 27, 0f)); Gizmos.color = Color.blue; //Gizmos.DrawCube(Parts[0].Center, new Vector3(Parts[0].Bounds.size.x, 0f, Parts[0].Bounds.size.z)); Gizmos.DrawCube(new Vector3(Min.x, 10, Min.y), new Vector3(10, 10, 10)); Gizmos.color = Color.green; Gizmos.DrawCube(new Vector3(Max.x, 10, Max.y), new Vector3(10, 10, 10)); } #endregion } }