【发布时间】:2021-03-15 12:51:51
【问题描述】:
我正在开发一个 Unity 工具,我想为它创建一个自定义 GUI。
在这个简单的脚本中,我正在检查鼠标是否悬停在按钮上,如果是,我更改 GUI 颜色。这只是一个非常基本的例子,但同样的原则也适用于我想做的事情。
问题是更改确实延迟了。我尝试实现 isDirty 状态,它只在需要时重新绘制。虽然它似乎不起作用。同样的延迟问题...我可以每帧重新绘制窗口,但这真的很糟糕。
private bool isDirty = false;
Rect _hoveredRect;
Rect HoveredRect
{
get { return _hoveredRect; }
set
{
if (_hoveredRect != value)
{
isDirty = true;
}
_hoveredRect = value;
}
}
void Update()
{
if (isDirty)
{
Repaint();
isDirty = false;
}
}
void OnGUI()
{
Rect button = new Rect(25, 25, 100, 35);
DrawButton(button, "Label");
}
bool DrawButton(Rect rect, string label)
{
var e = Event.current;
bool hovered = rect.Contains(e.mousePosition);
if (hovered)
{
HoveredRect = rect;
}
if (!hovered && HoveredRect == rect)
{
HoveredRect = Rect.zero;
}
var defaultColor = GUI.color;
GUI.color = hovered ? Color.red : defaultColor;
bool pressed = GUI.Button(rect, label);
GUI.color = defaultColor;
return pressed;
}
然后我想出了另一个解决方案,它应该可以工作,但是我需要获取鼠标位置并且我不能在 OnGUI 函数之外使用 Event.current。
Dictionary<Rect, bool> hoverableRects = new Dictionary<Rect, bool>();
private void OnEnable()
{
EditorApplication.update += UpdateMe;
}
private void OnDisable()
{
EditorApplication.update -= UpdateMe;
}
void UpdateMe()
{
var mousePos = ??; List<Rect> rects = new List<Rect>(hoverableRects.Keys);
foreach (var rect in rects)
{
hoverableRects[rect] = rect.Contains(mousePos);
}
}
void OnGUI()
{
Rect button = new Rect(25, 25, 100, 35);
DrawButton(button, "Label");
}
bool DrawButton(Rect rect, string label)
{
if (!hoverableRects.ContainsKey(rect))
{ hoverableRects.Add(rect, false); }
var defaultColor = GUI.color;
GUI.color = hoverableRects[rect] ? Color.red : defaultColor;
bool pressed = GUI.Button(rect, label);
GUI.color = defaultColor;
return pressed;
}
有没有办法在 OnGUI 方法之外的每一帧中获取鼠标位置?
【问题讨论】:
-
这能回答你的问题吗? Unity - Custom Editor - data refresh
-
没有。我在我的问题中提到了这种方法。我可以每帧都重新绘制窗口,但这会破坏性能
-
正如我的回答中提到的那样,
OnInspectorUpdate并不是每帧都调用 .. 此外,您可以通过仅检查您当前悬停的一个矩形并仅检查一次所有矩形来再次稍微降低性能影响你离开了当前的
标签: c# unity3d events position mouse