381 lines
14 KiB
C#
381 lines
14 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEngine.SceneManagement;
|
|||
|
|
|||
|
namespace Thousandto.Launcher.ExternalLibs
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 场景资源描述文件
|
|||
|
/// </summary>
|
|||
|
[Serializable]
|
|||
|
public class SceneAssetDescript
|
|||
|
{
|
|||
|
#region//私有变量
|
|||
|
private SceneAssetsDiscriptFile _script = null;
|
|||
|
private List<MatrialAssetData> _listMatData = new List<MatrialAssetData>(32);
|
|||
|
#endregion
|
|||
|
|
|||
|
#region//公共变量
|
|||
|
public Transform Trans = null;
|
|||
|
//mesh路径
|
|||
|
//public string[] MeshPaths = null;
|
|||
|
//合并后的网格名字
|
|||
|
//public string CombinName = string.Empty;
|
|||
|
//mesh路径索引
|
|||
|
//public int[] MeshIndexs = null;
|
|||
|
//subMesh 索引
|
|||
|
//public int SubMeshIndex = -1;
|
|||
|
//排序extend
|
|||
|
public float Sort = 0;
|
|||
|
//render类型
|
|||
|
public RendererType RdType = RendererType.None;
|
|||
|
//node类型
|
|||
|
public NodeRootType NType = NodeRootType.Default;
|
|||
|
//包围盒
|
|||
|
private Bounds NodeBounds;
|
|||
|
//材质属性
|
|||
|
public MatrialAssetData[] MatsData = null;
|
|||
|
//加载优先级
|
|||
|
//public NodeRootType RootType = NodeRootType.Default;
|
|||
|
public bool IsSetAsset = false;
|
|||
|
public bool IsActive = false;
|
|||
|
#endregion
|
|||
|
|
|||
|
//场景可视节点名字定义
|
|||
|
public static string FarRootName = "[Far]";
|
|||
|
public static string MidRootName = "[Mid]";
|
|||
|
public static string NearRootName = "[Near]";
|
|||
|
|
|||
|
private Material _defaultMat = null;
|
|||
|
private Shader _defaultShader = null;
|
|||
|
|
|||
|
#region//公共接口
|
|||
|
public void SetData(SceneNodeCommpent node, RendererType type, SceneAssetsDiscriptFile script)
|
|||
|
{
|
|||
|
_listMatData.Clear();
|
|||
|
node.IsUseDefaultShader = false;
|
|||
|
_script = script;
|
|||
|
if (node != null && node.Trans == null)
|
|||
|
return;
|
|||
|
string folderPath = string.Empty;
|
|||
|
Trans = node.Trans;
|
|||
|
IsActive = node.IsActive;
|
|||
|
Material[] mats = null;
|
|||
|
Material tailMat = null;
|
|||
|
switch (type)
|
|||
|
{
|
|||
|
case RendererType.MeshRenderer:
|
|||
|
{
|
|||
|
RdType = RendererType.MeshRenderer;
|
|||
|
MeshFilter mf = node.Trans.GetComponent<MeshFilter>();
|
|||
|
if (mf == null)
|
|||
|
return;
|
|||
|
MeshRenderer mRd = node.Trans.GetComponent<MeshRenderer>();
|
|||
|
Mesh ms = mf.sharedMesh;
|
|||
|
string path = GetMeshPath(ms, ref folderPath);
|
|||
|
mats = mRd.sharedMaterials;
|
|||
|
Sort = GetMaxBoundSize(ms.bounds);
|
|||
|
SaveMesh(ms, path, folderPath);
|
|||
|
|
|||
|
//List<CombinData> list = null;
|
|||
|
//if (node.RenderType == RendererType.MeshRenderer && !node.IsSetCombinData)
|
|||
|
//{
|
|||
|
// if (node.MatProList.Count != 0)
|
|||
|
// {
|
|||
|
// CombinData data = new CombinData();
|
|||
|
// data.mesh = mf.sharedMesh;
|
|||
|
// data.trans = node.Trans;
|
|||
|
// data.combinName = string.Format("Comb_MatProperty_{0}_Mesh", node.MatProList[0]);
|
|||
|
// //设置合并后的网格名字
|
|||
|
// CombinName = data.combinName;
|
|||
|
// if (!_script.DicCombinData.ContainsKey(node.MatProList[0]))
|
|||
|
// {
|
|||
|
// list = new List<CombinData>();
|
|||
|
// list.Add(data);
|
|||
|
// _script.DicCombinData.Add(node.MatProList[0], list);
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// list = _script.DicCombinData[node.MatProList[0]];
|
|||
|
// list.Add(data);
|
|||
|
// }
|
|||
|
// SubMeshIndex = list.Count - 1;
|
|||
|
// node.SubMeshIndex = SubMeshIndex;
|
|||
|
// int index = _script.GetCombinMeshPathIndex(CombinName);
|
|||
|
// MeshIndexs = new int[] { index };
|
|||
|
// node.IsSetCombinData = true;
|
|||
|
// }
|
|||
|
//}
|
|||
|
}
|
|||
|
break;
|
|||
|
case RendererType.SkinMesh:
|
|||
|
{
|
|||
|
RdType = RendererType.SkinMesh;
|
|||
|
SkinnedMeshRenderer skinnedRender = node.Trans.GetComponent<SkinnedMeshRenderer>();
|
|||
|
mats = skinnedRender.sharedMaterials;
|
|||
|
string path = GetMeshPath(skinnedRender.sharedMesh, ref folderPath);
|
|||
|
int index = _script.GetMeshPathIndex(path);
|
|||
|
//MeshIndexs = new int[] { index };
|
|||
|
//MeshPaths = new string[] { path };
|
|||
|
Sort = GetMaxBoundSize(skinnedRender.sharedMesh.bounds);
|
|||
|
SaveMesh(skinnedRender.sharedMesh, path, folderPath);
|
|||
|
}
|
|||
|
break;
|
|||
|
case RendererType.ParticleSystemRenderer:
|
|||
|
{
|
|||
|
RdType = RendererType.ParticleSystemRenderer;
|
|||
|
ParticleSystemRenderer psr = node.Trans.GetComponent<ParticleSystemRenderer>();
|
|||
|
Mesh[] msArray = new Mesh[psr.meshCount];
|
|||
|
psr.GetMeshes(msArray);
|
|||
|
List<string> pathes = new List<string>();
|
|||
|
for (int i = 0; i < msArray.Length; i++)
|
|||
|
{
|
|||
|
string path = GetMeshPath(msArray[i], ref folderPath);
|
|||
|
pathes.Add(path);
|
|||
|
SaveMesh(msArray[i], path, folderPath);
|
|||
|
}
|
|||
|
List<int> list = new List<int>();
|
|||
|
for (int i = 0; i < pathes.Count; i++)
|
|||
|
{
|
|||
|
int index = _script.GetMeshPathIndex(pathes[i]);
|
|||
|
list.Add(index);
|
|||
|
}
|
|||
|
//MeshIndexs = list.ToArray();
|
|||
|
//MeshPaths = pathes.ToArray();
|
|||
|
mats = psr.sharedMaterials;
|
|||
|
Sort = -1;
|
|||
|
tailMat = psr.trailMaterial;
|
|||
|
}
|
|||
|
break;
|
|||
|
case RendererType.TrailRender:
|
|||
|
{
|
|||
|
RdType = RendererType.TrailRender;
|
|||
|
TrailRenderer tRd = node.Trans.GetComponent<TrailRenderer>();
|
|||
|
mats = tRd.sharedMaterials;
|
|||
|
Sort = GetMaxBoundSize(tRd.bounds);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
bool isParticle = type == RendererType.ParticleSystemRenderer ? true : false;
|
|||
|
for (int i = 0; mats != null && i < mats.Length; i++)
|
|||
|
{
|
|||
|
Material defaultMat = null;
|
|||
|
MatrialAssetData data = new MatrialAssetData();
|
|||
|
if (node.IsUseDefaultShader)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (mats[i]!= null && string.Equals(mats[i].shader.name, "Gonbest/FallBack/FBWithLightmap"))
|
|||
|
continue;
|
|||
|
if (isParticle)
|
|||
|
{
|
|||
|
//如果是粒子render
|
|||
|
//默认第二个材质球是拖尾材质球
|
|||
|
data.IsTrail = i == 1 ? true : false;
|
|||
|
}
|
|||
|
if (mats[i] == null || (!mats[i].shader.name.Contains("Ares") && !mats[i].shader.name.Contains("Gonbest")))
|
|||
|
{
|
|||
|
if (mats[i] != null)
|
|||
|
{
|
|||
|
node.IsUseDefaultShader = true;
|
|||
|
defaultMat = GetDefaultMat();
|
|||
|
UnityEngine.Debug.LogError(string.Format("重要事情说一遍,发现unityShader:{0}---目标节点是:{1}", mats[i].shader.name, node.Trans.name));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
int index = i;
|
|||
|
//for (int m = 0; m < mats.Length; m++)
|
|||
|
//{
|
|||
|
// if (string.Equals(mats[i].name, mats[m].name))
|
|||
|
// {
|
|||
|
// index = m;
|
|||
|
// break;
|
|||
|
// }
|
|||
|
//}
|
|||
|
if (isParticle)
|
|||
|
{
|
|||
|
data.SetMatrialAssetData(node, mats[i], defaultMat, _script, true, index);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
data.SetMatrialAssetData(node, mats[i], defaultMat, _script, false, index);
|
|||
|
}
|
|||
|
if (tailMat == null || mats[i] != tailMat)
|
|||
|
{
|
|||
|
if (type == RendererType.SkinMesh)
|
|||
|
{
|
|||
|
SkinnedMeshRenderer skinnedRender = node.Trans.GetComponent<SkinnedMeshRenderer>();
|
|||
|
int count = skinnedRender.sharedMesh.subMeshCount;
|
|||
|
if (count != 1 && count == mats.Length)
|
|||
|
{
|
|||
|
_listMatData.Add(data);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//去除重复
|
|||
|
bool isFind = false;
|
|||
|
for (int m = 0; m < _listMatData.Count; m++)
|
|||
|
{
|
|||
|
if (_listMatData[m].Index == data.Index)
|
|||
|
{
|
|||
|
isFind = true;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!isFind)
|
|||
|
{
|
|||
|
_listMatData.Add(data);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//去除重复
|
|||
|
bool isFind = false;
|
|||
|
for (int m = 0; m < _listMatData.Count; m++)
|
|||
|
{
|
|||
|
if (_listMatData[m].Index == data.Index)
|
|||
|
{
|
|||
|
isFind = true;
|
|||
|
}
|
|||
|
}
|
|||
|
if (!isFind)
|
|||
|
{
|
|||
|
_listMatData.Add(data);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_listMatData.Add(data);
|
|||
|
}
|
|||
|
if (isParticle)
|
|||
|
{
|
|||
|
node.SetSaveSubMatTexIndex(i);
|
|||
|
}
|
|||
|
node.IsSaveTexture = true;
|
|||
|
}
|
|||
|
if (node.IsSaveTexture)
|
|||
|
{
|
|||
|
MatsData = new MatrialAssetData[_listMatData.Count];
|
|||
|
for (int i = 0; i < _listMatData.Count; i++)
|
|||
|
{
|
|||
|
MatsData[i] = _listMatData[i];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private Material GetDefaultMat()
|
|||
|
{
|
|||
|
if (_defaultMat == null)
|
|||
|
{
|
|||
|
Shader sh = Shader.Find("Gonbest/FallBack/FBWithMainTex");
|
|||
|
Material mat = new Material(sh);
|
|||
|
_defaultShader = sh;
|
|||
|
_defaultMat = mat;
|
|||
|
}
|
|||
|
return _defaultMat;
|
|||
|
}
|
|||
|
|
|||
|
private string GetMeshPath(Mesh ms, ref string folderPath)
|
|||
|
{
|
|||
|
if (ms == null)
|
|||
|
return string.Empty;
|
|||
|
string path = string.Empty;
|
|||
|
string replaceStr = string.Empty;
|
|||
|
#if UNITY_EDITOR
|
|||
|
path = UnityEditor.AssetDatabase.GetAssetPath(ms);
|
|||
|
#endif
|
|||
|
string[] strs = path.Split('.');
|
|||
|
if (strs != null && strs.Length != 0)
|
|||
|
{
|
|||
|
path = strs[0];
|
|||
|
}
|
|||
|
strs = path.Split('/');
|
|||
|
replaceStr = strs[strs.Length - 1];
|
|||
|
replaceStr = "/" + replaceStr;
|
|||
|
path = path.Replace(replaceStr, "");
|
|||
|
string newName = ms.name;
|
|||
|
if (string.Equals(newName, SceneManager.GetActiveScene().name))
|
|||
|
{
|
|||
|
newName = string.Format("{0}_{1}", newName, "mesh");
|
|||
|
}
|
|||
|
path = path + "/" + newName;
|
|||
|
path = path.Replace("Assets/GameAssets/RawResources/scene/", "");
|
|||
|
path = string.Format("SplitMesh/{0}", path);
|
|||
|
folderPath = path.Replace(string.Format("/{0}", newName), "");
|
|||
|
return path;
|
|||
|
}
|
|||
|
//获取bounds最大的size
|
|||
|
private float GetMaxBoundSize(Bounds b)
|
|||
|
{
|
|||
|
float size = -1;
|
|||
|
size = b.size.x > b.size.y ? b.size.x : b.size.y;
|
|||
|
size = size > b.size.z ? size : b.size.z;
|
|||
|
return size;
|
|||
|
}
|
|||
|
|
|||
|
//保存mesh
|
|||
|
private void SaveMesh(Mesh ms, string path, string folderPath)
|
|||
|
{
|
|||
|
if (ms == null)
|
|||
|
return;
|
|||
|
Mesh nMs = UnityEngine.Object.Instantiate(ms);
|
|||
|
string meshfolderPath = GetFolderPath(folderPath);
|
|||
|
if (!Directory.Exists(meshfolderPath))
|
|||
|
Directory.CreateDirectory(meshfolderPath);
|
|||
|
string savePath = GetMeshAssetPath(path);
|
|||
|
#if UNITY_EDITOR
|
|||
|
//UnityEditor.AssetDatabase.CreateAsset(nMs, savePath);
|
|||
|
#endif
|
|||
|
}
|
|||
|
//获取mesh的路径
|
|||
|
private string GetFolderPath( string path )
|
|||
|
{
|
|||
|
var folderPath = string.Format("GameAssets/Resources/{0}", path);
|
|||
|
folderPath = Application.dataPath + "/" + folderPath;
|
|||
|
return folderPath;
|
|||
|
}
|
|||
|
//获取mesh资源路劲
|
|||
|
public string GetMeshAssetPath(string path)
|
|||
|
{
|
|||
|
string assetPath = "Assets/GameAssets/Resources/";
|
|||
|
assetPath = assetPath + path + ".asset";
|
|||
|
return assetPath;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
public Bounds GetBound()
|
|||
|
{
|
|||
|
return NodeBounds;
|
|||
|
}
|
|||
|
|
|||
|
public void SetBound(Bounds b)
|
|||
|
{
|
|||
|
NodeBounds = b;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//Render类型
|
|||
|
public enum RendererType
|
|||
|
{
|
|||
|
None,
|
|||
|
//Mesh渲染
|
|||
|
MeshRenderer,
|
|||
|
//skin
|
|||
|
SkinMesh,
|
|||
|
//粒子渲染
|
|||
|
ParticleSystemRenderer,
|
|||
|
//拖尾粒子
|
|||
|
TrailRender,
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|