using UnityEngine;
using UnityEditor;
namespace MLAgents
{
///
/// CustomEditor for the PlayerBrain class. Defines the default Inspector view for a
/// PlayerBrain.
/// Shows the BrainParameters of the Brain and expose a tool to deep copy BrainParameters
/// between brains. Also exposes the key mappings for either continuous or discrete control
/// depending on the Vector Action Space Type of the Brain Parameter. These mappings are the
/// ones that will be used by the PlayerBrain.
///
[CustomEditor(typeof(PlayerBrain))]
public class PlayerBrainEditor : BrainEditor
{
private const string k_KeyContinuousPropName = "keyContinuousPlayerActions";
private const string k_KeyDiscretePropName = "discretePlayerActions";
private const string k_AxisContinuousPropName = "axisContinuousPlayerActions";
public override void OnInspectorGUI()
{
EditorGUILayout.LabelField("Player Brain", EditorStyles.boldLabel);
var brain = (PlayerBrain)target;
var serializedBrain = serializedObject;
base.OnInspectorGUI();
serializedBrain.Update();
if (brain.brainParameters.vectorActionSpaceType == SpaceType.Continuous)
{
DrawContinuousKeyMapping(serializedBrain, brain);
}
else
{
DrawDiscreteKeyMapping(serializedBrain);
}
serializedBrain.ApplyModifiedProperties();
}
///
/// Draws the UI for continuous control key mapping to actions.
///
/// The SerializedObject corresponding to the brain.
/// The Brain of which properties are displayed.
private static void DrawContinuousKeyMapping(
SerializedObject serializedBrain, PlayerBrain brain)
{
GUILayout.Label("Edit the continuous inputs for your actions", EditorStyles.boldLabel);
var keyActionsProp = serializedBrain.FindProperty(k_KeyContinuousPropName);
var axisActionsProp = serializedBrain.FindProperty(k_AxisContinuousPropName);
EditorGUILayout.PropertyField(keyActionsProp , true);
EditorGUILayout.PropertyField(axisActionsProp, true);
var keyContinuous = brain.keyContinuousPlayerActions;
var axisContinuous = brain.axisContinuousPlayerActions;
var brainParams = brain.brainParameters;
if (keyContinuous == null)
{
keyContinuous = new PlayerBrain.KeyContinuousPlayerAction[0];
}
if (axisContinuous == null)
{
axisContinuous = new PlayerBrain.AxisContinuousPlayerAction[0];
}
foreach (var action in keyContinuous)
{
if (action.index >= brainParams.vectorActionSize[0])
{
EditorGUILayout.HelpBox(
$"Key {action.key.ToString()} is assigned to index " +
$"{action.index.ToString()} but the action size is only of size " +
$"{brainParams.vectorActionSize}",
MessageType.Error);
}
}
foreach (var action in axisContinuous)
{
if (action.index >= brainParams.vectorActionSize[0])
{
EditorGUILayout.HelpBox(
$"Axis {action.axis} is assigned to index {action.index.ToString()} " +
$"but the action size is only of size {brainParams.vectorActionSize}",
MessageType.Error);
}
}
GUILayout.Label("You can change axis settings from Edit->Project Settings->Input",
EditorStyles.helpBox);
}
///
/// Draws the UI for discrete control key mapping to actions.
///
/// The SerializedObject corresponding to the brain.
private static void DrawDiscreteKeyMapping(SerializedObject serializedBrain)
{
GUILayout.Label("Edit the discrete inputs for your actions",
EditorStyles.boldLabel);
var dhas = serializedBrain.FindProperty(k_KeyDiscretePropName);
serializedBrain.Update();
EditorGUILayout.PropertyField(dhas, true);
}
}
}