Files

381 lines
14 KiB
C#
Raw Permalink Normal View History

2025-01-25 04:38:09 +08:00
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,
}
}