【问题标题】:Align variables horizontally in unity inspector在统一检查器中水平对齐变量
【发布时间】:2016-12-29 03:03:54
【问题描述】:

我正在编写一个非常简单的类来存储数据(至少目前是这样),以便在 Unity 项目中用于学习 AI。我希望能够轻松地在检查器中自定义多个代理,并且垂直堆叠的复选框数量使我的项目的这一部分主宰了检查器。如果我可以简单地让一个部分利用检查器右侧的充足空间,那将不那么难看。

我已经阅读了很多关于自定义属性抽屉和检查器窗口的内容,但似乎需要做很多工作,包括重写整个类的显示方式,只需要一次更改。

作为参考,这里是类本身。

[System.Serializable]
public class NNInfo
{
    public string networkName = "Agent";

    [Header("Movement Properties")]
    public float movementSpeed = 10f;
    public float rotationSpeed = 1f;

    [Header("Learning Properties")]
    public float learningRate = 0.1f;
    public float momentum = 0f;
    public Rewards rewardFunc;
    public int[] hiddenLayers;

    [Header("Other Properties")]
    public int maxHealth = 1000;

    [Header("Optional Inputs")]
    public bool m_PointToNearestBall = false;           // input which is 1 while the agent is facing a ball and -1 when facing away
    public bool m_DistanceToNearestBall = false;        // input which is 1 while the agent is at the ball and -1 when at max possible distance away
    public bool m_PointToEndzone = false;               // similar to m_PointToNearestBall but for the endzone
    public bool m_Position = false;                     // two inputs which inform the player of its normalized x and y coordinates on the field
    public bool m_WhetherHoldingBall = false;           // tells the player whether its holding a ball
    public bool m_CanSeeHealth = false;                 // Whether the player can know its own health

    [Header("Optional Outputs")]
    public bool m_ForwardLeft = false;                  // turn left and move forward simultaneously
    public bool m_ForwardRight = false;                 // turn right and move forward simultaneously
    public bool m_Reverse = false;                      // move backwards
    public bool m_Flip = false;                         // instantly switch to opposite direction
    public bool m_TurnToBall = false;                   // instantly turn to face nearest ball
    public bool m_TurnToLeft = false;                   // instantly turn to face left side of field
    public bool m_Attack = false;                       // attack a player (or idle if no contact)
}

【问题讨论】:

  • 这是一个非常酷的想法,但我认为这是不可能的(以一种简单的方式)。
  • 我认为这是主题不属于 SO。由于问题是关于 Unity Dev 工具的,它与纯编程没有直接关系。它应该属于 Game Dev (gamedev.stackexchange.com) 或者为什么不属于 Unity Answers 网站 (answers.unity3d.com)。
  • 要完成,您需要更新编辑器代码(或编写您自己的函数)。难度不大,网上有很多教程。

标签: unity3d inspector


【解决方案1】:

自定义属性抽屉是您应该感兴趣的关键字。

编写您自己的代码来管理这些 - 让您描述您希望如何在 Unity 编辑器的 Inspector View 中显示您的属性。

要开始,请转到官方documentation site,,其中包含您可以基于的代码。

代码sn-ps(Javacrpt,c#版本可以在链接下找到):

对象的代码:

enum IngredientUnit { Spoon, Cup, Bowl, Piece }

// Custom serializable class
class Ingredient extends System.Object {
    var name : String;
    var amount : int = 1;
    var unit : IngredientUnit;
}

var potionResult : Ingredient;
var potionIngredients : Ingredient[];

function Update () {
    // Update logic here...
}

编辑器代码:

@CustomPropertyDrawer(Ingredient)
class IngredientDrawer extends PropertyDrawer {

    // Draw the property inside the given rect
    function OnGUI (position : Rect, property : SerializedProperty, label : GUIContent) {
        // Using BeginProperty / EndProperty on the parent property means that
        // prefab override logic works on the entire property.
        EditorGUI.BeginProperty (position, label, property);

        // Draw label
        position = EditorGUI.PrefixLabel (position, GUIUtility.GetControlID (FocusType.Passive), label);

        // Don't make child fields be indented
        var indent = EditorGUI.indentLevel;
        EditorGUI.indentLevel = 0;

        // Calculate rects
        var amountRect = new Rect (position.x, position.y, 30, position.height);
        var unitRect = new Rect (position.x+35, position.y, 50, position.height);
        var nameRect = new Rect (position.x+90, position.y, position.width-90, position.height);

        // Draw fields - passs GUIContent.none to each so they are drawn without labels
        EditorGUI.PropertyField (amountRect, property.FindPropertyRelative ("amount"), GUIContent.none);
        EditorGUI.PropertyField (unitRect, property.FindPropertyRelative ("unit"), GUIContent.none);
        EditorGUI.PropertyField (nameRect, property.FindPropertyRelative ("name"), GUIContent.none);

        // Set indent back to what it was
        EditorGUI.indentLevel = indent;

        EditorGUI.EndProperty ();
    }
}

【讨论】:

    猜你喜欢
    • 2016-09-15
    • 1970-01-01
    • 2020-09-26
    • 2013-04-16
    • 2013-02-02
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多