218 lines
9.2 KiB
C#
218 lines
9.2 KiB
C#
|
#if UNITY_EDITOR && !FUNCELL_LAUNCHER
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using UnityEditor;
|
|||
|
using UnityEditor.SceneManagement;
|
|||
|
using UnityEngine.SceneManagement;
|
|||
|
using UnityEngine;
|
|||
|
using System;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace Thousandto.Launcher.ExternalLibs
|
|||
|
{
|
|||
|
public class GrassCombine
|
|||
|
{
|
|||
|
//private const string ScenePath = "GameAssets/ExportResources/Scene";
|
|||
|
//private const string AssetPath = "Assets/GameAssets/ExportResources/scene/{0}/";
|
|||
|
//private const string FilePath = "GameAssets/ExportResources/scene/{0}";
|
|||
|
|
|||
|
#region//const
|
|||
|
//子节点数量的警告值
|
|||
|
public const int CN_MAX_CHILD_COUNT_WANNING = 100;
|
|||
|
//-----------------------------//
|
|||
|
//总的顶点数量警告阀值
|
|||
|
public const int CN_MAX_VERTEX_COUNT_WANNING = 4096;
|
|||
|
#endregion
|
|||
|
|
|||
|
public static void CombineScene(string sceneName, string sPath, string aPath, string fPath)
|
|||
|
{
|
|||
|
DirectoryInfo directory = new DirectoryInfo(Application.dataPath + "/" + sPath);
|
|||
|
if (directory == null)
|
|||
|
return;
|
|||
|
string sceneFullPath = string.Format(directory.FullName + "\\{0}.unity", sceneName);
|
|||
|
string assetPath = string.Format(aPath, sceneName);
|
|||
|
string filePath = string.Format(fPath, sceneName);
|
|||
|
filePath = Application.dataPath + "/" + filePath;
|
|||
|
Scene scene = EditorSceneManager.OpenScene(sceneFullPath, OpenSceneMode.Single);
|
|||
|
GameObject root = GameObject.Find("SceneRoot");
|
|||
|
if (root == null)
|
|||
|
return;
|
|||
|
|
|||
|
Transform rootTrans = root.transform;
|
|||
|
Transform grass = null;
|
|||
|
for(int i = 0;i < rootTrans.childCount;i++)
|
|||
|
{
|
|||
|
var ch = rootTrans.GetChild(i);
|
|||
|
if(ch.name.ToLower().Trim() == "grass")
|
|||
|
{
|
|||
|
grass = ch;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (grass == null)
|
|||
|
return;
|
|||
|
if (!Directory.Exists(filePath))
|
|||
|
Directory.CreateDirectory(filePath);
|
|||
|
for (int m = 0; m < grass.childCount; m++)
|
|||
|
{
|
|||
|
Transform child = grass.GetChild(m);
|
|||
|
if (child == null)
|
|||
|
continue;
|
|||
|
Mesh ms = Combine(child, assetPath, filePath);
|
|||
|
}
|
|||
|
//string savePath = Path.Combine(assetPath, "Mesh_ScriptTable_Object_" + name + ".asset");
|
|||
|
EditorSceneManager.SaveScene(scene);
|
|||
|
}
|
|||
|
|
|||
|
private static Mesh Combine(Transform region, string assetpath, string filePath)
|
|||
|
{
|
|||
|
var info = MeshCombine.CreateMeshCombineInfo(region);
|
|||
|
if (info != null)
|
|||
|
{
|
|||
|
List<Vector3> vList = new List<Vector3>();
|
|||
|
List<ChildMeshDataScript> scriptList = new List<ChildMeshDataScript>();
|
|||
|
GrassRelationScript relationScript = Thousandto.Core.Base.UnityUtils.RequireComponent<GrassRelationScript>(region.gameObject);
|
|||
|
for (int i = 0; i < region.childCount; i++)
|
|||
|
{
|
|||
|
var tran = region.GetChild(i);
|
|||
|
if (tran == null)
|
|||
|
continue;
|
|||
|
MeshFilter childMf = tran.GetComponent<MeshFilter>();
|
|||
|
MeshRenderer rd = tran.GetComponent<MeshRenderer>();
|
|||
|
if (childMf == null || rd == null)
|
|||
|
{
|
|||
|
UnityEngine.Debug.LogError("Grass已经合并过了");
|
|||
|
return null;
|
|||
|
}
|
|||
|
int starIndex = vList.Count;
|
|||
|
ChildMeshDataScript script = Thousandto.Core.Base.UnityUtils.RequireComponent<ChildMeshDataScript>(tran.gameObject);
|
|||
|
if (script == null)
|
|||
|
continue;
|
|||
|
script.ChildMeshInfo = new RuntimeChildMesh(tran, rd.lightmapIndex, rd.lightmapScaleOffset, childMf.sharedMesh.colors);
|
|||
|
script.ChildMeshInfo.NewVertices = new Vector3[childMf.sharedMesh.vertices.Length];
|
|||
|
//计算顶点
|
|||
|
for (int m = 0; m < childMf.sharedMesh.vertices.Length; m++)
|
|||
|
{
|
|||
|
//先把顶点转换为世界坐标
|
|||
|
var wp = tran.localToWorldMatrix.MultiplyPoint3x4(childMf.sharedMesh.vertices[m]);
|
|||
|
//再把顶点转换为本地坐标
|
|||
|
var p = region.worldToLocalMatrix.MultiplyPoint3x4(wp);
|
|||
|
vList.Add(p);
|
|||
|
script.ChildMeshInfo.NewVertices[m] = p;
|
|||
|
script.ChildMeshInfo.StartIndex = starIndex;
|
|||
|
}
|
|||
|
scriptList.Add(script);
|
|||
|
AddColliderBox(tran.gameObject);
|
|||
|
SetMeshRenderer(rd);
|
|||
|
info.AddChild(tran);
|
|||
|
}
|
|||
|
if (scriptList.Count == CN_MAX_CHILD_COUNT_WANNING + 1)
|
|||
|
{
|
|||
|
Debug.LogError("RuntimeMesh Has Too Much Child Count! More then " + CN_MAX_CHILD_COUNT_WANNING);
|
|||
|
}
|
|||
|
relationScript.AddRelationScript(scriptList);
|
|||
|
info.Build();
|
|||
|
|
|||
|
var mf = Thousandto.Core.Base.UnityUtils.RequireComponent<MeshFilter>(region.gameObject);
|
|||
|
var render = Thousandto.Core.Base.UnityUtils.RequireComponent<MeshRenderer>(region.gameObject);
|
|||
|
render.sharedMaterial = info.Material;
|
|||
|
render.lightmapIndex = info.LightmapIndex;
|
|||
|
render.lightmapScaleOffset = new Vector4(1, 1, 0, 0);
|
|||
|
string result = SaveMeshForAsset(info.NewMesh, region.name, assetpath, filePath);
|
|||
|
mf.sharedMesh = LoadCombineAsset(result);
|
|||
|
relationScript.InitCombineInfo();
|
|||
|
return info.NewMesh;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogError("MeshCombineScript: not found renderer child. ");
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
private static string SaveMeshForObj(string name, Vector3[] tVertices, Vector2[] tUV, int[] tPolys, string path)
|
|||
|
{
|
|||
|
if (!Directory.Exists(path))
|
|||
|
Directory.CreateDirectory(path);
|
|||
|
string savePath = Path.Combine(path, name + ".obj");
|
|||
|
StreamWriter sw = new StreamWriter(savePath);
|
|||
|
try
|
|||
|
{
|
|||
|
sw.WriteLine("# T4M File");
|
|||
|
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
|
|||
|
for (int i = 0; i < tVertices.Length; i++)
|
|||
|
{
|
|||
|
//UpdateProgress();
|
|||
|
StringBuilder sb = new StringBuilder("v ", tVertices.Length);
|
|||
|
sb.Append(tVertices[i].x.ToString()).Append(" ").
|
|||
|
Append(tVertices[i].y.ToString()).Append(" ").
|
|||
|
Append(tVertices[i].z.ToString());
|
|||
|
sw.WriteLine(sb);
|
|||
|
}
|
|||
|
|
|||
|
for (int i = 0; i < tUV.Length; i++)
|
|||
|
{
|
|||
|
//UpdateProgress();
|
|||
|
StringBuilder sb = new StringBuilder("vt ", tUV.Length);
|
|||
|
sb.Append(tUV[i].x.ToString()).Append(" ").
|
|||
|
Append(tUV[i].y.ToString());
|
|||
|
sw.WriteLine(sb);
|
|||
|
}
|
|||
|
|
|||
|
for (int i = 0; i < tPolys.Length; i += 3)
|
|||
|
{
|
|||
|
//UpdateProgress();
|
|||
|
StringBuilder sb = new StringBuilder("f ", tPolys.Length);
|
|||
|
sb.Append(tPolys[i] + 1).Append("/").Append(tPolys[i] + 1).Append(" ").
|
|||
|
Append(tPolys[i + 1] + 1).Append("/").Append(tPolys[i + 1] + 1).Append(" ").
|
|||
|
Append(tPolys[i + 2] + 1).Append("/").Append(tPolys[i + 2] + 1);
|
|||
|
|
|||
|
sw.WriteLine(sb);
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception err)
|
|||
|
{
|
|||
|
Debug.Log("Error saving file: " + err.Message);
|
|||
|
}
|
|||
|
sw.Close();
|
|||
|
AssetDatabase.SaveAssets();
|
|||
|
|
|||
|
return savePath;
|
|||
|
}
|
|||
|
|
|||
|
private static string SaveMeshForAsset(Mesh ms, string name, string assetpath, string filepath)
|
|||
|
{
|
|||
|
if (ms == null)
|
|||
|
return string.Empty;
|
|||
|
string savePath = Path.Combine(assetpath, name + ".asset");
|
|||
|
string path = assetpath + name;
|
|||
|
if (File.Exists(path))
|
|||
|
File.Delete(path);
|
|||
|
AssetDatabase.CreateAsset(ms, savePath);
|
|||
|
return savePath;
|
|||
|
}
|
|||
|
|
|||
|
private static Mesh LoadCombineAsset(string path)
|
|||
|
{
|
|||
|
Mesh ms = AssetDatabase.LoadAssetAtPath(path, typeof(Mesh)) as Mesh;
|
|||
|
return ms;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private static void AddColliderBox(GameObject go)
|
|||
|
{
|
|||
|
if (go == null)
|
|||
|
return;
|
|||
|
var collider = Thousandto.Core.Base.UnityUtils.RequireComponent<BoxCollider>(go);
|
|||
|
collider.size = new Vector3(collider.size.x, collider.size.y, 0.2f);
|
|||
|
collider.isTrigger = true;
|
|||
|
}
|
|||
|
private static void SetMeshRenderer(MeshRenderer render)
|
|||
|
{
|
|||
|
if (render != null) render.enabled = false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|