Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 画;EditorGUILayout.FloatField“;字段后是否有自定义标签?_C#_Unity3d - Fatal编程技术网

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();
    }    
}