Files
Main/Assets/Editor/SplitTerrain/Uitls/Utils.cs
2025-01-25 04:38:09 +08:00

238 lines
8.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}
}