using System; using System.Collections.Generic; using UnityEngine; namespace Thousandto.Launcher.ExternalLibs { /// /// 场景数据资源还原系统类 /// public class SceneRestoreParts { #region//私有变量 private bool _isMatLoadFinished = false; private bool _isSetPartOver = false; private int _texReMainCount = 0; private Vector3 _pos = Vector3.zero; private SceneAssetsDiscriptFile _fileScript = null; //private ShowScenePartIndexs _firstShowParts = null; private Dictionary _dicMeshAsset = new Dictionary(); private Dictionary> _dicRegMesh = new Dictionary>(); //场景材质球 Dictionary _dicSceneMat = new Dictionary(); //加载mesh资源 private static Action> _loadMeshRes; private static Action> _loadParticeMesh; private static Action> _loadTextureRes; //static private static SceneRestoreParts _instance = null; #endregion #region//公共属性 private bool IsSetPartOver { get { return _isSetPartOver; } } #endregion #region//回调函数 private void OnMaterialTextureCallBack(Material mat, string pName) { _texReMainCount--; if (_texReMainCount == 0) { if (!_isMatLoadFinished) { _isMatLoadFinished = true; } } } private void RegMesh(Mesh ms, string path) { if (_dicMeshAsset.ContainsKey(path) && _dicMeshAsset[path] == null) { _dicMeshAsset[path] = ms; SetRegMeshes(path, ms); } } #endregion #region//私有函数 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.NType == NodeRootType.NearRoot || descrip.NType == NodeRootType.ParticNear) { if (descrip.Trans) { descrip.Trans.gameObject.SetActive(true); if (descrip.IsSetAsset) continue; var trans = descrip.Trans; Renderer rd = trans.GetComponent(); //SetMesh(descrip, trans, descrip.RenderType); descrip.IsSetAsset = true; //part.IsRePlace = true; } } //SetMaterial(descrip.MatsData, descrip.Trans, descrip.RenderType); } } private void SetMesh(SceneAssetDescript descrip, Transform trans, RendererType type) { //if (type != RendererType.ParticleSystemRenderer) //{ // int index = descrip.MeshIndexs != null && descrip.MeshIndexs.Length > 0 ? descrip.MeshIndexs[0] : -1; // if (index != -1) // { // string path = _fileScript.GetMeshPath(index); // //SetMesh(trans, path, type); // } //} //else //{ // List list = new List(); // for (int i = 0; descrip.MeshIndexs != null && i < descrip.MeshIndexs.Length; i++) // { // int index = descrip.MeshIndexs[i]; // string path = string.Empty; // if (descrip.SubMeshIndex != -1) // { // //网格被合并过 // path = _fileScript.GetCombinMeshPath(index); // } // else // { // //没有合并网格 // path = _fileScript.GetMeshPath(index); // } // if (!string.IsNullOrEmpty(path)) // { // list.Add(path); // } // } // //SetParticleMesh(trans, list.ToArray()); //} } private void SetMesh(Transform trans, string path ,RendererType type) { if (trans == null) return; if (_dicMeshAsset.ContainsKey(path)) { Mesh ms = _dicMeshAsset[path]; if (ms == null) { List list = null; if (_dicRegMesh.ContainsKey(path)) { list = _dicRegMesh[path]; if (list != null) { RegObj obj = new RegObj(); obj.trans = trans; obj.type = type; list.Add(obj); } } else { list = new List(); RegObj obj = new RegObj(); obj.trans = trans; obj.type = type; list.Add(obj); _dicRegMesh.Add(path, list); } } else { switch (type) { case RendererType.MeshRenderer: { MeshFilter mf = trans.GetComponent(); if (mf != null) { //mf.sharedMesh = ms; } } break; case RendererType.SkinMesh: { SkinnedMeshRenderer skinRender = trans.GetComponent(); if (skinRender != null) { //skinRender.sharedMesh = ms; } } break; } } } else { if (_loadMeshRes != null) { _loadMeshRes(path, (int)type, trans, RegMesh); } _dicMeshAsset.Add(path, null); } } private void SetParticleMesh(Transform trans, string[] paths) { int index = 0; List list = new List(); for (int i = 0; i < paths.Length; i++) { if (_dicMeshAsset.ContainsKey(paths[i])) { if (_dicMeshAsset[paths[i]] != null) { list.Add(_dicMeshAsset[paths[i]]); } index += 1; if (index == paths.Length) { ParticleSystemRenderer prd = trans.GetComponent(); //prd.SetMeshes(list.ToArray()); } } else { if (_loadParticeMesh != null) { _loadParticeMesh(paths[i], (ms)=> { if (ms != null) { list.Add(ms); index += 1; if (_dicMeshAsset.ContainsKey(paths[i])) { _dicMeshAsset[paths[i]] = ms; } if (index == paths.Length) { ParticleSystemRenderer prd = trans.GetComponent(); //prd.SetMeshes(list.ToArray()); } } }); } _dicMeshAsset.Add(paths[i], null); } } } private void SetRegMeshes(string path, Mesh ms) { if (!_dicRegMesh.ContainsKey(path)) return; List list = _dicRegMesh[path]; if (list == null) return; for (int i = 0; i < list.Count;i++) { switch (list[i].type) { case RendererType.MeshRenderer: { MeshFilter mf = list[i].trans.GetComponent(); if (mf != null) { //mf.sharedMesh = ms; } } break; case RendererType.SkinMesh: { SkinnedMeshRenderer skinRender = list[i].trans.GetComponent(); if (skinRender != null) { //skinRender.sharedMesh = ms; } } break; } } } private void SetMaterial(MatrialAssetData[] dataArray, Transform trans, RendererType type) { Material[] mats = new Material[dataArray.Length]; List matList = new List(dataArray.Length); for (int i = 0; i < dataArray.Length; i++) { Material mat = null; //mats[i] = if (_dicSceneMat.ContainsKey(dataArray[i].Index)) { mat = _dicSceneMat[dataArray[i].Index]; } else { mat = RestoreMaterail(dataArray[i]); _dicSceneMat.Add(dataArray[i].Index, mat); } matList.Add(mat); } mats = matList.ToArray(); switch (type) { case RendererType.MeshRenderer: { MeshRenderer mRd = trans.GetComponent(); if (mRd != null) { mRd.sharedMaterials = mats; } } break; case RendererType.SkinMesh: { SkinnedMeshRenderer sRd = trans.GetComponent(); if (sRd != null) { sRd.sharedMaterials = mats; } } break; case RendererType.ParticleSystemRenderer: { ParticleSystemRenderer pRd = trans.GetComponent(); if (pRd != null) { // 0 是 materail 1 是trailMaterail for (int i = 0; i < dataArray.Length; i++) { if (!dataArray[i].IsTrail) { if (_dicSceneMat.ContainsKey(dataArray[i].Index)) { pRd.sharedMaterial = _dicSceneMat[dataArray[i].Index]; } } else { if (_dicSceneMat.ContainsKey(dataArray[i].Index)) { pRd.trailMaterial = _dicSceneMat[dataArray[i].Index]; } } } } } break; } } private Material RestoreMaterail(MatrialAssetData data) { if (data == null) return null; if (data.Index == -1) return null; MatAssetsProperty property = _fileScript.GetMatProperty(data.Index); if (property == null) return null; Shader sh = PrefabAssetRuntimeUtil.FindShader(property.ShaderName); if (sh == null) { Debug.LogError("RestoreMaterial:not find shader;;" + property.ShaderName); return null; } Material mat = new Material(sh); //设置需要动态加载的纹理 if (property.TexIndexs != null) { //_isMatLoadFinished = false; _texReMainCount = property.TexIndexs.Length; for (int i = 0; i < property.TexIndexs.Length; i++) { //如果纹理名字是null //string texPath = _fileScript.GetTexturePath(property.TexIndexs[i].Index); Texture tex = property.TexIndexs[i].tex; if (tex == null) { mat.SetTexture(property.TexIndexs[i].Name, null); _texReMainCount--; } else { var texName = property.TexIndexs[i].Name; //if (_loadTextureRes != null) //{ // _loadTextureRes(texPath, (tex) => // { // mat.SetTexture(texName, tex); // }); //} mat.SetTexture(texName, tex); } mat .SetTextureOffset(property.TexIndexs[i].Name, property.TexOffset[i]); mat.SetTextureScale(property.TexIndexs[i].Name, property.TexScale[i]); } //if (_texReMainCount == 0) //{ // if (!_isMatLoadFinished) // { // _isMatLoadFinished = true; // } //} } //设置四元值 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); } } return mat; } #endregion #region//static函数 public static void InitSceneData(GameObject root, Vector3 pos, Action> loadMesh, Action> loadTexture, Action> loadParticeMesh,List posList, Dictionary> dic, Dictionary> typeDic) { _loadMeshRes = loadMesh; _loadParticeMesh = loadParticeMesh; _loadTextureRes = loadTexture; _instance = new SceneRestoreParts(); _instance.SetSceneData(root, pos, posList, dic, typeDic); } public static void RestoreLeftParts() { if (_instance != null) { List list = new List((int)CellType.Count); for (int i = 0; i < (int)CellType.Count; i++) { int row = (int)Math.Floor((_instance._pos.z - _instance._fileScript.Min.y) / (_instance._fileScript.Max.y - _instance._fileScript.Min.y) * _instance._fileScript.RC[i]); int col = (int)Math.Floor((_instance._pos.x - _instance._fileScript.Min.x) / (_instance._fileScript.Max.x - _instance._fileScript.Min.x) * _instance._fileScript.RC[i]); int cel = row * _instance._fileScript.RC[i] + col; list.Add(cel); } for (int i = 0; i < list.Count; i++) { ShowScenePartIndexs partIndex = new ShowScenePartIndexs(list[i], _instance._fileScript.RC[i]); if (i == 0) { _instance.SetOtherPartRes(_instance._fileScript.PBig, partIndex, _instance._fileScript.RC[i]); } else if (i == 1) { _instance.SetOtherPartRes(_instance._fileScript.PMidle, partIndex, _instance._fileScript.RC[i]); } else if (i == 2) { _instance.SetOtherPartRes(_instance._fileScript.PSmall, partIndex, _instance._fileScript.RC[i]); } } } } #endregion #region//私有函数 private void SetSceneData(GameObject root, Vector3 pos, List posList, Dictionary> dic, Dictionary> typeDic) { if (root == null) return; _fileScript = root.GetComponent(); if (_fileScript == null) return; _pos = pos; posList.Clear(); posList.Add(_fileScript.Min); posList.Add(_fileScript.Max); //int playerIndex = 0; dic.Clear(); typeDic.Clear(); for (int j = 0; j < (int)CellType.Count; j++) { var parts = _fileScript.GetParts((CellType)j); for (int k = 0; k < parts.Length; k++) { for (int m = 0; m < parts[k].Descripts.Length; m++) { var trans = parts[k].Descripts[m].Trans; if (parts[k] == null || parts[k].Descripts[m] == null || trans == null) { #if UNITY_EDITOR UnityEngine.Debug.LogError("场景远近处理数据错误"); #endif continue; } if (parts[k].Descripts[m].IsActive) { int key = k + 100000 * (j + 1); List l = dic.TryGetValue(key, out l) ? l : null; if (l != null) { l.Add(trans); } else { l = new List(parts[k].Descripts.Length); l.Add(trans); dic.Add(key, l); } List typeList = typeDic.TryGetValue(key, out typeList) ? typeList : null; if (typeList != null) { typeList.Add((int)parts[k].Descripts[m].NType); } else { typeList = new List(parts[k].Descripts.Length); typeList.Add((int)parts[k].Descripts[m].NType); typeDic.Add(key, typeList); } } //----暂时不处理场景物件隐藏 //if (parts[k].Descripts[m].NodeType == NodeRootType.Default || parts[k].Descripts[m].NodeType == NodeRootType.FarRoot || // parts[k].Descripts[m].NodeType == NodeRootType.Other || parts[k].Descripts[m].NodeType == NodeRootType.ParticFar) //{ // if (!trans.gameObject.activeSelf) // trans.gameObject.SetActive(true); //} //else //{ // if(trans.gameObject.activeSelf) // trans.gameObject.SetActive(false); //} } } } _dicMeshAsset.Clear(); _dicRegMesh.Clear(); _isSetPartOver = false; //_rowCol = _fileScript.RowCols[(int)CellType.Level_2]; List list = new List((int)CellType.Count); for (int i = 0; i < (int)CellType.Count; i++) { int row = (int)Math.Floor((pos.z - _fileScript.Min.y) / (_fileScript.Max.y - _fileScript.Min.y) * _fileScript.RC[i]); int col = (int)Math.Floor((pos.x - _fileScript.Min.x) / (_fileScript.Max.x - _fileScript.Min.x) * _fileScript.RC[i]); int cel = row * _fileScript.RC[i] + col; list.Add(cel); } //屏蔽场景快速显示第一部分模型和材质球还原,材质球还原已经被放在场景脚本里面调用,场景物件第一次初始化全部都是默认显示的 //for (int i = 0; i < list.Count; i++) //{ // ShowScenePartIndexs partIndex = new ShowScenePartIndexs(list[i], _fileScript.RowCols[i]); // if (i == 0) // { // SetFastPartRes(_fileScript.Parts_Big, partIndex); // } // else if (i == 1) // { // SetFastPartRes(_fileScript.Parts_Midle, partIndex); // } // else if (i == 2) // { // SetFastPartRes(_fileScript.Parts_Small, partIndex); // } //} //_firstShowParts = new ShowScenePartIndexs(playerIndex, _rowCol); //SetFastPartRes(_fileScript.Parts_Small); //SetOtherPartRes(_fileScript.Parts); } private bool IntersertBounds(Bounds bs, Vector3 pos) { if (bs.Contains(pos)) return true; return false; } #endregion #region//公共函数 //设置firstShowParts资源 public void SetFastPartRes(RegionPart[] partArray, ShowScenePartIndexs partIndex) { var enumer = partIndex.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { int index = enumer.Current.Value[i]; if (index == -1) continue; if (partArray.Length > index) { RegionPart part = partArray[index]; SetPartRender(part); } } } } finally { enumer.Dispose(); } } //顺序设置其他part资源 public void SetOtherPartRes(RegionPart[] partArray, ShowScenePartIndexs partIndex,int type) { while (partIndex.DicIndexs.Count != 0) { var enumer = partIndex.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { var list = enumer.Current.Value; for (int i = 0; i < list.Count; i++) { if (list[i] >= 0 && list[i] < partArray.Length) { RegionPart part = partArray[list[i]]; if(part != null && !part.IsRePlace) SetPartRender(part); } } } } finally { enumer.Dispose(); } partIndex.SetRoundIndexs(type); } _isSetPartOver = true; } #endregion #region//私有类 /// /// 格子索引数据类 /// public class ShowScenePartIndexs { #region//公共变量 private int _centerIndex = -1; private int _leftIndex = -1; private int _rightIndex = -1; private int _topIndex = -1; private int _bottomIndex = -1; private int _leftTopIndex = -1; private int _leftBottomIndex = -1; private int _rightTopIndex = -1; private int _rightBottomIndex = -1; private Dictionary> _dicIndexs = new Dictionary>((int)IndexType.Count); #endregion #region//公共属性 public int CenterIndex { get { return _centerIndex; } } public int LeftIndex { get { return _leftIndex; } } public int RightIndex { get { return _rightIndex; } } public int TopIndex { get { return _topIndex; } } public int BottomIndex { get { return _bottomIndex; } } public int LeftTopIndex { get { return _leftTopIndex; } } public int LeftBottomIndex { get { return _leftBottomIndex; } } public int RightTopIndex { get { return _rightTopIndex; } } public int RightBottomIndex { get { return _rightBottomIndex; } } public Dictionary> DicIndexs { get { return _dicIndexs; } } #endregion #region//构造函数 public ShowScenePartIndexs(int index, int rowCol) { ResetNineCel(index, rowCol); } public void ResetNineCel(int index, int rowCol) { int result = 0; int row = index / rowCol; _dicIndexs.Clear(); _centerIndex = index; result = _centerIndex - 1; _leftIndex = result >= row * rowCol ? result : -1; result = _centerIndex + 1; _rightIndex = result <= (row + 1) * rowCol - 1 ? result : -1; result = _centerIndex + rowCol; _topIndex = result < Mathf.Pow(rowCol, 2) ? result : -1; result = _centerIndex - rowCol; _bottomIndex = result >= 0 ? result : -1; result = _centerIndex + rowCol - 1; _leftTopIndex = result < Mathf.Pow(rowCol, 2) && result >= (row + 1) * rowCol ? result : -1; result = _centerIndex + rowCol + 1; _rightTopIndex = result < Mathf.Pow(rowCol, 2) && result <= (row + 1) * rowCol + rowCol - 1 ? result : -1; result = _centerIndex - rowCol - 1; _leftBottomIndex = result >= 0 && result >= (row - 1) * rowCol ? result : -1; result = _centerIndex - rowCol + 1; _rightBottomIndex = result >= 0 && result <= (row - 1) * rowCol + rowCol - 1 ? result : -1; List centerList = new List(); List leftList = new List(); List rightList = new List(); List topList = new List(); List bottomList = new List(); List leftTopList = new List(); List leftBottomList = new List(); List rightTopList = new List(); List rightBottomList = new List(); centerList.Add(_centerIndex); leftList.Add(_leftIndex); rightList.Add(_rightIndex); topList.Add(_topIndex); bottomList.Add(_bottomIndex); leftTopList.Add(_leftTopIndex); leftBottomList.Add(_leftBottomIndex); rightTopList.Add(_rightTopIndex); rightBottomList.Add(_rightBottomIndex); _dicIndexs.Add((int)IndexType.Center, centerList); _dicIndexs.Add((int)IndexType.Left, leftList); _dicIndexs.Add((int)IndexType.Right, rightList); _dicIndexs.Add((int)IndexType.Top, topList); _dicIndexs.Add((int)IndexType.Bottom, bottomList); _dicIndexs.Add((int)IndexType.LeftTop, leftTopList); _dicIndexs.Add((int)IndexType.LeftBottom, leftBottomList); _dicIndexs.Add((int)IndexType.RightTop, rightTopList); _dicIndexs.Add((int)IndexType.RightBottom, rightBottomList); } public void SetRoundIndexs(int rowCol) { List list = null; Dictionary> dicTemp = new Dictionary>(); if (_dicIndexs == null) return; int row = 0; int result = 0; //添加left Index List tempList1 = new List(); _dicIndexs.TryGetValue((int)IndexType.LeftTop, out list); if (list != null && list.Count > 0 && list[0] != -1) { row = list[0] / rowCol; result = list[0] - 1; result = result >= row * rowCol ? result : -1; if (result != -1) { tempList1.Add(result); //设置leftTop result = result + rowCol; result = result < Mathf.Pow(rowCol, 2) ? result : -1; if (result != -1) { List speList = new List(); speList.Add(result); dicTemp.Add((int)IndexType.LeftTop, speList); } } } _dicIndexs.TryGetValue((int)IndexType.Left, out list); if (list != null) { for (int i = 0; i < list.Count; i++) { row = list[i] / rowCol; result = list[i] - 1; result = result >= row * rowCol ? result : -1; if (result != -1) { tempList1.Add(result); } } } _dicIndexs.TryGetValue((int)IndexType.LeftBottom, out list); if (list != null) { row = list[0] / rowCol; result = list[0] - 1; result = result >= row * rowCol ? result : -1; if (result != -1) { tempList1.Add(result); //设置leftBottom List speList = new List(); result = result - rowCol; result = result >= 0 ? result : -1; if (result != -1) { speList.Add(result); dicTemp.Add((int)IndexType.LeftBottom, speList); } } } if (tempList1.Count > 0) { dicTemp.Add((int)IndexType.Left, tempList1); } //添加Riht Index List tempList2 = new List(); _dicIndexs.TryGetValue((int)IndexType.RightTop, out list); if (list != null && list.Count > 0 && list[0] != -1) { row = list[0] / rowCol; result = list[0] + 1; result = result <= (row + 1) * rowCol - 1 ? result : -1; if (result != -1) { tempList2.Add(result); //设置rightTop result = result + rowCol; result = result < Mathf.Pow(rowCol, 2) ? result : -1; if (result != -1) { List speList = new List(); speList.Add(result); dicTemp.Add((int)IndexType.RightTop, speList); } } } _dicIndexs.TryGetValue((int)IndexType.Right, out list); if (list != null) { for (int i = 0; i < list.Count; i++) { row = list[i] / rowCol; result = list[i] + 1; result = result <= (row + 1) * rowCol - 1 ? result : -1; if (result != -1) { tempList2.Add(result); } } } _dicIndexs.TryGetValue((int)IndexType.RightBottom, out list); if (list != null) { row = list[0] / rowCol; result = list[0] + 1; result = result <= (row + 1) * rowCol - 1 ? result : -1; if (result != -1) { tempList2.Add(result); //设置rightBottom List speList = new List(); result = result - rowCol; result = result >= 0 ? result : -1; if (result != -1) { speList.Add(result); dicTemp.Add((int)IndexType.RightBottom, speList); } } } if (tempList2.Count > 0) { dicTemp.Add((int)IndexType.Right, tempList2); } //添加Top Index List tempList3 = new List(); _dicIndexs.TryGetValue((int)IndexType.LeftTop, out list); if (list != null && list.Count > 0 && list[0] != -1) { row = list[0] / rowCol; result = list[0] + rowCol; result = result < Mathf.Pow(rowCol, 2) ? result : -1; if (result != -1) { tempList3.Add(result); list.Clear(); } } _dicIndexs.TryGetValue((int)IndexType.Top, out list); if (list != null) { for (int i = 0; i < list.Count; i++) { row = list[i] / rowCol; result = list[i] + rowCol; result = result < Mathf.Pow(rowCol, 2) ? result : -1; if (result != -1) { tempList3.Add(result); } } } _dicIndexs.TryGetValue((int)IndexType.RightTop, out list); if (list != null) { row = list[0] / rowCol; result = list[0] + rowCol; result = result < Mathf.Pow(rowCol, 2) ? result : -1; if (result != -1) { tempList3.Add(result); } } if (tempList3.Count > 0) { dicTemp.Add((int)IndexType.Top, tempList3); } //添加Bottom Index List tempList4 = new List(); _dicIndexs.TryGetValue((int)IndexType.LeftBottom, out list); if (list != null && list.Count > 0 && list[0] != -1) { row = list[0] / rowCol; result = list[0] - rowCol; result = result >= 0 ? result : -1; if (result != -1) { tempList4.Add(result); } } _dicIndexs.TryGetValue((int)IndexType.Bottom, out list); if (list != null) { for (int i = 0; i < list.Count; i++) { row = list[i] / rowCol; result = list[i] - rowCol; result = result >= 0 ? result : -1; if (result != -1) { tempList4.Add(result); } } } _dicIndexs.TryGetValue((int)IndexType.RightBottom, out list); if (list != null) { row = list[0] / rowCol; result = list[0] - rowCol; result = result >= 0 ? result : -1; if (result != -1) { tempList4.Add(result); } } if (tempList4.Count > 0) { dicTemp.Add((int)IndexType.Bottom, tempList4); } _dicIndexs.Clear(); _dicIndexs = dicTemp; } #endregion #region//enum private enum IndexType { Left = 0, Right, Top, Bottom, LeftTop, LeftBottom, RightTop, RightBottom, Center, Count, } #endregion } private class RegObj { public Transform trans = null; public RendererType type = RendererType.None; } #endregion } }