added MouseWorldPositionWindow for displaying world position under cursor in Scene View
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
This commit is contained in:
parent
384a8fad82
commit
2639239085
132
Assets/Scripts/Editor/MouseWorldPositionWindow.cs
Normal file
132
Assets/Scripts/Editor/MouseWorldPositionWindow.cs
Normal file
@ -0,0 +1,132 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class MouseWorldPositionWindow : EditorWindow
|
||||
{
|
||||
private enum PlaneMode { XY, XZ, YZ, CameraFacing }
|
||||
|
||||
private PlaneMode planeMode = PlaneMode.XZ;
|
||||
private float planeOffset = 0f; // смещение плоскости по нормали (Z для XY, Y для XZ, X для YZ)
|
||||
private bool lockToSceneView = true;
|
||||
private int decimals = 3;
|
||||
|
||||
private Vector3 lastWorld;
|
||||
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("Plane", planeMode);
|
||||
if (planeMode != PlaneMode.CameraFacing)
|
||||
planeOffset = EditorGUILayout.FloatField("Plane Offset", 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", lastWorld);
|
||||
}
|
||||
|
||||
using (new EditorGUI.DisabledScope(!hasPoint))
|
||||
{
|
||||
if (GUILayout.Button("Copy (x,y,z)"))
|
||||
{
|
||||
EditorGUIUtility.systemCopyBuffer = FormatVec(lastWorld, decimals);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.HelpBox(
|
||||
"Move mouse in Scene View. The window shows world position under cursor.\n" +
|
||||
"3D uses ray-plane intersection (choose plane). 2D обычно: XY @ Z=0.",
|
||||
MessageType.Info);
|
||||
}
|
||||
|
||||
private void OnSceneGUI(SceneView sv)
|
||||
{
|
||||
if (!lockToSceneView && sv != SceneView.lastActiveSceneView) return;
|
||||
|
||||
var 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);
|
||||
|
||||
// чтобы окно обновлялось живо
|
||||
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:
|
||||
var normal = cam.transform.forward;
|
||||
var 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;
|
||||
}
|
||||
|
||||
private static string FormatVec(Vector3 v, int d)
|
||||
{
|
||||
string f = "F" + Mathf.Clamp(d, 0, 6);
|
||||
return $"{v.x.ToString(f)}, {v.y.ToString(f)}, {v.z.ToString(f)}";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
2
Assets/Scripts/Editor/MouseWorldPositionWindow.cs.meta
Normal file
2
Assets/Scripts/Editor/MouseWorldPositionWindow.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eedb77236baea004994341514803f9e7
|
||||
Loading…
x
Reference in New Issue
Block a user