Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
142 lines
4.5 KiB
C#
142 lines
4.5 KiB
C#
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
public class MouseWorldPositionWindow : EditorWindow
|
|
{
|
|
private enum PlaneMode { XY, XZ, YZ, CameraFacing }
|
|
|
|
// Множители для быстрого доступа: multipliers[d] = 10^d
|
|
private static readonly float[] Multipliers = { 1f, 10f, 100f, 1000f, 10000f, 100000f, 1000000f };
|
|
|
|
private PlaneMode planeMode = PlaneMode.XZ;
|
|
private float planeOffset;
|
|
private bool lockToSceneView = true;
|
|
private int decimals = 3;
|
|
|
|
private Vector3 lastWorld;
|
|
private Vector3 displayWorld;
|
|
private bool hasPoint;
|
|
|
|
[MenuItem("Tools/Mouse World Position")]
|
|
public static void Open()
|
|
{
|
|
GetWindow<MouseWorldPositionWindow>("Mouse World Pos");
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
SceneView.duringSceneGui += OnSceneGUI;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
SceneView.duringSceneGui -= OnSceneGUI;
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
EditorGUILayout.LabelField("Source", EditorStyles.boldLabel);
|
|
lockToSceneView = EditorGUILayout.ToggleLeft("Use last active Scene View", lockToSceneView);
|
|
|
|
EditorGUILayout.Space(6);
|
|
EditorGUILayout.LabelField("Projection", EditorStyles.boldLabel);
|
|
|
|
planeMode = (PlaneMode)EditorGUILayout.EnumPopup("Плоскость", planeMode);
|
|
if (planeMode != PlaneMode.CameraFacing)
|
|
planeOffset = EditorGUILayout.FloatField("Смещение плоскости", planeOffset);
|
|
|
|
decimals = EditorGUILayout.IntSlider("Decimals", decimals, 0, 6);
|
|
|
|
EditorGUILayout.Space(10);
|
|
EditorGUILayout.LabelField("Result", EditorStyles.boldLabel);
|
|
|
|
using (new EditorGUI.DisabledScope(true))
|
|
{
|
|
EditorGUILayout.Toggle("Has Point", hasPoint);
|
|
EditorGUILayout.Vector3Field("World", displayWorld);
|
|
}
|
|
|
|
using (new EditorGUI.DisabledScope(!hasPoint))
|
|
{
|
|
if (GUILayout.Button("Copy (x,y,z)"))
|
|
{
|
|
string f = "F" + decimals;
|
|
EditorGUIUtility.systemCopyBuffer = $"{displayWorld.x.ToString(f)}, {displayWorld.y.ToString(f)}, {displayWorld.z.ToString(f)}";
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnSceneGUI(SceneView sv)
|
|
{
|
|
if (!lockToSceneView && sv != SceneView.lastActiveSceneView) return;
|
|
|
|
Event e = Event.current;
|
|
if (e == null) return;
|
|
|
|
// Берём позицию мыши только когда курсор над SceneView
|
|
if (e.type != EventType.MouseMove && e.type != EventType.MouseDrag && e.type != EventType.Repaint)
|
|
return;
|
|
|
|
Ray ray = HandleUtility.GUIPointToWorldRay(e.mousePosition);
|
|
|
|
hasPoint = TryGetPoint(ray, sv.camera, out lastWorld);
|
|
|
|
// Вычисляем displayWorld один раз при изменении позиции
|
|
if (hasPoint)
|
|
{
|
|
float mult = Multipliers[decimals];
|
|
displayWorld = new Vector3(
|
|
Mathf.Ceil(lastWorld.x * mult) / mult,
|
|
Mathf.Ceil(lastWorld.y * mult) / mult,
|
|
Mathf.Ceil(lastWorld.z * mult) / mult
|
|
);
|
|
}
|
|
else
|
|
{
|
|
displayWorld = default;
|
|
}
|
|
|
|
Repaint();
|
|
}
|
|
|
|
private bool TryGetPoint(Ray ray, Camera cam, out Vector3 world)
|
|
{
|
|
// Для CameraFacing: плоскость, перпендикулярная камере, проходящая через origin камеры + (forward * planeOffset)
|
|
Plane plane;
|
|
|
|
switch (planeMode)
|
|
{
|
|
case PlaneMode.XY:
|
|
plane = new Plane(Vector3.forward, new Vector3(0f, 0f, planeOffset)); // Z = offset
|
|
break;
|
|
|
|
case PlaneMode.XZ:
|
|
plane = new Plane(Vector3.up, new Vector3(0f, planeOffset, 0f)); // Y = offset
|
|
break;
|
|
|
|
case PlaneMode.YZ:
|
|
plane = new Plane(Vector3.right, new Vector3(planeOffset, 0f, 0f)); // X = offset
|
|
break;
|
|
|
|
case PlaneMode.CameraFacing:
|
|
default:
|
|
Vector3 normal = cam.transform.forward;
|
|
Vector3 point = cam.transform.position; // можно поменять на position + forward*dist если надо
|
|
plane = new Plane(normal, point);
|
|
break;
|
|
}
|
|
|
|
if (plane.Raycast(ray, out float enter))
|
|
{
|
|
world = ray.GetPoint(enter);
|
|
return true;
|
|
}
|
|
|
|
world = default;
|
|
return false;
|
|
}
|
|
|
|
}
|
|
#endif
|