using Thousandto.Core.Asset; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using UnityEditor; using UnityEngine; namespace Thousandto.Editor.Test { public static class Utils { /// /// 是否相交 /// /// /// /// 中心点是否落在Rect中,是的话,说明相交面积是最大的 /// public static bool IsIntersect(Thing thing, Rect rect, out bool centerInRect) { var centerPos = GetGameObjectCenter(thing); centerInRect = IsPointInRect(centerPos, rect); return centerInRect; //return IsPointInRect(pos1, rect) || // IsPointInRect(pos2, rect) || // IsPointInRect(pos3, rect) || // IsPointInRect(pos4, rect) || // IsPointInRect(pos5, rect) || // IsPointInRect(pos6, rect) || // IsPointInRect(pos7, rect) || // IsPointInRect(pos8, rect); } public static int CalcIndex(Vector3 worldPos, int blockSize) { int posX = ScaleTo64n(worldPos.x, blockSize); int posZ = ScaleTo64n(worldPos.z, blockSize); int indexX = posX / blockSize; int indexY = posZ / blockSize; return TerrainConfigLoader.CalcIndex(indexX, indexY); } public static int CalcIndex(Vector2 worldPos, int blockSize) { int posX = ScaleTo64n(worldPos.x, blockSize); int posZ = ScaleTo64n(worldPos.y, blockSize); int indexX = posX / blockSize; int indexY = posZ / blockSize; return TerrainConfigLoader.CalcIndex(indexX, indexY); } public static int ScaleTo64n(float pos, int blockSize) { if (blockSize <= 0) return (int)pos; int temp = 1; int value = 0; while (true) { value = temp * blockSize; if (value > pos) { value = (temp - 1) * blockSize; break; } temp++; } return value; } public static Vector2 GetGameObjectCenter(Thing thing) { var bounds = thing.Bounds; var transform = thing.Go.transform; bounds = new Bounds(bounds.center, bounds.size); bounds.min = ScaleVector3(bounds.min, transform.lossyScale); bounds.max = ScaleVector3(bounds.max, transform.lossyScale); Vector3 pos1 = bounds.min; Vector3 pos2 = bounds.min + new Vector3(bounds.size.x, 0, 0); Vector3 pos3 = bounds.min + new Vector3(0, bounds.size.y, 0); Vector3 pos4 = bounds.min + new Vector3(0, 0, bounds.size.z); Vector3 pos5 = bounds.max; Vector3 pos6 = bounds.max - new Vector3(bounds.size.x, 0, 0); Vector3 pos7 = bounds.max - new Vector3(0, bounds.size.y, 0); Vector3 pos8 = bounds.max - new Vector3(0, 0, bounds.size.z); if(bounds.size != Vector3.zero) { pos1 = transform.rotation * pos1 + transform.position; pos2 = transform.rotation * pos2 + transform.position; pos3 = transform.rotation * pos3 + transform.position; pos4 = transform.rotation * pos4 + transform.position; pos5 = transform.rotation * pos5 + transform.position; pos6 = transform.rotation * pos6 + transform.position; pos7 = transform.rotation * pos7 + transform.position; pos8 = transform.rotation * pos8 + transform.position; } //顶部4个点对角一半就是中心点 var centerPos = (pos3 + pos5) / 2; return new Vector2(centerPos.x, centerPos.z); } public static Vector3 ScaleVector3(Vector3 source, Vector3 scale) { source.x *= scale.x; source.y *= scale.y; source.z *= scale.z; return source; } //是否点落在指定Rect范围内 public static bool IsPointInRect(Vector3 pos, Rect rect) { if (pos.x >= rect.x && pos.x <= rect.x + rect.width && pos.z >= rect.y && pos.z <= rect.y + rect.height) return true; //if (rect.Contains(new Vector2(pos.x, pos.z))) // return true; return false; } public static string GetGameObjectHierarchyPath(GameObject go) { Transform trans = go.transform; Transform parent = trans.parent; StringBuilder sb = new StringBuilder(); sb.Append(trans.name); while (parent != null) { sb.Insert(0, "/"); sb.Insert(0, parent.name); parent = parent.parent; } return sb.ToString(); } //计算生成的mesh在整个场景范围中的索引 public static int CalcTerrainMeshIndex(string savedMeshPath, int blockSize) { MyTerrainData td = MyTerrainData.CreateTerrainDataFromFileName(savedMeshPath); return CalcTerrainMeshIndex(td, blockSize); } public static void CallExe(string exeFile, string args) { Process p = new Process(); var start = p.StartInfo; start.Arguments = args; start.FileName = exeFile; start.CreateNoWindow = false; start.ErrorDialog = true; start.UseShellExecute = true; start.RedirectStandardInput = false; start.RedirectStandardOutput = false; start.RedirectStandardError = false; p.Start(); p.WaitForExit(); } //同步prefab public static void SyncPrefabInEditor(GameObject[] gos) { AssetDatabase.StartAssetEditing(); for (int i = 0; i < gos.Length; ++i) { var parent = PrefabUtility.GetPrefabParent(gos[i]); if (PrefabUtility.GetPrefabType(parent) == PrefabType.Prefab && PrefabUtility.GetPrefabType(gos[i]) == PrefabType.PrefabInstance) { PrefabUtility.ReplacePrefab(gos[i], parent, ReplacePrefabOptions.ConnectToPrefab); } } AssetDatabase.StopAssetEditing(); } //计算生成的mesh在整个场景范围中的索引 public static int CalcTerrainMeshIndex(MyTerrainData td, int blockSize) { Rect rect = td.GetRectSize(); var centerPos = (rect.min + rect.max) / 2; return CalcIndex(new Vector3(centerPos.x, 0, centerPos.y), blockSize); } public static void CopyTransProperty(Transform trans, Transform target) { trans.position = target.position; trans.rotation = target.rotation; trans.localScale = target.lossyScale; } public static void CopyMesh(Transform trans, Transform target) { return; var sourceMesh = trans.GetComponentInChildren(); if (sourceMesh == null) return; var mesh = target.GetComponentInChildren(); sourceMesh.sharedMesh = mesh.sharedMesh; } public static void AddToDict(Dictionary> source, T1 key, T2 data) where T1 : new() where T2 : new() { if (source.ContainsKey(key)) source[key].Add(data); else { List list = new List(); list.Add(data); source.Add(key, list); } } public static void ShowErrorMsgBox(string title, string msg) { if (EditorUtility.DisplayDialog(title, msg, "ok")) { UnityEngine.Debug.LogError(title + " -> " + msg); } } } }