C# 画;EditorGUILayout.FloatField“;字段后是否有自定义标签?
我正在制作一个自定义编辑器窗口,我想在上面绘制C# 画;EditorGUILayout.FloatField“;字段后是否有自定义标签?,c#,unity3d,C#,Unity3d,我正在制作一个自定义编辑器窗口,我想在上面绘制EditorGUILayout.FloatField。如果我这样写: EditorGUILayout.FloatField("change val", someFloatValue); 一个标签出现在字段前面。但我希望它出现在球场后面。另外,我想用纹理来改变简单的文本 我现在所拥有的: 我想要实现的目标: UPD.我错过了重要信息: 在纹理上的鼠标行为必须与在FloatField标签上的鼠标行为相同,即,如果单击纹理并开始拖动光标,则字段中的
EditorGUILayout.FloatField
。如果我这样写:
EditorGUILayout.FloatField("change val", someFloatValue);
一个标签出现在字段前面。但我希望它出现在球场后面。另外,我想用纹理来改变简单的文本
我现在所拥有的:
我想要实现的目标:
UPD.我错过了重要信息: 在纹理上的鼠标行为必须与在FloatField标签上的鼠标行为相同,即,如果单击纹理并开始拖动光标,则字段中的float值必须更改
我找不到一个简单的方法。也许我错过了什么
有可能不为这个简单的操作创建很多辅助类吗?如果是,那么怎么做?这是很有可能的,但您不应该使用GUILayout/EditorGUILayout类。类名中的布局意味着这些变体自己处理定位,它们各自占用默认的空间量并移动到下一行,这非常方便,但要做更高级的工作,您应该使用以Rect作为绘图位置的GUI版本,因此从GUI/EditorGUI类中获取(类名中没有布局)
我建议你首先做一个自定义的PropertyDrawer,PropertyDrawer的API需要手动放置元素,因此有很多好的例子。一旦你开始使用矩形而不是自动布局来绘制,就没有限制要在哪里绘制多少层,在你自己的检查器之外开始绘制其实很简单(只要它在同一个窗口中)只需在floatfield后面放置一个label字段即可
EditorGUILayout.BeginHorizontal();
someFloatValue = EditorGUILayout.FloatField(someFloatValue);
EditorGUILayout.LabelField("Change Val")
EditorGUILayout.EndHorizontal();
如果要放置纹理,则只需使用所需纹理作为背景创建GUIStyle
,并将该样式用于标签
GUIStyle myStyle = new GUIStyle();
myStyle.normal.background = myTexture;
EditorGUILayout.BeginHorizontal();
someFloatValue = EditorGUILayout.FloatField(someFloatValue);
EditorGUILayout.LabelField("", myStyle)
EditorGUILayout.EndHorizontal();
现在,要处理宽度,只需使用GUILayout.Width()
嗯,我已经为字段(也为
IntField
)做了一个丑陋的变通方法。
如果删除所有多余的代码,我用来填充内容-它会很短
简化的示例如下所示:
using UnityEditor;
using UnityEngine;
public class MainWindow : EditorWindow {
private float floatFieldVal;
private Rect groupFloatFieldRect;
[MenuItem("Examples/Test")]
static void Init() {
MainWindow window = (MainWindow)GetWindow(typeof(MainWindow), false, "My Empty Window");
window.Show();
}
void OnGUI() {
EditorGUILayout.BeginHorizontal(); {
EditorGUILayout.BeginVertical(); {
GUILayout.Button("Button 1");
GUILayout.Button("Button 2");
GUILayout.Button("Button 3");
} EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUILayout.Width(300)); {
// never load asset in the loop :)
string assetFullPath = "Assets/Editor/Test.guiskin";
var fakeFieldGUISkin = (GUISkin)AssetDatabase.LoadAssetAtPath(assetFullPath, typeof(GUISkin));
GUIStyle fakeFieldStyle = fakeFieldGUISkin.GetStyle("test");
// place fake floatField right over a real field texture button
Rect test = new Rect(groupFloatFieldRect);
test.position = new Vector2(test.x + groupFloatFieldRect.width - 20, test.y + 3);
test.size = new Vector2(20, 20);
floatFieldVal = EditorGUI.FloatField(test, "fake", floatFieldVal, fakeFieldStyle);
// Draw FloatField And Texture as a Group
Rect groupRect = EditorGUILayout.BeginHorizontal(); {
// never create GUIStyle in the loop :)
GUIStyle floatIconStyle = new GUIStyle(EditorStyles.toolbarButton) {
fixedWidth = 20f,
margin = new RectOffset(0, 0, 0, 0),
padding = new RectOffset(0, 0, 0, 0)
};
floatFieldVal = EditorGUILayout.FloatField("", floatFieldVal);
// It emulates a texture
GUILayout.Label("◀▶", floatIconStyle)
// save group rect in a variable
if (Event.current.type == EventType.Repaint)
groupFloatFieldRect = groupRect;
} EditorGUILayout.EndHorizontal();
} EditorGUILayout.EndVertical();
} EditorGUILayout.EndHorizontal();
}
void OnInspectorUpdate() {
Repaint();
}
}
当然,所有的幻数都只是一个简单的例子。另外,guiskin
加载和GUIStyle
创建不应该在一个循环中(在本例中是在OnGUI
中)。这也是一个简单的例子
Test.guiskin
用于删除默认皮肤数据并在需要时调整其他参数
上面的代码就是这样的:
我不想制作自己的GUI系统,因为Unity已经有了它。)事实上,我必须编写与fields相同的逻辑:观察鼠标点击并按住按钮、聚焦/模糊事件、增加字段值等。这太令人伤心了……所以,唯一的方法就是创建大量的辅助类:'(您仍然可以使用unity的GUI,但它们有两种风格:布局和非Layuout(rect-base),它们的操作方式完全相同,事实上我怀疑布局版本只是围绕着非布局版本。它们使用
GetControlRect
和LastRect
作为EditorGUILayout
:…我临时做了一个变通办法(见我的答案)。如果删除我用于内容填充的所有冗余代码-它将非常短…但我还是会考虑使用属性抽屉。这不是我想要的。因为鼠标在纹理上的行为必须与在FloatField标签上的行为相同,即如果我单击纹理并开始拖动光标-字段中的浮点值必须更改。很抱歉错过了信息。我想我已经把它添加到我的问题中了
using UnityEditor;
using UnityEngine;
public class MainWindow : EditorWindow {
private float floatFieldVal;
private Rect groupFloatFieldRect;
[MenuItem("Examples/Test")]
static void Init() {
MainWindow window = (MainWindow)GetWindow(typeof(MainWindow), false, "My Empty Window");
window.Show();
}
void OnGUI() {
EditorGUILayout.BeginHorizontal(); {
EditorGUILayout.BeginVertical(); {
GUILayout.Button("Button 1");
GUILayout.Button("Button 2");
GUILayout.Button("Button 3");
} EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical(GUILayout.Width(300)); {
// never load asset in the loop :)
string assetFullPath = "Assets/Editor/Test.guiskin";
var fakeFieldGUISkin = (GUISkin)AssetDatabase.LoadAssetAtPath(assetFullPath, typeof(GUISkin));
GUIStyle fakeFieldStyle = fakeFieldGUISkin.GetStyle("test");
// place fake floatField right over a real field texture button
Rect test = new Rect(groupFloatFieldRect);
test.position = new Vector2(test.x + groupFloatFieldRect.width - 20, test.y + 3);
test.size = new Vector2(20, 20);
floatFieldVal = EditorGUI.FloatField(test, "fake", floatFieldVal, fakeFieldStyle);
// Draw FloatField And Texture as a Group
Rect groupRect = EditorGUILayout.BeginHorizontal(); {
// never create GUIStyle in the loop :)
GUIStyle floatIconStyle = new GUIStyle(EditorStyles.toolbarButton) {
fixedWidth = 20f,
margin = new RectOffset(0, 0, 0, 0),
padding = new RectOffset(0, 0, 0, 0)
};
floatFieldVal = EditorGUILayout.FloatField("", floatFieldVal);
// It emulates a texture
GUILayout.Label("◀▶", floatIconStyle)
// save group rect in a variable
if (Event.current.type == EventType.Repaint)
groupFloatFieldRect = groupRect;
} EditorGUILayout.EndHorizontal();
} EditorGUILayout.EndVertical();
} EditorGUILayout.EndHorizontal();
}
void OnInspectorUpdate() {
Repaint();
}
}