Files
ichni_Creator_Studio/Assets/Scripts/Gird/SimpleGridController.cs
2026-02-13 17:40:50 +08:00

197 lines
6.3 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 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<MeshRenderer>();
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;
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<TextMeshPro>();
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<TextMeshPro>();
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<MeshFilter>();
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;
}
}