using Thousandto.Code.Logic; using Thousandto.Core.Asset; using Thousandto.Core.Base; using System; using System.Collections.Generic; using UnityEngine; namespace Thousandto.Code.Center { /// /// 场景数据资源还原系统类 /// public class SceneRestoreSystem { #region//私有变量 //三个等级rowCol wide private int[] _rowCols = null; private int[] _cellWides = null; //玩家所在区域的index private int[] _playerIndexs = new int[(int)PartType.Count]; private bool _isInit = false; private bool _enable = true; private bool _storyEnable = true; private bool _userMidleSetting = false; //雾效缩放距离 private float _fogScaleFactor = 1f; private Vector2 _initPos = Vector2.zero; //点前地图的最小点坐标 private Vector3 _min = Vector3.zero; //当前地图的最大点坐标 private Vector3 _max = Vector3.zero; private ShowScenePartIndexs _partSequence = null; //index:0 地图的最小点 index:1 地图最大点 private List _posList = new List(); private Dictionary> _transDic = new Dictionary>(); private Dictionary> _typeDic = new Dictionary>(); //big 区域 所有物件trans private Dictionary> _bigPartTransDic = new Dictionary>(); //midle 区域 所有物件trans private Dictionary> _midPartTransDic = new Dictionary>(); //small 区域 所有物件trans private Dictionary> _smallPartTransDic = new Dictionary>(); //big 区域 所有物件Type private Dictionary> _bigPartTypeDic = new Dictionary>(); //mid 区域 所有物件Type private Dictionary> _midPartTypeDic = new Dictionary>(); //small 区域 所有物件Type private Dictionary> _smallPartTypeDic = new Dictionary>(); //缓存mid大小的物件 private List _cacheMidTrans = new List(); private List _prevSmallPartIndexs = new List(32); private List _curSmallPartIndexs = new List(32); private static Action> _loadMesh = null; private static Action> _loadParticeMesh = null; private static Action> _loadTexture = null; //sceneRestorePart代理类 private SceneRestoreProxy _srProxy = null; //是否替换场景shader private bool _isReplaceSimpleShader = false; //是否替换场景半透明shader private bool _isReplaceBlendShader = false; //是否替换场景中简单的mesh private bool _isReplaceSimpleMesh = false; //透明shader名字数组 //不带法线 private string[] _blend_Names = { "Ares/Scene/Diffuse_AlphaBlend", "Ares/Scene/Diffuse_AlphaBlend_RGB", "Ares/Animation/AlphaScrollingTwoUV", "Ares/Animation/AlphaScrollingTwoUV_Add", "Ares/Animation/AlphaScrollingTwoUV_Add_RGB", "Ares/Animation/AlphaScrollingTwoUV_RGB", "Ares/Animation/AlphaScrollingUV", "Ares/Animation/AlphaScrollingUV_Add", "Ares/Animation/AlphaScrollingUV_Add_RGB", "Ares/Animation/AlphaScrollingUV_RGB", "Ares/Animation/Wind_UVA_Alpha", "Ares/Animation/Wind_UVA_Alpha_RGB", }; private string _blend_Re_Name = "Ares/Scene/Diffuse"; //带法线 private string[] _blend_N_Names = { "Ares/Scene/Diffuse_AlphaBlend", "Ares/Scene/Diffuse_AlphaBlend_RGB", }; private string _blend_Re_N_Name = "Ares/Scene/Diffuse_Normal"; //替换cube private GameObject _replaceCube = null; //所有的ParticFar节点 private List _allParticFarList = new List(); //所有的FarRoot节点 private List _allFarNodeList = new List(); #endregion #region//const 常量 private const int BIG_PART_KEY = 100000; private const int MID_PART_KEY = 200000; private const int SMALL_PART_KEY = 300000; #endregion #region//属性 public Vector2 InitPos { get { return _initPos; } set { _initPos = value; } } public bool Enable { get { return _enable; } set { if (_enable != value) { try { if (_transDic != null) { var enumer = _transDic.GetEnumerator(); try { if (value) { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { if (enumer.Current.Value[i] != null) enumer.Current.Value[i].gameObject.SetActive(!value); } } } else { //高品质 LocalPlayer lp = GameCenter.GameSceneSystem.GetLocalPlayer(); if (lp != null) { InitDisableSetting(lp.Position); } SetVfxIn_MidleSmallPart(_playerIndexs[(int)PartType.Level_1], true); } } finally { enumer.Dispose(); } } if (_isInit) { for (int i = 0; i < _allParticFarList.Count; i++) { GameObject go = _allParticFarList[i].gameObject; if (go && !go.activeSelf) { go.SetActive(true); } } for (int i = 0; i < _allFarNodeList.Count; i++) { GameObject go = _allFarNodeList[i].gameObject; if (go && !go.activeSelf) { go.SetActive(true); } } SetBigPartShow(); SetMidlePartShow(_playerIndexs[(int)PartType.Level_1], true); SetSmallPartShow(_playerIndexs[(int)PartType.Level_2], true); } } catch (Exception e) { UnityEngine.Debug.LogError(string.Format("场景远景裁剪处理设置失败!!!!{0}", e)); } } _enable = value; } } public bool StoryEnable { get { return _storyEnable; } set { _storyEnable = value; if (!_storyEnable) { if (_transDic != null) { var enumer = _transDic.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { if(enumer.Current.Value[i] != null && !enumer.Current.Value[i].gameObject.activeSelf) enumer.Current.Value[i].gameObject.SetActive(true); } } } finally { enumer.Dispose(); } } } } } public Vector3 Min { get { return _min; } } public Vector3 Max { get { return _max; } } //雾效缩放因子 public float FogScaleFactor { get { return _fogScaleFactor; } } public bool IsRePlaceSimpleShader { set { _isReplaceSimpleShader = value; if (value) { RePlaceShader(); } } } public bool IsReplaceBlendShader { set { _isReplaceBlendShader = value; if (value) { RePlaceBlendShader(); } } } public bool IsReplaceSimpleMesh { set { _isReplaceSimpleMesh = value; if (value) { RePlaceSimpleMesh(); } } } #endregion #region//回调函数 //private void OnSettingChanged(object o, object sender = null) //{ // GameSettingKeyCode code = (GameSettingKeyCode)o; // if (code == GameSettingKeyCode.QualityLevel) // { // int value = GameCenter.GameSetting.GetSetting(GameSettingKeyCode.QualityLevel); // SetEnable(value); // } //} #endregion #region//公共属性 #endregion #region//私有函数 private void LoadMesh(string path, int type, Transform trans, Action regMesh) { ResourcesEx.LoadAsync(path, AssetTypeCode.Mesh, (o, b, err) => { if (o is Mesh) { Mesh ms = o as Mesh; switch (type) { case (int)SceneNodeRendererType.MeshRenderer: { MeshFilter mf = trans.GetComponent(); if (mf != null) { mf.sharedMesh = ms; } } break; case (int)SceneNodeRendererType.SkinMesh: { SkinnedMeshRenderer skinRender = trans.GetComponent(); if (skinRender != null) { skinRender.sharedMesh = ms; } } break; } if (regMesh != null) { regMesh(ms, path); } } }, AsyncActionType.LoadObject); } private void LoadParticeMesh(string path, Action action) { ResourcesEx.LoadAsync(path, AssetTypeCode.Mesh, (o, b, err) => { if (o is Mesh) { Mesh ms = o as Mesh; if (action != null) { action(ms); } } }, AsyncActionType.LoadObject); } private void LoadTexture(string path, Action action) { TextureManager.SharedInstance.LoadTexture(path, (info) => { if (action != null) { action(info.AssetObject); } }); } //设置各个层级格子的行列数 private void SetPartRowCols(int standWide, ref int rowCol) { float wide = _max.x - _min.x; float celWide = wide / 1; SetRowCol(celWide, wide, standWide, ref rowCol); } private void SetRowCol(float celWide, float wide, float standWide, ref int rowCol) { if (celWide > standWide) { rowCol += 1; celWide = wide / rowCol; SetRowCol(celWide, wide, standWide, ref rowCol); } } //获取玩家所在格子的索引 private int[] _playerCellCache = new int[(int)PartType.Count]; private int[] GetPlayerCel(Vector3 pos) { for (int i = 0; i < (int)PartType.Count; i++) { int row = (int)Math.Floor((pos.z - _min.y) / (_max.y - _min.y) * _rowCols[i]); int col = (int)Math.Floor((pos.x - _min.x) / (_max.x - _min.x) * _rowCols[i]); int cel = row * _rowCols[i] + col; _playerCellCache[i] = cel; } return _playerCellCache; } //设置大格子包含的小格子序号 private Dictionary GetSmallCellRangeByBigIndex(int cellId) { Dictionary ret = new Dictionary(); _partSequence.ResetNineCel(cellId, _rowCols[(int)PartType.Level_0]); var enumer = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { for (int m = 0; m < enumer.Current.Value.Count; m++) { int index = enumer.Current.Value[m]; int cr = _rowCols[(int)PartType.Level_0]; int num = cr * 9; int row = index / cr; int col = index % cr; int min = row * 9 * num + col * 9; int max = (row + 1) * 9 * num - num + col * 9 + 9; for (int i = min; i < max; i++) { int sRow = i / num; int sCol = i % num; //计算当前行的起始值 int sMax = sRow * num + col * 9 + 9 - 1; int sMin = sMax - 9; if (i > sMin && i <= sMax) { ret.Add(i, 1); } } } } } finally { enumer.Dispose(); } return ret; } //区分物件属于哪个区域 private void DiferencePartTrans() { var enumer = _transDic.GetEnumerator(); try { while (enumer.MoveNext()) { int key = enumer.Current.Key; for (int i = 0; i < enumer.Current.Value.Count; i++) { int count = enumer.Current.Value.Count; Transform trans = enumer.Current.Value[i]; if (key >= BIG_PART_KEY && key< MID_PART_KEY) { AddPartTrans(key, BIG_PART_KEY, trans, _bigPartTransDic, count); } else if (key >= MID_PART_KEY && key < SMALL_PART_KEY) { AddPartTrans(key, MID_PART_KEY, trans, _midPartTransDic, count); } else if (key >= SMALL_PART_KEY) { AddPartTrans(key, SMALL_PART_KEY, trans, _smallPartTransDic, count); } } } } finally { enumer.Dispose(); } } //区分物件type所属区域 private void DiferencePartTransType() { var enumer = _typeDic.GetEnumerator(); try { while (enumer.MoveNext()) { int key = enumer.Current.Key; for (int i = 0; i < enumer.Current.Value.Count; i++) { int count = enumer.Current.Value.Count; int type = enumer.Current.Value[i]; if (key >= BIG_PART_KEY && key= MID_PART_KEY && key < SMALL_PART_KEY) { AddPartType(key, MID_PART_KEY, type, _midPartTypeDic, count, _midPartTransDic); } else if (key >= SMALL_PART_KEY) { AddPartType(key, SMALL_PART_KEY, type, _smallPartTypeDic, count, _smallPartTransDic); } } } } finally { enumer.Dispose(); } } private void AddPartTrans(int index, int partKey, Transform trans, Dictionary> dic, int count) { int key = index % partKey; List list = dic.TryGetValue(key,out list) ? list:null; if (list != null) { list.Add(trans); } else { list = new List(count); list.Add(trans); dic.Add(key, list); } } private void AddPartType(int index, int partKey, int type, Dictionary> dic, int count, Dictionary> transDic) { int key = index % partKey; List list = dic.TryGetValue(key,out list)? list:null; if (list!= null) { list.Add(type); } else { list = new List(count); list.Add(type); dic.Add(key, list); } if (type == (int)NodeRootType.ParticFar && transDic.ContainsKey(key)) { List transList = transDic[key]; if (transList != null && list.Count <= transList.Count) { Transform trans = transList[list.Count - 1]; if (trans && !trans.gameObject.activeSelf) { trans.gameObject.SetActive(true); _allParticFarList.Add(trans); } } } else if (type == (int)NodeRootType.FarRoot && transDic.ContainsKey(key)) { List transList = transDic[key]; if (transList != null && list.Count <= transList.Count) { Transform trans = transList[list.Count - 1]; if (trans && !trans.gameObject.activeSelf) { trans.gameObject.SetActive(true); _allFarNodeList.Add(trans); } } } } //高画质设置 private void InitDisableSetting(Vector3 pos) { var enumerSmall = _smallPartTransDic.GetEnumerator(); try { while (enumerSmall.MoveNext()) { List listTrans = _smallPartTransDic[enumerSmall.Current.Key]; List typeList = _smallPartTypeDic[enumerSmall.Current.Key]; for (int i = 0; i < listTrans.Count; i++) { var trans = listTrans[i]; if (trans) { if (typeList[i] == (int)NodeRootType.ParticMidle || typeList[i] == (int)NodeRootType.ParticNear) { SetVisable(false, trans); } else { SetVisable(true, trans); } } } } } finally { enumerSmall.Dispose(); } var enumerMid = _midPartTransDic.GetEnumerator(); try { while (enumerMid.MoveNext()) { List listTrans = _midPartTransDic[enumerMid.Current.Key]; List typeList = _midPartTypeDic[enumerMid.Current.Key]; for (int i = 0; i < listTrans.Count; i++) { var trans = listTrans[i]; if (trans) { if (typeList[i] == (int)NodeRootType.ParticMidle || typeList[i] == (int)NodeRootType.ParticNear) { SetVisable(false, trans); } else { SetVisable(true, trans); } } } } } finally { enumerMid.Dispose(); } //设置bigPart var enumerBig = _bigPartTransDic.GetEnumerator(); try { while (enumerBig.MoveNext()) { List listTrans = _bigPartTransDic[enumerBig.Current.Key]; List typeList = _bigPartTypeDic[enumerBig.Current.Key]; //只显示物件不显示mid mear 特效 for (int m = 0; m < listTrans.Count; m++) { Transform trans = listTrans[m]; if (trans) { if (typeList[m] == (int)NodeRootType.ParticMidle || typeList[m] == (int)NodeRootType.ParticNear) { SetVisable(false, trans); } else { SetVisable(true, trans); } } } } } finally { enumerBig.Dispose(); } } //高画质设置 private void InitEnableSetting(Vector3 pos) { var enumerSmall = _smallPartTransDic.GetEnumerator(); try { while (enumerSmall.MoveNext()) { List listTrans = _smallPartTransDic[enumerSmall.Current.Key]; List typeList = _smallPartTypeDic[enumerSmall.Current.Key]; for (int i = 0; i < listTrans.Count; i++) { var trans = listTrans[i]; if (trans) { if (typeList[i] == (int)NodeRootType.ParticFar) { SetVisable(true, trans); } } } } } finally { enumerSmall.Dispose(); } var enumerMid = _midPartTransDic.GetEnumerator(); try { while (enumerMid.MoveNext()) { List listTrans = _midPartTransDic[enumerMid.Current.Key]; List typeList = _midPartTypeDic[enumerMid.Current.Key]; for (int i = 0; i < listTrans.Count; i++) { var trans = listTrans[i]; if (trans) { if (typeList[i] == (int)NodeRootType.ParticFar) { SetVisable(true, trans); } } } } } finally { enumerMid.Dispose(); } //设置bigPart var enumerBig = _bigPartTransDic.GetEnumerator(); try { while (enumerBig.MoveNext()) { List listTrans = _bigPartTransDic[enumerBig.Current.Key]; List typeList = _bigPartTypeDic[enumerBig.Current.Key]; //只显示物件不显示mid mear 特效 for (int m = 0; m < listTrans.Count; m++) { Transform trans = listTrans[m]; if (trans) { if (typeList[m] == (int)NodeRootType.ParticFar) { SetVisable(false, trans); } } } } } finally { enumerBig.Dispose(); } } //设置 90 乘以 90 格子显示 private void SetBigPartShow() { var enumer = _bigPartTransDic.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { var trans = enumer.Current.Value[i]; if (trans && !trans.gameObject.activeSelf) trans.gameObject.SetActive(true); } } } finally { enumer.Dispose(); } } //设置30 乘以 30 九宫格显示 以玩家所在格子为中心的九宫格内除了 near 层的 物件都显示出来 private void SetMidlePartShow(int playerCell, bool visable = true) { if (_rowCols != null && _rowCols[(int)PartType.Level_1] != 0) { _partSequence.ResetNineCel(playerCell, _rowCols[(int)PartType.Level_1]); } var enumer = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { int index = enumer.Current.Value[i]; if (_midPartTransDic.ContainsKey(index) && _midPartTypeDic.ContainsKey(index)) { List listTrans = _midPartTransDic[index]; List typeList = _midPartTypeDic[index]; for (int m = 0; m < listTrans.Count; m++) { Transform trans = listTrans[m]; if (typeList[m] == (int)NodeRootType.FarRoot || typeList[m] == (int)NodeRootType.ParticFar) { if (trans) { if (!trans.gameObject.activeSelf) { trans.gameObject.SetActive(true); } } } if (trans) SetVisable(visable, trans); } } ShowScenePartIndexs partsIndex = new ShowScenePartIndexs(); int row = index / _rowCols[(int)PartType.Level_1]; int col = index % _rowCols[(int)PartType.Level_1]; row = row * 3 + 1; col = col * 3 + 1; int cel = row * _rowCols[(int)PartType.Level_2] + col; if (_rowCols != null && _rowCols[(int)PartType.Level_2] != 0) { partsIndex.ResetNineCel(cel, _rowCols[(int)PartType.Level_2]); } var enum_small = partsIndex.DicIndexs.GetEnumerator(); try { while (enum_small.MoveNext()) { int smallIndex = enum_small.Current.Value[i]; if (_smallPartTransDic.ContainsKey(smallIndex) && _smallPartTypeDic.ContainsKey(smallIndex)) { List listTrans = _smallPartTransDic[smallIndex]; List typeList = _smallPartTypeDic[smallIndex]; for (int m = 0; m < listTrans.Count; m++) { Transform trans = listTrans[m]; if (typeList[m] == (int)NodeRootType.FarRoot || typeList[m] == (int)NodeRootType.ParticFar) { if (trans) { if (!trans.gameObject.activeSelf) { trans.gameObject.SetActive(true); } } } //如果使用中品质 if (_userMidleSetting) { //显示mid和near 物件 if (trans) SetVisable(visable, trans); } else { //显示mid 物件 if (trans && typeList[m] == (int)NodeRootType.MidleRoot) SetVisable(visable, trans); } } } } } finally { enum_small.Dispose(); } } } } finally { enumer.Dispose(); } } //隐藏mid格子中的small格子的物件 private void SetTransIn_MidleSmallPart(int playerCell, bool visable) { if (_rowCols != null && _rowCols[(int)PartType.Level_1] != 0) { _partSequence.ResetNineCel(playerCell, _rowCols[(int)PartType.Level_1]); } var enumer = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { int index = enumer.Current.Value[i]; ShowScenePartIndexs partsIndex = new ShowScenePartIndexs(); int row = index / _rowCols[(int)PartType.Level_1]; int col = index % _rowCols[(int)PartType.Level_1]; row = row * 3 + 1; col = col * 3 + 1; int cel = row * _rowCols[(int)PartType.Level_2] + col; if (_rowCols != null && _rowCols[(int)PartType.Level_2] != 0) { partsIndex.ResetNineCel(cel, _rowCols[(int)PartType.Level_2]); } var enum_small = partsIndex.DicIndexs.GetEnumerator(); while (enum_small.MoveNext()) { int smallIndex = enum_small.Current.Value[i]; if (_smallPartTransDic.ContainsKey(smallIndex) && _smallPartTypeDic.ContainsKey(smallIndex)) { List listTrans = _smallPartTransDic[smallIndex]; List typeList = _smallPartTypeDic[smallIndex]; for (int m = 0; m < listTrans.Count; m++) { if (typeList[m] == (int)NodeRootType.FarRoot || typeList[m] == (int)NodeRootType.ParticFar) { if (listTrans[m]) continue; } if (listTrans[m]) { SetVisable(visable, listTrans[m]); } } } } } } } finally { enumer.Dispose(); } } //隐藏mid格子中的small格子的物件 private void SetVfxIn_MidleSmallPart(int playerCell, bool visable) { if (_partSequence == null) return; if (_rowCols != null && _rowCols[(int)PartType.Level_1] != 0) { _partSequence.ResetNineCel(playerCell, _rowCols[(int)PartType.Level_1]); } var enumer = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { int index = enumer.Current.Value[i]; if (_midPartTransDic.ContainsKey(index)) { List midListTrans = _midPartTransDic[index]; List midTypeList = _midPartTypeDic[index]; for (int k = 0; k < midListTrans.Count; k++) { if (midTypeList[k] == (int)NodeRootType.ParticMidle || midTypeList[k] == (int)NodeRootType.ParticNear) { SetVisable(visable, midListTrans[k]); } } } ShowScenePartIndexs partsIndex = new ShowScenePartIndexs(); int row = 0; int col = 0; if (_rowCols[(int)PartType.Level_1] != 0) { row = index / _rowCols[(int)PartType.Level_1]; col = index % _rowCols[(int)PartType.Level_1]; } row = row * 3 + 1; col = col * 3 + 1; int cel = row * _rowCols[(int)PartType.Level_2] + col; if (_rowCols != null && _rowCols[(int)PartType.Level_2] != 0) { partsIndex.ResetNineCel(cel, _rowCols[(int)PartType.Level_2]); } var enum_small = partsIndex.DicIndexs.GetEnumerator(); while (enum_small.MoveNext()) { int smallIndex = enum_small.Current.Value[i]; if (_smallPartTransDic.ContainsKey(smallIndex) && _smallPartTypeDic.ContainsKey(smallIndex)) { List listTrans = _smallPartTransDic[smallIndex]; List typeList = _smallPartTypeDic[smallIndex]; for (int m = 0; m < listTrans.Count; m++) { if (typeList[m] == (int)NodeRootType.ParticMidle || typeList[m] == (int)NodeRootType.ParticNear) { if (listTrans[m]) { SetVisable(visable, listTrans[m]); } } } } } } } } finally { enumer.Dispose(); } } private void HideOverPart(int prevPlayerCell, int curPlayerCell, PartType partType,Dictionary> partIndexs, Dictionary> partTypes) { _prevSmallPartIndexs.Clear(); _curSmallPartIndexs.Clear(); if (_rowCols != null && _rowCols[(int)partType] != 0) { _partSequence.ResetNineCel(prevPlayerCell, _rowCols[(int)partType]); } var enumer1 = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer1.MoveNext()) { for (int i = 0; i < enumer1.Current.Value.Count; i++) { int index1 = enumer1.Current.Value[i]; _prevSmallPartIndexs.Add(index1); } } } finally { enumer1.Dispose(); } if (_rowCols != null && _rowCols[(int)partType] != 0) { _partSequence.ResetNineCel(curPlayerCell, _rowCols[(int)partType]); } var enumer2 = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer2.MoveNext()) { for (int m = 0; m < enumer2.Current.Value.Count; m++) { int index2 = enumer2.Current.Value[m]; _curSmallPartIndexs.Add(index2); } } } finally { enumer2.Dispose(); } for (int i = 0; i < _prevSmallPartIndexs.Count; i++) { bool isFind = false; for (int m = 0; m < _curSmallPartIndexs.Count; m++) { if (_prevSmallPartIndexs[i] == _curSmallPartIndexs[m]) { isFind = true; } } if (!isFind) { var index = _prevSmallPartIndexs[i]; if (partIndexs.ContainsKey(index) && partIndexs.ContainsKey(index)) { List listTrans = partIndexs[index]; List typeList = partTypes[index]; for (int m = 0; m < listTrans.Count; m++) { if (listTrans[m]) { if (partType == PartType.Level_2) { if (typeList[m] == (int)NodeRootType.MidleRoot || typeList[m] == (int)NodeRootType.ParticMidle || typeList[m] == (int)NodeRootType.FarRoot || typeList[m] == (int)NodeRootType.ParticFar) { continue; } else { SetVisable(false, listTrans[m]); } } else { if (typeList[m] == (int)NodeRootType.FarRoot || typeList[m] == (int)NodeRootType.ParticFar) { continue; } else { SetVisable(false, listTrans[m]); } } } } } } } } //设置10 乘以 10 九宫格显示 以玩家所在格子为中心的九宫格内的所有 near层的物件都显示出来 其他物件都隐藏 private void SetSmallPartShow(int playerCell,bool visable = true) { if (_rowCols != null && _rowCols[(int)PartType.Level_2] != 0) { _partSequence.ResetNineCel(playerCell, _rowCols[(int)PartType.Level_2]); } var enumer = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { int index = enumer.Current.Value[i]; if (_smallPartTransDic.ContainsKey(index) && _smallPartTypeDic.ContainsKey(index)) { List listTrans = _smallPartTransDic[index]; List typeList = _smallPartTypeDic[index]; for (int m = 0; m < listTrans.Count; m++) { if (listTrans[m]) { if (typeList[m] == (int)NodeRootType.ParticNearHide) { if (visable) continue; } else { if (!visable) { if (typeList[m] == (int)NodeRootType.MidleRoot || typeList[m] == (int)NodeRootType.ParticMidle || typeList[m] == (int)NodeRootType.FarRoot || typeList[m] == (int)NodeRootType.ParticFar) { if (typeList[m] == (int)NodeRootType.MidleRoot || typeList[m] == (int)NodeRootType.ParticMidle) { _cacheMidTrans.Add(listTrans[m]); } continue; } else { SetVisable(visable, listTrans[m]); } } else { SetVisable(visable, listTrans[m]); } } } } } } } } finally { enumer.Dispose(); } } private void SetSmallPartMidHide(int playerCell) { if (_rowCols != null && _rowCols[(int)PartType.Level_2] != 0) { _partSequence.ResetNineCel(playerCell, _rowCols[(int)PartType.Level_2]); } var enumer = _partSequence.DicIndexs.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { int index = enumer.Current.Value[i]; if (_smallPartTransDic.ContainsKey(index) && _smallPartTypeDic.ContainsKey(index)) { List listTrans = _smallPartTransDic[index]; List typeList = _smallPartTypeDic[index]; for (int m = 0; m < listTrans.Count; m++) { if (listTrans[m]) { for (int k = _cacheMidTrans.Count - 1; k >= 0; k--) { if (_cacheMidTrans[k] == listTrans[m]) { _cacheMidTrans.RemoveAt(k); } } } } for (int m = _cacheMidTrans.Count - 1; m >= 0; m--) { _cacheMidTrans[m].gameObject.SetActive(false); _cacheMidTrans.RemoveAt(m); } _cacheMidTrans.Clear(); } } } } finally { enumer.Dispose(); } } private void SetVisable(bool visable, Transform trans) { //if (!GameCenter.SceneOcSystem.IsLoadFinish) //{ // trans.gameObject.SetActive(visable); // return; //} //if (visable) //{ // if (CheckOcVisable(trans)) // { // trans.gameObject.SetActive(true); // return; // } //} //trans.gameObject.SetActive(false); if (trans.gameObject.activeSelf != visable) { trans.gameObject.SetActive(visable); } } private bool CheckOcVisable(Transform trans) { return GameCenter.SceneOcSystem.CheckOc(trans); } //替换简单shader private void RePlaceShader() { var enumer = _transDic.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { Transform trans = enumer.Current.Value[i]; Renderer rd = trans.GetComponent(); Shader sh = Shader.Find("Gonbest/FallBack/FBWithSimpleShader"); Material mat = new Material(sh); rd.sharedMaterial = mat; } } } finally { enumer.Dispose(); } } //替换半透明shader private void RePlaceBlendShader() { var enumer = _transDic.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { Transform trans = enumer.Current.Value[i]; Renderer rd = trans.GetComponent(); for (int m = 0; m < _blend_Names.Length; m++) { Shader sh = Shader.Find(_blend_Re_Name); Material mat = new Material(sh); rd.sharedMaterial = mat; } for (int m = 0; m < _blend_N_Names.Length; m++) { Shader sh = Shader.Find(_blend_Re_N_Name); Material mat = new Material(sh); rd.sharedMaterial = mat; } } } } finally { enumer.Dispose(); } } //替换简单mesh private void RePlaceSimpleMesh() { if (_replaceCube == null) { _replaceCube = CreateCube(); } if (_replaceCube) { _replaceCube.gameObject.SetActive(false); MeshFilter cubeMf = _replaceCube.GetComponent(); Mesh cubMesh = cubeMf == null ? null : cubeMf.sharedMesh; if (cubMesh) { var enumer = _transDic.GetEnumerator(); try { while (enumer.MoveNext()) { for (int i = 0; i < enumer.Current.Value.Count; i++) { Transform trans = enumer.Current.Value[i]; MeshFilter mf = trans.GetComponent(); if (mf) { mf.sharedMesh = cubMesh; } } } } finally { enumer.Dispose(); } } } } //创建cube private GameObject CreateCube() { GameObject cube = new GameObject("cube"); MeshFilter mf = cube.AddComponent(); MeshRenderer mr = cube.AddComponent(); Vector3[] vertices = new Vector3[24]; int[] triangles = new int[36]; //forward vertices[0].Set(0.5f, -0.5f, 0.5f); vertices[1].Set(-0.5f, -0.5f, 0.5f); vertices[2].Set(0.5f, 0.5f, 0.5f); vertices[3].Set(-0.5f, 0.5f, 0.5f); //back vertices[4].Set(vertices[2].x, vertices[2].y, -0.5f); vertices[5].Set(vertices[3].x, vertices[3].y, -0.5f); vertices[6].Set(vertices[0].x, vertices[0].y, -0.5f); vertices[7].Set(vertices[1].x, vertices[1].y, -0.5f); //up vertices[8] = vertices[2]; vertices[9] = vertices[3]; vertices[10] = vertices[4]; vertices[11] = vertices[5]; //down vertices[12].Set(vertices[10].x, -0.5f, vertices[10].z); vertices[13].Set(vertices[11].x, -0.5f, vertices[11].z); vertices[14].Set(vertices[8].x, -0.5f, vertices[8].z); vertices[15].Set(vertices[9].x, -0.5f, vertices[9].z); //right vertices[16] = vertices[6]; vertices[17] = vertices[0]; vertices[18] = vertices[4]; vertices[19] = vertices[2]; //left vertices[20].Set(-0.5f, vertices[18].y, vertices[18].z); vertices[21].Set(-0.5f, vertices[19].y, vertices[19].z); vertices[22].Set(-0.5f, vertices[16].y, vertices[16].z); vertices[23].Set(-0.5f, vertices[17].y, vertices[17].z); int currentCount = 0; for (int i = 0; i < 24; i = i + 4) { triangles[currentCount++] = i; triangles[currentCount++] = i + 3; triangles[currentCount++] = i + 1; triangles[currentCount++] = i; triangles[currentCount++] = i + 2; triangles[currentCount++] = i + 3; } mf.mesh.vertices = vertices; mf.mesh.triangles = triangles; return cube; } #endregion #region//公共函数 public void Initialize() { //GameCenter.EventManager.UnRegFixEventHandle(CoreEventDefine.EID_CORE_GAME_SETTING_CHANGED, OnSettingChanged); //GameCenter.EventManager.RegFixEventHandle(CoreEventDefine.EID_CORE_GAME_SETTING_CHANGED, OnSettingChanged); } public void Uninitialize() { //GameCenter.EventManager.UnRegFixEventHandle(CoreEventDefine.EID_CORE_GAME_SETTING_CHANGED, OnSettingChanged); } public void InitSceneData(GameObject sceneRoot, Vector2? position = null) { UnInitSceneData(); if (sceneRoot == null) return; _rowCols = new int[(int)PartType.Count]; for (int i = 0; i < _rowCols.Length; i++) { _rowCols[i] = 0; } _cellWides = new int[(int)PartType.Count]; _cellWides[0] = 90; _cellWides[1] = 30; _cellWides[2] = 10; _loadMesh = LoadMesh; _loadParticeMesh = LoadParticeMesh; _loadTexture = LoadTexture; try { Vector3 pos = new Vector3(position.Value.x, 0, position.Value.y); _srProxy = new SceneRestoreProxy(sceneRoot, _loadMesh, _loadTexture, _loadParticeMesh, _posList, _transDic, _typeDic, pos); if (_posList != null && _posList.Count >= 2) { _min = _posList[0]; _max = _posList[1]; for (int i = 0; i < (int)PartType.Count; i++) { SetPartRowCols(_cellWides[i], ref _rowCols[i]); } var array = GetPlayerCel(pos); for (int i = 0; i < _playerIndexs.Length; ++i) { _playerIndexs[i] = array[i]; } DiferencePartTrans(); DiferencePartTransType(); if (_partSequence == null) { _partSequence = new ShowScenePartIndexs(); } if (_enable) { SetBigPartShow(); SetMidlePartShow(_playerIndexs[(int)PartType.Level_1], true); SetSmallPartShow(_playerIndexs[(int)PartType.Level_2], true); } else { //高品质 InitDisableSetting(pos); SetVfxIn_MidleSmallPart(_playerIndexs[(int)PartType.Level_1], true); } if (_isReplaceSimpleShader) { RePlaceShader(); } if (_isReplaceBlendShader) { RePlaceBlendShader(); } if (_isReplaceSimpleMesh) { RePlaceSimpleMesh(); } _isInit = true; } } catch (Exception e) { UnityEngine.Debug.LogError(string.Format("加载地图远近处理数据失败!!!!{0}", e)); } } public void UnInitSceneData() { _posList.Clear(); _transDic.Clear(); _typeDic.Clear(); _smallPartTransDic.Clear(); _midPartTransDic.Clear(); _bigPartTransDic.Clear(); _smallPartTypeDic.Clear(); _midPartTypeDic.Clear(); _bigPartTypeDic.Clear(); _allParticFarList.Clear(); _allFarNodeList.Clear(); } public void RestoryLeftParts() { //if (!_enable) // return; if (_srProxy!=null) _srProxy.RestoryLeftParts(); //加载场景遮挡剔除数据 //GameCenter.SceneOcSystem.LoadParam(); } public void ClearCache() { _transDic.Clear(); _cacheMidTrans.Clear(); _isInit = false; } public void Update() { if (!_isInit) return; if (!_storyEnable) return; if (!_enable) { ////高品质 //LocalPlayer lp = GameCenter.GameSceneSystem.GetLocalPlayer(); //if (lp != null) //{ // int[] cells = GetPlayerCel(lp.Position); // if (cells[(int)PartType.Level_0] != _playerIndexs[(int)PartType.Level_0]) // { // //如果玩家位置变化了 // //隐藏之前格子的物件 // Dictionary smallCellIndexs = GetSmallCellRangeByBigIndex(_playerIndexs[(int)PartType.Level_0]); // var enumer = smallCellIndexs.GetEnumerator(); // try // { // while (enumer.MoveNext()) // { // bool b = _smallPartTransDic.ContainsKey(enumer.Current.Key); // if (b) // { // List listTrans = _smallPartTransDic[enumer.Current.Key]; // if (listTrans != null) // { // for (int i = 0; i < listTrans.Count; i++) // { // SetVisable(false, listTrans[i]); // } // } // } // } // } // finally // { // enumer.Dispose(); // } // _playerIndexs[(int)PartType.Level_0] = cells[(int)PartType.Level_0]; // SetPartByDisable(lp.Position); // } //} //return; } if (!IsValid()) return; UpdateAllPart(); } private void UpdateAllPart() { LocalPlayer lp = GameCenter.GameSceneSystem.GetLocalPlayer(); if (lp != null) { bool isMidChange = false; //更新玩家所在各个层级格子位置 int[] cells = GetPlayerCel(lp.Position); if (cells[(int)PartType.Level_1] != _playerIndexs[(int)PartType.Level_1]) { isMidChange = true; if (!_enable) { //如果是高品质 SetVfxIn_MidleSmallPart(_playerIndexs[(int)PartType.Level_1], false); SetVfxIn_MidleSmallPart(cells[(int)PartType.Level_1], true); _playerIndexs[(int)PartType.Level_1] = cells[(int)PartType.Level_1]; } else { UpdateMidlePart(cells); } } if (cells[(int)PartType.Level_2] != _playerIndexs[(int)PartType.Level_2]) { if (_enable) { UpdateSmallPart(cells, isMidChange); } } } } private void UpdateMidlePart(int[] cells) { //如果所在玩家Mid格子位置变更了 //清除一次缓存的mid物件 //重新显示small物件 SetSmallPartMidHide(_playerIndexs[(int)PartType.Level_2]); HideOverPart(_playerIndexs[(int)PartType.Level_1], cells[(int)PartType.Level_1], PartType.Level_1, _midPartTransDic, _midPartTypeDic); //隐藏mid中的small物件 SetTransIn_MidleSmallPart(_playerIndexs[(int)PartType.Level_1], false); //SetMidlePartShow(_playerIndexs[(int)PartType.Level_1], false); SetMidlePartShow(cells[(int)PartType.Level_1], true); _playerIndexs[(int)PartType.Level_1] = cells[(int)PartType.Level_1]; } private void UpdateSmallPart(int[] cells, bool isMidChange = false) { //如果所在玩家Small格子位置变更了 //SetSmallPartShow(_playerIndexs[(int)PartType.Level_2], false); if (_userMidleSetting) { if (cells[(int)PartType.Level_1] != _playerIndexs[(int)PartType.Level_1] || isMidChange) { HideOverPart(_playerIndexs[(int)PartType.Level_2], cells[(int)PartType.Level_2], PartType.Level_2, _smallPartTransDic, _smallPartTypeDic); } } else { HideOverPart(_playerIndexs[(int)PartType.Level_2], cells[(int)PartType.Level_2], PartType.Level_2, _smallPartTransDic, _smallPartTypeDic); } SetSmallPartShow(cells[(int)PartType.Level_2], true); _playerIndexs[(int)PartType.Level_2] = cells[(int)PartType.Level_2]; } private bool IsValid() { bool ret = true; if (_rowCols == null) return false; for (int i = 0; i < _rowCols.Length; i++) { if (_rowCols[i] == 0) ret = false; } return ret; } public void SetEnable(int value) { if (value == 2) { Enable = false; _userMidleSetting = false; } else if (value == 1) { _userMidleSetting = true; if (Enable) { //从低画质切换到中画质 LocalPlayer lp = GameCenter.GameSceneSystem.GetLocalPlayer(); if (lp != null && IsValid()) { int[] cells = GetPlayerCel(lp.Position); SetTransIn_MidleSmallPart(cells[(int)PartType.Level_1], true); } } Enable = true; } else { _userMidleSetting = false; if (Enable) { //从中画质切换到低画质 LocalPlayer lp = GameCenter.GameSceneSystem.GetLocalPlayer(); if (lp != null && IsValid()) { if (_rowCols != null) { int[] cells = GetPlayerCel(lp.Position); //隐藏midle中包含的small格子中的物件 SetTransIn_MidleSmallPart(cells[(int)PartType.Level_1], false); //重设small格子中的物件 SetSmallPartShow(cells[(int)PartType.Level_2], true); } } } Enable = true; } } public void SetAllDicTrans(Dictionary dic) { var enumer = _smallPartTransDic.GetEnumerator(); } public void SetDicTrans(Dictionary dic) { } public Dictionary> GetDicTrans() { return _transDic; } #endregion /// /// 格子索引类 /// private 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>(); #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() { } public ShowScenePartIndexs(int index, int rowCol) { ResetNineCel(index, rowCol); } public void ResetNineCel(int index, int rowCol) { if (rowCol == 0) return; 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); } #endregion #region//enum private enum IndexType { Left = 0, Right, Top, Bottom, LeftTop, LeftBottom, RightTop, RightBottom, Center, } #endregion } #region//私有枚举 //Render类型 private enum SceneNodeRendererType { None, //Mesh渲染 MeshRenderer, //skin SkinMesh, //粒子渲染 ParticleSystemRenderer, } private enum NodeRootType { Default = 0, FarRoot = 1, //远处可视节点 NearRoot, //进出可视节点 MidleRoot, //midel节点 ParticFar, //特效远 ParticMidle, //特效中 ParticNear, //特效进节点 ParticNearHide, //特效near节点隐藏 Other, //其他节点 } //part 类型 private enum PartType { Level_0 = 0, Level_1 = 1, Level_2 = 2, Count = 3, } #endregion } }