平衡导致问题的 EditorWindow OnGUI 方法内部的调用
Balancing calls inside of a EditorWindow OnGUI method causing problems
我正在制作一个系统来平衡 EditorWindow 的 OnGUI 方法内部的调用。
我正在执行以下操作:
public void Update()
{
Repaint();
}
在我的 OnGUI 方法中,我调用了这个 Balancer。我有一个包含回调的列表 (List)。
所以思路很简单,一些callvaxc
我正在为具有完整 GUI 的回调跳过一些重绘帧,并为其他回调调用每个重绘(例如,选取框标签或显示 gif)。
由于某种原因,发生了这个错误"Getting control 0's position in a group with only 0 controls when doing repaint"
private int m_repaintCounter;
public void Draw()
{
Event e = Event.current;
try
{
foreach (var action in m_actions)
{
try
{
// Test 1
// MainAction is a class that inherits from Action (class MainAction : Action)
if (action is MainAction)
{
bool isDesignedType = e.rawType == EventType.Repaint || e.rawType == EventType.Layout;
if (isDesignedType)
++m_repaintCounter;
if (!(m_repaintCounter == 20 && isDesignedType))
continue;
else
m_repaintCounter = 0;
}
// Test 2
action.Value();
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}
}
catch
{
// Due to recompile the collection will modified, so we need to avoid the exception
}
}
但是如果我评论 "Test 1" 一切正常。
在class的ctor
我们需要指定一个GUI方法的回调,例如:
public Balancer(Action drawAction)
{
m_actions = new List<Action>();
m_actions.Add(drawAction);
}
所以我们可以轻松做到(在EditorWindow
内):
private Balancer m_balancer;
public void OnEnable()
{
m_balancer = new Balancer(Draw);
}
public void Draw()
{
// This block will be called every 20 repaints as specified on the if statment
GUILayout.BeginHorizontal("box");
{
GUILayout.Button("I'm the first button");
GUILayout.Button("I'm to the right");
// This marquee will be called on each repaint
m_balancer.AddAction(() => CustomClass.DisplayMarquee("example"));
}
GUILayout.EndHorizontal();
}
// Inside of the Balancer class we have
// We use System.Linq.Expressions to identify actions that were added already
private HashSet<string> m_alreadyAddedActions = new HashSet<string>();
public void AddAction(Expression<Action> callback)
{
if(!m_alreadyAddedActions.Add(callback.ToString()))
return;
m_actions.Add(callback.Compile());
}
我想不通。我在互联网上找不到任何信息。谁能帮帮我?
好的,所以,OnGui
(IMGui) 很难用。如果您不将其用于编辑器脚本,请改用新的 4.6 UI (UGui)。
那么现在。问题。
OnGui 至少被称为 twice every frame。其中一个是计算布局,另一个是实际绘制东西 ("repaint")。
如果事物的数量、事物的大小或其他任何东西在这两个调用之间发生变化,那么 Unity 将出错 "Getting control 0's position in a group with only 0 controls when doing repaint."
即:您无法在 Layout and before Repaint.
之后的任何时候更改 IMGui 系统中的 UI 状态
仅,仅,仅 在 Event.current == EventType.Repaint
期间更改状态(以及由此绘制的对象)并且仅,仅,仅 更改下一帧的状态(或者,在 Event.current == EventType.Layout
期间进行更改,前提是相同的新状态将在重绘期间导致相同的代码路径)。在任何情况下,都不要在 Repaint 期间进行上一个 Layout 期间不存在的更改。
我正在制作一个系统来平衡 EditorWindow 的 OnGUI 方法内部的调用。 我正在执行以下操作:
public void Update()
{
Repaint();
}
在我的 OnGUI 方法中,我调用了这个 Balancer。我有一个包含回调的列表 (List)。 所以思路很简单,一些callvaxc 我正在为具有完整 GUI 的回调跳过一些重绘帧,并为其他回调调用每个重绘(例如,选取框标签或显示 gif)。
由于某种原因,发生了这个错误"Getting control 0's position in a group with only 0 controls when doing repaint"
private int m_repaintCounter;
public void Draw()
{
Event e = Event.current;
try
{
foreach (var action in m_actions)
{
try
{
// Test 1
// MainAction is a class that inherits from Action (class MainAction : Action)
if (action is MainAction)
{
bool isDesignedType = e.rawType == EventType.Repaint || e.rawType == EventType.Layout;
if (isDesignedType)
++m_repaintCounter;
if (!(m_repaintCounter == 20 && isDesignedType))
continue;
else
m_repaintCounter = 0;
}
// Test 2
action.Value();
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}
}
catch
{
// Due to recompile the collection will modified, so we need to avoid the exception
}
}
但是如果我评论 "Test 1" 一切正常。
在class的ctor
我们需要指定一个GUI方法的回调,例如:
public Balancer(Action drawAction)
{
m_actions = new List<Action>();
m_actions.Add(drawAction);
}
所以我们可以轻松做到(在EditorWindow
内):
private Balancer m_balancer;
public void OnEnable()
{
m_balancer = new Balancer(Draw);
}
public void Draw()
{
// This block will be called every 20 repaints as specified on the if statment
GUILayout.BeginHorizontal("box");
{
GUILayout.Button("I'm the first button");
GUILayout.Button("I'm to the right");
// This marquee will be called on each repaint
m_balancer.AddAction(() => CustomClass.DisplayMarquee("example"));
}
GUILayout.EndHorizontal();
}
// Inside of the Balancer class we have
// We use System.Linq.Expressions to identify actions that were added already
private HashSet<string> m_alreadyAddedActions = new HashSet<string>();
public void AddAction(Expression<Action> callback)
{
if(!m_alreadyAddedActions.Add(callback.ToString()))
return;
m_actions.Add(callback.Compile());
}
我想不通。我在互联网上找不到任何信息。谁能帮帮我?
好的,所以,OnGui
(IMGui) 很难用。如果您不将其用于编辑器脚本,请改用新的 4.6 UI (UGui)。
那么现在。问题。
OnGui 至少被称为 twice every frame。其中一个是计算布局,另一个是实际绘制东西 ("repaint")。
如果事物的数量、事物的大小或其他任何东西在这两个调用之间发生变化,那么 Unity 将出错 "Getting control 0's position in a group with only 0 controls when doing repaint."
即:您无法在 Layout and before Repaint.
之后的任何时候更改 IMGui 系统中的 UI 状态仅,仅,仅 在 Event.current == EventType.Repaint
期间更改状态(以及由此绘制的对象)并且仅,仅,仅 更改下一帧的状态(或者,在 Event.current == EventType.Layout
期间进行更改,前提是相同的新状态将在重绘期间导致相同的代码路径)。在任何情况下,都不要在 Repaint 期间进行上一个 Layout 期间不存在的更改。