Revert "我不理解,这check那check就是出不来"

This reverts commit ba1824d5d6.
This commit is contained in:
SoulliesOfficial
2025-10-03 06:30:22 -04:00
parent ba1824d5d6
commit 2e3b2bd908
25 changed files with 181377 additions and 197816 deletions

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Lean.Pool;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
@@ -18,47 +19,28 @@ namespace Ichni.Editor
[Tooltip("指定网格所在的平面0 = XZ (y=0), 1 = XY (z=0), 2 = YZ (x=0)")]
public int gridPlane = 0;
[Tooltip("网格基础缩放值,单位 1")]
public float baseScale = 1f;
[Tooltip("网格基础缩放值,单位 1")] public float baseScale = 1f;
[Tooltip("调整缩放的影响因子,建议值 15")]
public float scaleMultiplier = 1f;
[Tooltip("调整缩放的影响因子,建议值 15")] public float scaleMultiplier = 1f;
[Tooltip("距离因子,用于计算对数缩放(例如距离大于该值时切换到下一级单位)")]
public float distanceFactor = 10f;
[Tooltip("位置文本更新频率(秒)")]
public float textUpdateFrequency = 0.1f;
[FormerlySerializedAs("showPositionText")]
public bool canShowPositionText;
public bool isShowingPositionText;
public Transform textContainer;
public GameObject positionTextPrefab;
// 内部缓存材质
private Material gridMaterial;
public Dictionary<GameObject, Vector3> positionTexts = new Dictionary<GameObject, Vector3>();
// 对象池相关
private Queue<GameObject> textPool = new Queue<GameObject>();
private const int POOL_SIZE = 50;
// 性能优化缓存
private float lastTextUpdateTime = 0f;
private Vector3 lastCameraPosition;
private float lastGridScale;
private Plane gridPlaneCache;
private Vector2 screenCenter;
public float logScale;
public float gridScale; // 1, 4, 16, 64...
[FormerlySerializedAs("showPositionText")] public bool canShowPositionText;
public bool isShowingPositionText;
public Transform textContainer;
public GameObject positionTextPrefab;
public Dictionary<GameObject, Vector3> positionTexts;
void Start()
{
InitializeTextPool();
positionTexts = new Dictionary<GameObject, Vector3>();
sceneCamera = EditorManager.instance.cameraManager.sceneCamera.sceneCamera;
// 实例化材质,避免修改共享材质
@@ -70,12 +52,6 @@ namespace Ichni.Editor
float screenWidth = Screen.width;
float lineWidth = lineWidthOf3840 * (screenWidth / 3840f);
gridMaterial.SetFloat("_LineWidth", lineWidth);
// 预计算屏幕中心
screenCenter = new Vector2(Screen.width / 2f, Screen.height / 2f);
// 预计算网格平面
UpdateGridPlaneCache();
}
void Update()
@@ -108,266 +84,84 @@ namespace Ichni.Editor
if (canShowPositionText && isShowingPositionText)
{
// 添加更新频率控制
bool shouldUpdate = Time.time - lastTextUpdateTime >= textUpdateFrequency ||
Vector3.Distance(sceneCamera.transform.position, lastCameraPosition) > gridScale * 0.5f ||
Mathf.Abs(gridScale - lastGridScale) > 0.1f;
GetPoints();
if (shouldUpdate)
foreach (KeyValuePair<GameObject, Vector3> positionText in positionTexts)
{
GetPoints();
lastTextUpdateTime = Time.time;
lastCameraPosition = sceneCamera.transform.position;
lastGridScale = gridScale;
}
else
{
// 只更新文本朝向(性能较轻)
UpdateTextOrientations();
}
}
else if (isShowingPositionText && !canShowPositionText)
{
ClearAllTexts();
isShowingPositionText = false;
}
}
#region
private void InitializeTextPool()
{
for (int i = 0; i < POOL_SIZE; i++)
{
GameObject textObj = Instantiate(positionTextPrefab, textContainer);
textObj.SetActive(false);
textPool.Enqueue(textObj);
}
}
private GameObject GetTextFromPool()
{
if (textPool.Count > 0)
{
GameObject textObj = textPool.Dequeue();
textObj.SetActive(true);
return textObj;
}
// 如果池子空了,动态创建一个(应该很少发生)
GameObject newTextObj = Instantiate(positionTextPrefab, textContainer);
return newTextObj;
}
private void ReturnTextToPool(GameObject textObj)
{
textObj.SetActive(false);
textPool.Enqueue(textObj);
}
private void UpdateTextOrientations()
{
foreach (var textObj in positionTexts.Keys)
{
if (textObj != null && textObj.activeInHierarchy)
{
Vector3 direction = sceneCamera.transform.position - textObj.transform.position;
textObj.transform.forward = -direction.normalized;
positionText.Key.transform.position = positionText.Value + new Vector3(gridScale / 6, 0, gridScale / 12);
float scaleFactor = gridScale * 1.5f;
positionText.Key.transform.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);
Vector3 direction = EditorManager.instance.cameraManager.currentCamera.transform.position - positionText.Key.transform.position;
positionText.Key.transform.forward = -direction.normalized;
}
}
}
private void ClearAllTexts()
{
foreach (var textObj in positionTexts.Keys)
{
if (textObj != null)
{
ReturnTextToPool(textObj);
}
}
positionTexts.Clear();
}
#endregion
#region
void GetPoints()
{
// 使用平面射线检测替代 Physics.Raycast性能更好
Ray sceneCameraRay = sceneCamera.ScreenPointToRay(screenCenter);
if (gridPlaneCache.Raycast(sceneCameraRay, out float enter))
Ray sceneCameraRay = sceneCamera.ScreenPointToRay(new Vector2(Screen.width / 2f, Screen.height / 2f));
if (Physics.Raycast(sceneCameraRay, out RaycastHit sceneCameraHit, float.MaxValue, LayerMask.GetMask("Grid")))
{
Vector3 point = sceneCameraRay.GetPoint(enter);
// 添加距离检查,太远就不显示文本
float distanceToCamera = Vector3.Distance(sceneCamera.transform.position, point);
if (distanceToCamera > 50f)
if (sceneCameraHit.collider.gameObject == gameObject)
{
ClearAllTexts();
return;
}
Vector3 point = sceneCameraHit.point;
float radius = gridScale * 16f;
float step = gridScale * 4f;
float radius = gridScale * 16f;
float step = gridScale * 4f;
// 计算可见区域边界
Vector2Int minMaxX = CalculateBounds(point.x, radius, step);
Vector2Int minMaxZ = CalculateBounds(point.z, radius, step);
float minX = point.x - radius;
float maxX = point.x + radius;
float minZ = point.z - radius;
float maxZ = point.z + radius;
// 使用 HashSet 来跟踪需要显示的位置(避免重复计算)
HashSet<Vector3> requiredPositions = new HashSet<Vector3>();
// 对于 X 与 Z 方向,根据网格间距取整,确保从整点开始
minX = Mathf.Floor(minX / step) * step;
maxX = Mathf.Ceil(maxX / step) * step;
minZ = Mathf.Floor(minZ / step) * step;
maxZ = Mathf.Ceil(maxZ / step) * step;
for (int x = minMaxX.x; x <= minMaxX.y; x++)
{
for (int z = minMaxZ.x; z <= minMaxZ.y; z++)
List<Vector3> newPositions = new List<Vector3>();
// 添加距离检测逻辑
bool withinDistance = Vector3.Distance(sceneCamera.transform.position, point) <= 50f;
for (float x = minX; x <= maxX; x += step)
{
Vector3 position = new Vector3(x * step, 0, z * step);
requiredPositions.Add(position);
for (float z = minZ; z <= maxZ; z += step)
{
Vector3 position = new Vector3(x, 0, z);
if (withinDistance && !positionTexts.ContainsValue(position))
{
GameObject posText = LeanPool.Spawn(positionTextPrefab);
posText.transform.position = position + new Vector3(gridScale / 8, 0, gridScale / 16);
posText.transform.forward = -transform.up;
posText.GetComponent<TMP_Text>().text = $"({Mathf.RoundToInt(position.x)}, {Mathf.RoundToInt(position.z)})";
posText.transform.SetParent(textContainer);
positionTexts.Add(posText, position);
}
newPositions.Add(new Vector3(x, 0, z));
}
}
List<GameObject> toRemove = new List<GameObject>();
// 清除不在新范围内的Text
foreach (KeyValuePair<GameObject, Vector3> positionText in positionTexts)
{
if (!newPositions.Contains(positionText.Value))
{
LeanPool.Despawn(positionText.Key);
toRemove.Add(positionText.Key);
}
}
foreach (GameObject text in toRemove)
{
positionTexts.Remove(text);
}
}
UpdateTextDisplay(requiredPositions);
}
}
// 辅助方法:计算边界(避免重复的数学运算)
private Vector2Int CalculateBounds(float center, float radius, float step)
{
int min = Mathf.FloorToInt((center - radius) / step);
int max = Mathf.CeilToInt((center + radius) / step);
return new Vector2Int(min, max);
}
// 更新网格平面缓存
private void UpdateGridPlaneCache()
{
gridPlaneCache = gridPlane switch
{
0 => new Plane(Vector3.up, transform.position), // XZ
1 => new Plane(Vector3.forward, transform.position), // XY
2 => new Plane(Vector3.right, transform.position), // YZ
_ => new Plane(Vector3.up, transform.position)
};
}
private void UpdateTextDisplay(HashSet<Vector3> requiredPositions)
{
// 第一步:移除不再需要的位置文本
List<GameObject> toRemove = new List<GameObject>();
foreach (var kvp in positionTexts)
{
if (!requiredPositions.Contains(kvp.Value))
{
toRemove.Add(kvp.Key);
}
}
foreach (GameObject textObj in toRemove)
{
positionTexts.Remove(textObj);
ReturnTextToPool(textObj);
}
// 第二步:添加新位置文本
foreach (Vector3 position in requiredPositions)
{
if (!ContainsPosition(position))
{
GameObject textObj = GetTextFromPool();
SetupTextObject(textObj, position);
positionTexts[textObj] = position;
}
}
}
private bool ContainsPosition(Vector3 position)
{
foreach (var pos in positionTexts.Values)
{
if (Vector3.Distance(pos, position) < 0.1f)
return true;
}
return false;
}
private void SetupTextObject(GameObject textObj, Vector3 position)
{
textObj.transform.position = position + new Vector3(gridScale / 6, 0, gridScale / 12);
float scaleFactor = gridScale * 1.5f;
textObj.transform.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);
// 设置文本内容
TMP_Text tmpText = textObj.GetComponent<TMP_Text>();
if (tmpText != null)
{
tmpText.text = $"({Mathf.RoundToInt(position.x)}, {Mathf.RoundToInt(position.z)})";
}
// 初始朝向
Vector3 direction = sceneCamera.transform.position - textObj.transform.position;
textObj.transform.forward = -direction.normalized;
}
#endregion
#region
public void ShowPositionText()
{
canShowPositionText = true;
isShowingPositionText = true;
lastTextUpdateTime = 0; // 强制下一次更新
}
public void HidePositionText()
{
canShowPositionText = false;
ClearAllTexts();
}
public void SetGridPlane(int planeIndex)
{
if (planeIndex >= 0 && planeIndex <= 2)
{
gridPlane = planeIndex;
gridMaterial.SetFloat("_Plane", gridPlane);
UpdateGridPlaneCache();
}
}
#endregion
void OnDestroy()
{
// 清理资源
if (gridMaterial != null)
{
if (Application.isEditor)
DestroyImmediate(gridMaterial);
else
Destroy(gridMaterial);
}
ClearAllTexts();
// 清理对象池
foreach (var textObj in textPool)
{
if (textObj != null)
{
if (Application.isEditor)
DestroyImmediate(textObj);
else
Destroy(textObj);
}
}
textPool.Clear();
}
}
}