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
}
}