Files
Main/Assets/Editor/SplitTerrain/Uitls/Utils.cs

238 lines
8.2 KiB
C#
Raw Normal View History

2025-01-25 04:38:09 +08:00
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
{
/// <summary>
/// 是否相交
/// </summary>
/// <param name="thing"></param>
/// <param name="rect"></param>
/// <param name="centerInRect">中心点是否落在Rect中是的话说明相交面积是最大的</param>
/// <returns></returns>
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<MeshFilter>();
if (sourceMesh == null)
return;
var mesh = target.GetComponentInChildren<MeshFilter>();
sourceMesh.sharedMesh = mesh.sharedMesh;
}
public static void AddToDict<T1, T2>(Dictionary<T1, List<T2>> source, T1 key, T2 data) where T1 : new() where T2 : new()
{
if (source.ContainsKey(key))
source[key].Add(data);
else
{
List<T2> list = new List<T2>();
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);
}
}
}
}