using System.Collections; using System.Collections.Generic; using DG.Tweening; using Ichni; using TMPro; using UnityEngine; using UnityEngine.InputSystem; [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] public class SimpleGridController : MonoBehaviour { public Camera targetCamera => EditorManager.instance.cameraManager.currentCamera; [Header("Settings")] public Material gridMaterial; public GameObject textPrefab; // 预制体需要挂载 TextMeshPro public Transform textParent; [Header("Grid Logic")] public bool showCoordinates = true; public float baseGridSize = 1.0f; [Range(10f, 1000f)] public float drawDistance = 100f; // --- 内部状态 --- private MeshRenderer _renderer; private Material _instancedMat; private float _currentSpacing = 1.0f; void Start() { InitMesh(); _renderer = GetComponent(); if (gridMaterial) { _instancedMat = new Material(gridMaterial); _renderer.material = _instancedMat; } } public Color MainColor = new Color(0.8f, 0.8f, 0.8f, 0.5f); public Color SubColor = new Color(0.5f, 0.5f, 0.5f, 0.5f); void Update() { if (Mouse.current.middleButton.wasPressedThisFrame) { StartCoroutine(Pressing()); } } GameObject coordTextObj = null; [System.Obsolete] IEnumerator Pressing() { if (coordTextObj != null) { coordTextObj.transform.DOComplete(); } TextMeshPro coordText = null; float targetScale = 1f; Tweener scaleTween = null; while (Mouse.current.middleButton.isPressed) { Ray ray = targetCamera.ScreenPointToRay(Mouse.current.position.ReadValue()); Plane plane = new Plane(Vector3.up, Vector3.zero); if (plane.Raycast(ray, out float enter)) { Vector3 hitPoint = ray.GetPoint(enter); Vector2 xz = new Vector2(hitPoint.x, hitPoint.z); // 创建或复用文字对象 if (coordTextObj == null) { coordTextObj = Instantiate(textPrefab, textParent); coordText = coordTextObj.GetComponent(); coordTextObj.transform.localScale = Vector3.zero; targetScale = Mathf.Clamp(Vector3.Distance(targetCamera.transform.position, hitPoint) * 0.05f, 0.1f, 1000f); scaleTween = coordTextObj.transform.DOScale(Vector3.one * targetScale, 0.2f).SetEase(Ease.OutBack); } else { // 动态融合:用DOTween的ChangeEndValue实时调整目标scale targetScale = Mathf.Clamp(Vector3.Distance(targetCamera.transform.position, hitPoint) * 0.05f, 0.1f, 1000f); if (scaleTween != null && scaleTween.IsActive()) { scaleTween.ChangeEndValue(Vector3.one * targetScale, true); } else { coordTextObj.transform.localScale = Vector3.one * targetScale; } } coordTextObj.transform.position = hitPoint + Vector3.up * targetScale; coordTextObj.transform.rotation = Quaternion.LookRotation(coordTextObj.transform.position - targetCamera.transform.position, Vector3.up); if (coordText == null) coordText = coordTextObj.GetComponent(); coordText.text = $"({xz.x:F2}, {xz.y:F2})\n({Mathf.Round(xz.x):F2}, {Mathf.Round(xz.y):F2})"; coordText.fontSize = 8; coordText.enableWordWrapping = false; coordText.color = Color.yellow; } yield return null; } // 释放文字对象 if (coordTextObj != null) { coordTextObj.transform.DOScale(0, 0.3f).SetEase(Ease.OutExpo).OnComplete(() => { Destroy(coordTextObj); coordTextObj = null; }); } } void LateUpdate() { if (!targetCamera) return; Vector3 camPos = targetCamera.transform.position; // 1. 网格跟随相机 (无限大地板) transform.position = new Vector3(camPos.x, 0, camPos.z); // 2. 计算层级 (1m / 10m / 100m) float absH = Mathf.Abs(camPos.y); float step = baseGridSize; Color Mcolor = MainColor; Color Scolor = SubColor; // 简单的自适应逻辑:根据高度决定网格密度 if (absH > 150f)//>150 { step *= 10f; Scolor = Lerp(SubColor, Color.clear, (absH - 150f) / 150f); } else if (absH > 15f)//15-150 { step *= 10f; Mcolor = Lerp(MainColor, SubColor, (absH - 15f) / (150f - 15f)); Scolor = Lerp(SubColor, Color.clear, (absH - 15f) / (150f - 15f)); } else//0-15 { Mcolor = Lerp(MainColor, SubColor, absH / 15f); Scolor = Lerp(SubColor, Color.clear, absH / 15f); } _currentSpacing = step; // 3. 更新 Shader if (_instancedMat) { _instancedMat.SetColor("_MainColor", Scolor); _instancedMat.SetColor("_AxisColor", Mcolor); _instancedMat.SetFloat("_GridSpacing", _currentSpacing); _instancedMat.SetFloat("_FadeDist", drawDistance); } } private Color Lerp(Color a, Color b, float t) { return new Color( Mathf.Lerp(a.r, b.r, t), Mathf.Lerp(a.g, b.g, t), Mathf.Lerp(a.b, b.b, t), Mathf.Lerp(a.a, b.a, t) ); } private void InitMesh() { MeshFilter mf = GetComponent(); Mesh mesh = new Mesh(); // 覆盖视野的大 Quad float size = 2000f; Vector3[] vertices = new Vector3[4] { new Vector3(-size, 0, -size), new Vector3(size, 0, -size), new Vector3(-size, 0, size), new Vector3(size, 0, size) }; mesh.vertices = vertices; mesh.triangles = new int[6] { 0, 2, 1, 2, 3, 1 }; mesh.uv = new Vector2[4] { Vector2.zero, Vector2.right, Vector2.up, Vector2.one }; mesh.RecalculateBounds(); mf.mesh = mesh; } }