Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
LightController / LightMode: - Новый LightMode.cs: enum эффектов под протокол 85XXYY (13 эффектов + Off) значения enum = коды команд XX, Off=-1 генерирует просто '85' - Новый LightController.cs: управление подсветкой платы * SetLight(mode, duration) → строит команду 85XXYY, возвращает LightSequence * Blink() / StopBlink() / SetBlinkInterval() — мигание шляпы * StopSequence() / StopAllEffects() — остановка эффектов * Все параметры (hatOn/hatOff, blinkInterval, defaultMode/Duration) в инспекторе - Вложенный класс LightSequence — builder цепочек эффектов: SetLight(A,3).Then(B,3).Then(C,3).Loop() SetLight(A,3).Then(LightMode.Off) SetLight(A,5) — одиночный эффект GameManager: - Добавлено свойство Light (→ Plate.Light) - GameWin → SetLight(FinalWave, 30) - GameOver → SetLight(BlueWave, 30) - NewGame → SetLight(Rainbow, 99) - LoadScene MainMenu → SetLight(Off) + Blink() namespace (добавлены в файлы без namespace): - Editor/MouseWorldPositionOverlay.cs → RR.Common.InspectorOverrides - UI/StatsWindowUIController.cs → RR.Common.UI - Utilities/AdvancedLogging_Test.cs → RR.Common.Utility - Utilities/DebugSettings.cs → RR.Common.Utility
140 lines
4.4 KiB
C#
140 lines
4.4 KiB
C#
#if UNITY_EDITOR && UNITY_2021_2_OR_NEWER
|
|
using UnityEditor;
|
|
using UnityEditor.Overlays;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace RR.Common.InspectorOverrides
|
|
{
|
|
|
|
[Overlay(typeof(SceneView), id: "mouse-world-position", displayName: "Mouse World Position")]
|
|
[Icon("d_Grid.BoxTool")]
|
|
public class MouseWorldPositionOverlay : Overlay
|
|
{
|
|
private enum PlaneMode { XY, XZ, YZ, CameraFacing }
|
|
|
|
private static readonly float[] Multipliers = { 1f, 10f, 100f, 1000f, 10000f, 100000f, 1000000f };
|
|
|
|
private PlaneMode planeMode = PlaneMode.XY;
|
|
private float planeOffset;
|
|
private int decimals = 2;
|
|
|
|
private Vector3 displayWorld;
|
|
private bool hasPoint;
|
|
|
|
private Label positionLabel;
|
|
|
|
|
|
public override void OnCreated()
|
|
{
|
|
SceneView.duringSceneGui += OnSceneGUI;
|
|
}
|
|
|
|
public override void OnWillBeDestroyed()
|
|
{
|
|
SceneView.duringSceneGui -= OnSceneGUI;
|
|
}
|
|
|
|
public override VisualElement CreatePanelContent()
|
|
{
|
|
VisualElement root = new() { style = { minWidth = 220 } };
|
|
|
|
// Плоскость
|
|
EnumField planeModeField = new("Плоскость", planeMode);
|
|
planeModeField.RegisterValueChangedCallback(evt => planeMode = (PlaneMode)evt.newValue);
|
|
root.Add(planeModeField);
|
|
|
|
// Смещение
|
|
FloatField offsetField = new("Смещение") { value = planeOffset };
|
|
offsetField.RegisterValueChangedCallback(evt => planeOffset = evt.newValue);
|
|
root.Add(offsetField);
|
|
|
|
// Знаки после запятой
|
|
SliderInt decimalsSlider = new("Знаки", 0, 6) { value = decimals, showInputField = true };
|
|
decimalsSlider.RegisterValueChangedCallback(evt => decimals = evt.newValue);
|
|
root.Add(decimalsSlider);
|
|
|
|
// Позиция (только для чтения)
|
|
positionLabel = new Label("—") { style = { marginTop = 8, unityFontStyleAndWeight = FontStyle.Bold } };
|
|
root.Add(positionLabel);
|
|
|
|
// Кнопка копирования
|
|
Button copyButton = new(() =>
|
|
{
|
|
if (!hasPoint) return;
|
|
string f = "F" + decimals;
|
|
EditorGUIUtility.systemCopyBuffer = $"{displayWorld.x.ToString(f)}, {displayWorld.y.ToString(f)}, {displayWorld.z.ToString(f)}";
|
|
}) { text = "Копировать (x,y,z)" };
|
|
root.Add(copyButton);
|
|
|
|
return root;
|
|
}
|
|
|
|
private void OnSceneGUI(SceneView sv)
|
|
{
|
|
if (containerWindow != sv) return;
|
|
|
|
Event e = Event.current;
|
|
if (e == null) return;
|
|
|
|
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 Vector3 world);
|
|
|
|
if (hasPoint)
|
|
{
|
|
float mult = Multipliers[decimals];
|
|
displayWorld = new Vector3(
|
|
Mathf.Ceil(world.x * mult) / mult,
|
|
Mathf.Ceil(world.y * mult) / mult,
|
|
Mathf.Ceil(world.z * mult) / mult
|
|
);
|
|
|
|
string f = "F" + decimals;
|
|
positionLabel?.schedule.Execute(() =>
|
|
positionLabel.text = $"X:{displayWorld.x.ToString(f)} Y:{displayWorld.y.ToString(f)} Z:{displayWorld.z.ToString(f)}"
|
|
);
|
|
}
|
|
else
|
|
{
|
|
positionLabel?.schedule.Execute(() => positionLabel.text = "—");
|
|
}
|
|
}
|
|
|
|
private bool TryGetPoint(Ray ray, Camera cam, out Vector3 world)
|
|
{
|
|
Plane plane;
|
|
|
|
switch (planeMode)
|
|
{
|
|
case PlaneMode.XY:
|
|
plane = new Plane(Vector3.forward, new Vector3(0f, 0f, planeOffset));
|
|
break;
|
|
case PlaneMode.XZ:
|
|
plane = new Plane(Vector3.up, new Vector3(0f, planeOffset, 0f));
|
|
break;
|
|
case PlaneMode.YZ:
|
|
plane = new Plane(Vector3.right, new Vector3(planeOffset, 0f, 0f));
|
|
break;
|
|
case PlaneMode.CameraFacing:
|
|
default:
|
|
plane = new Plane(cam.transform.forward, cam.transform.position);
|
|
break;
|
|
}
|
|
|
|
if (plane.Raycast(ray, out float enter))
|
|
{
|
|
world = ray.GetPoint(enter);
|
|
return true;
|
|
}
|
|
|
|
world = default;
|
|
return false;
|
|
}
|
|
|
|
}
|
|
} // namespace RR.Common.InspectorOverrides
|
|
#endif
|