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