Выровнять переменные по горизонтали в Инспекторе единиц
Я пишу очень простой класс для хранения данных (по крайней мере, на данный момент) для использования в проекте 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)
}
1 ответ
Custom Property Drawer - это ключевое слово, которое должно вас заинтересовать.
Написание собственного кода для управления ими - позволяет вам описать, как вы хотите показать свои свойства в Inspector View в редакторе Unity.
Для начала перейдите на официальный сайт документации, который содержит код , на котором вы можете основываться.
Фрагменты кода (версию 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 ();
}
}