浏览代码

Brains as Scriptable Objects (#1250)

* Initial Commit
Ported most functionalities, still need to :
 - Documentation
 - Add Comments
 - Custom drawer for BrainParameters
 - Fix the UnitTests
 - Review Functionalities

* Added Custom Drawer for the Brain Parameters

* Improvements to the HubDrawer

* Modified the Brain Editors

* Minor bug fixes and UI changes

* Modified the Help Boxes of the Drawers

* Modified Brain class, renamed Initialize and made DecideAction virtual

* Fix the UnityTests

* Simpler Brain creation menu

* Renamed Internal Brain to Learning Brain

* modified the parameters to remove reference to External or Internal in the Protobuf objects

* Updated the protobuf generated files

* Fix the Pytests

* Removed the graph scope from the Learning Brain

* cleaner logic than try catch

* Removed the isExternal field of the brain and put the isTraining logic into LearningBrain and Training Hub

* Modified how the Brain finds the A...
/develop-generalizationTraining-TrainerController
GitHub 6 年前
当前提交
d7224351
共有 130 个文件被更改,包括 4984 次插入2491 次删除
  1. 168
      UnitySDK/Assets/ML-Agents/Editor/BrainEditor.cs
  2. 15
      UnitySDK/Assets/ML-Agents/Editor/BrainEditor.cs.meta
  3. 175
      UnitySDK/Assets/ML-Agents/Editor/ResetParameterDrawer.cs
  4. 2
      UnitySDK/Assets/ML-Agents/Editor/Tests/DemonstrationTests.cs
  5. 62
      UnitySDK/Assets/ML-Agents/Editor/Tests/MLAgentsEditModeTest.cs
  6. 5
      UnitySDK/Assets/ML-Agents/Examples/3DBall/Prefabs/Game.prefab
  7. 279
      UnitySDK/Assets/ML-Agents/Examples/3DBall/Scenes/3DBall.unity
  8. 9
      UnitySDK/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DDecision.cs
  9. 6
      UnitySDK/Assets/ML-Agents/Examples/Basic/Scripts/BasicDecision.cs
  10. 6
      UnitySDK/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherDecision.cs
  11. 17
      UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RandomDecision.cs
  12. 6
      UnitySDK/Assets/ML-Agents/Examples/Template/Scripts/TemplateDecision.cs
  13. 73
      UnitySDK/Assets/ML-Agents/Scripts/Academy.cs
  14. 21
      UnitySDK/Assets/ML-Agents/Scripts/ActionMasker.cs
  15. 4
      UnitySDK/Assets/ML-Agents/Scripts/Agent.cs
  16. 2
      UnitySDK/Assets/ML-Agents/Scripts/Batcher.cs
  17. 315
      UnitySDK/Assets/ML-Agents/Scripts/Brain.cs
  18. 58
      UnitySDK/Assets/ML-Agents/Scripts/CommunicatorObjects/BrainParametersProto.cs
  19. 4
      UnitySDK/Assets/ML-Agents/Scripts/CommunicatorObjects/UnityInput.cs
  20. 6
      UnitySDK/Assets/ML-Agents/Scripts/CommunicatorObjects/UnityMessage.cs
  21. 4
      UnitySDK/Assets/ML-Agents/Scripts/CommunicatorObjects/UnityOutput.cs
  22. 2
      UnitySDK/Assets/ML-Agents/Scripts/CommunicatorObjects/UnityRlInitializationOutput.cs
  23. 2
      UnitySDK/Assets/ML-Agents/Scripts/CommunicatorObjects/UnityRlInput.cs
  24. 8
      UnitySDK/Assets/ML-Agents/Scripts/CommunicatorObjects/UnityToExternalGrpc.cs
  25. 8
      UnitySDK/Assets/ML-Agents/Scripts/Decision.cs
  26. 2
      UnitySDK/Assets/ML-Agents/Scripts/DemonstrationStore.cs
  27. 19
      UnitySDK/Assets/ML-Agents/Scripts/Utilities.cs
  28. 10
      docs/Background-TensorFlow.md
  29. 46
      docs/Basic-Guide.md
  30. 6
      docs/FAQ.md
  31. 56
      docs/Getting-Started-with-Balance-Ball.md
  32. 4
      docs/Glossary.md
  33. 79
      docs/Learning-Environment-Create-New.md
  34. 5
      docs/Learning-Environment-Design-Academy.md
  35. 19
      docs/Learning-Environment-Design-Agents.md
  36. 70
      docs/Learning-Environment-Design-Brains.md
  37. 11
      docs/Learning-Environment-Design-Heuristic-Brains.md
  38. 7
      docs/Learning-Environment-Design-Player-Brains.md
  39. 51
      docs/Learning-Environment-Design.md
  40. 22
      docs/Learning-Environment-Executable.md
  41. 51
      docs/ML-Agents-Overview.md
  42. 18
      docs/Migrating.md
  43. 14
      docs/Python-API.md
  44. 2
      docs/Readme.md
  45. 15
      docs/Training-Imitation-Learning.md
  46. 2
      docs/Training-ML-Agents.md
  47. 2
      docs/Using-Docker.md
  48. 12
      docs/Using-TensorFlow-Sharp-in-Unity.md
  49. 629
      docs/images/academy.png
  50. 114
      docs/images/agent.png
  51. 204
      docs/images/brain.png
  52. 355
      docs/images/broadcast.png
  53. 348
      docs/images/mlagents-NewTutAcademy.png
  54. 999
      docs/images/mlagents-NewTutAssignBrain.png
  55. 703
      docs/images/mlagents-NewTutBrain.png
  56. 92
      docs/images/mlagents-NewTutHierarchy.png
  57. 1
      ml-agents/mlagents/envs/communicator_objects/__init__.py
  58. 15
      ml-agents/mlagents/envs/communicator_objects/agent_action_proto_pb2.py
  59. 29
      ml-agents/mlagents/envs/communicator_objects/agent_info_proto_pb2.py
  60. 39
      ml-agents/mlagents/envs/communicator_objects/brain_parameters_proto_pb2.py
  61. 13
      ml-agents/mlagents/envs/communicator_objects/command_proto_pb2.py
  62. 19
      ml-agents/mlagents/envs/communicator_objects/engine_configuration_proto_pb2.py
  63. 18
      ml-agents/mlagents/envs/communicator_objects/environment_parameters_proto_pb2.py
  64. 11
      ml-agents/mlagents/envs/communicator_objects/header_pb2.py
  65. 13
      ml-agents/mlagents/envs/communicator_objects/resolution_proto_pb2.py
  66. 11
      ml-agents/mlagents/envs/communicator_objects/space_type_proto_pb2.py
  67. 11
      ml-agents/mlagents/envs/communicator_objects/unity_input_pb2.py
  68. 13
      ml-agents/mlagents/envs/communicator_objects/unity_message_pb2.py
  69. 11
      ml-agents/mlagents/envs/communicator_objects/unity_output_pb2.py
  70. 9
      ml-agents/mlagents/envs/communicator_objects/unity_rl_initialization_input_pb2.py
  71. 17
      ml-agents/mlagents/envs/communicator_objects/unity_rl_initialization_output_pb2.py
  72. 28
      ml-agents/mlagents/envs/communicator_objects/unity_rl_input_pb2.py
  73. 24
      ml-agents/mlagents/envs/communicator_objects/unity_rl_output_pb2.py
  74. 6
      ml-agents/mlagents/envs/environment.py
  75. 2
      ml-agents/tests/mock_communicator.py
  76. 3
      protobuf-definitions/proto/mlagents/envs/communicator_objects/brain_parameters_proto.proto
  77. 183
      UnitySDK/Assets/Gizmos/LearningBrain Icon.png
  78. 369
      UnitySDK/Assets/ML-Agents/Editor/BrainParametersDrawer.cs
  79. 12
      UnitySDK/Assets/ML-Agents/Editor/BrainParametersDrawer.cs.meta
  80. 208
      UnitySDK/Assets/ML-Agents/Editor/BroadcastHubDrawer.cs
  81. 3
      UnitySDK/Assets/ML-Agents/Editor/BroadcastHubDrawer.cs.meta
  82. 56
      UnitySDK/Assets/ML-Agents/Editor/HeuristicBrainEditor.cs
  83. 3
      UnitySDK/Assets/ML-Agents/Editor/HeuristicBrainEditor.cs.meta
  84. 27
      UnitySDK/Assets/ML-Agents/Editor/LearningBrainEditor.cs
  85. 3
      UnitySDK/Assets/ML-Agents/Editor/LearningBrainEditor.cs.meta
  86. 106
      UnitySDK/Assets/ML-Agents/Editor/PlayerBrainEditor.cs
  87. 3
      UnitySDK/Assets/ML-Agents/Editor/PlayerBrainEditor.cs.meta
  88. 23
      UnitySDK/Assets/ML-Agents/Editor/Tests/UtilitiesTests.cs
  89. 3
      UnitySDK/Assets/ML-Agents/Editor/Tests/UtilitiesTests.cs.meta
  90. 8
      UnitySDK/Assets/ML-Agents/Examples/3DBall/Brains.meta
  91. 124
      UnitySDK/Assets/ML-Agents/Scripts/BrainParameters.cs
  92. 3
      UnitySDK/Assets/ML-Agents/Scripts/BrainParameters.cs.meta
  93. 68
      UnitySDK/Assets/ML-Agents/Scripts/BroadcastHub.cs
  94. 3
      UnitySDK/Assets/ML-Agents/Scripts/BroadcastHub.cs.meta
  95. 86
      UnitySDK/Assets/ML-Agents/Scripts/HeuristicBrain.cs
  96. 486
      UnitySDK/Assets/ML-Agents/Scripts/LearningBrain.cs
  97. 108
      UnitySDK/Assets/ML-Agents/Scripts/PlayerBrain.cs
  98. 73
      docs/Learning-Environment-Design-Learning-Brains.md

168
UnitySDK/Assets/ML-Agents/Editor/BrainEditor.cs


namespace MLAgents
{
/*
This code is meant to modify the behavior of the inspector on Brain Components.
Depending on the type of brain that is used, the available fields will be modified in the inspector accordingly.
*/
/// <summary>
/// CustomEditor for the Brain base class. Defines the default Inspector view for a Brain.
/// Shows the BrainParameters of the Brain and expose a tool to deep copy BrainParameters
/// between brains.
/// </summary>
{
[SerializeField] bool _Foldout = true;
{
Brain myBrain = (Brain) target;
SerializedObject serializedBrain = serializedObject;
if (myBrain.transform.parent == null)
{
EditorGUILayout.HelpBox(
"A Brain GameObject must be a child of an Academy GameObject!",
MessageType.Error);
}
else if (myBrain.transform.parent.GetComponent<Academy>() == null)
{
EditorGUILayout.HelpBox(
"The Parent of a Brain must have an Academy Component attached to it!",
MessageType.Error);
}
serializedBrain.Update();
_Foldout = EditorGUILayout.Foldout(_Foldout, "Brain Parameters");
int indentLevel = EditorGUI.indentLevel;
if (_Foldout)
{
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("Vector Observation");
EditorGUI.indentLevel++;
SerializedProperty bpVectorObsSize =
serializedBrain.FindProperty("brainParameters.vectorObservationSize");
EditorGUILayout.PropertyField(bpVectorObsSize, new GUIContent("Space Size",
"Length of state " +
"vector for brain (In Continuous state space)." +
"Or number of possible values (in Discrete state space)."));
SerializedProperty bpNumStackedVectorObs =
serializedBrain.FindProperty("brainParameters.numStackedVectorObservations");
EditorGUILayout.PropertyField(bpNumStackedVectorObs, new GUIContent(
"Stacked Vectors", "Number of states that" +
" will be stacked before beeing fed to the neural network."));
EditorGUI.indentLevel--;
SerializedProperty bpCamResol =
serializedBrain.FindProperty("brainParameters.cameraResolutions");
EditorGUILayout.PropertyField(bpCamResol, new GUIContent("Visual Observation",
"Describes height, " +
"width, and whether to greyscale visual observations for the Brain."), true);
EditorGUILayout.LabelField("Vector Action");
EditorGUI.indentLevel++;
SerializedProperty bpVectorActionType =
serializedBrain.FindProperty("brainParameters.vectorActionSpaceType");
EditorGUILayout.PropertyField(bpVectorActionType, new GUIContent("Space Type",
"Corresponds to whether state" +
" vector contains a single integer (Discrete) " +
"or a series of real-valued floats (Continuous)."));
if (bpVectorActionType.enumValueIndex == 1)
{
//Continuous case :
SerializedProperty bpVectorActionSize =
serializedBrain.FindProperty("brainParameters.vectorActionSize");
bpVectorActionSize.arraySize = 1;
SerializedProperty continuousActionSize =
bpVectorActionSize.GetArrayElementAtIndex(0);
EditorGUILayout.PropertyField(continuousActionSize, new GUIContent(
"Space Size", "Length of continuous action vector."));
}
else
{
// Discrete case :
SerializedProperty bpVectorActionSize =
serializedBrain.FindProperty("brainParameters.vectorActionSize");
bpVectorActionSize.arraySize = EditorGUILayout.IntField(
"Branches Size", bpVectorActionSize.arraySize);
EditorGUI.indentLevel++;
for (int branchIndex = 0;
branchIndex < bpVectorActionSize.arraySize;
branchIndex++)
{
SerializedProperty branchActionSize =
bpVectorActionSize.GetArrayElementAtIndex(branchIndex);
EditorGUILayout.PropertyField(branchActionSize, new GUIContent(
"Branch " + branchIndex+" Size",
"Number of possible actions for the branch number " + branchIndex+"."));
}
EditorGUI.indentLevel--;
}
try
{
BrainParameters parameters = myBrain.brainParameters;
int numberOfDescriptions = 0;
if (parameters.vectorActionSpaceType == SpaceType.continuous)
numberOfDescriptions = parameters.vectorActionSize[0];
else
numberOfDescriptions = parameters.vectorActionSize.Length;
if (parameters.vectorActionDescriptions == null ||
parameters.vectorActionDescriptions.Length != numberOfDescriptions)
parameters.vectorActionDescriptions = new string[numberOfDescriptions];
}
catch
{
}
if (bpVectorActionType.enumValueIndex == 1)
{
//Continuous case :
SerializedProperty bpVectorActionDescription =
serializedBrain.FindProperty("brainParameters.vectorActionDescriptions");
EditorGUILayout.PropertyField(bpVectorActionDescription, new GUIContent(
"Action Descriptions", "A list of strings used to name" +
" the available actions for the Brain."), true);
}
else
{
// Discrete case :
SerializedProperty bpVectorActionDescription =
serializedBrain.FindProperty("brainParameters.vectorActionDescriptions");
EditorGUILayout.PropertyField(bpVectorActionDescription, new GUIContent(
"Branch Descriptions", "A list of strings used to name" +
" the available branches for the Brain."), true);
}
}
EditorGUI.indentLevel = indentLevel;
SerializedProperty bt = serializedBrain.FindProperty("brainType");
EditorGUILayout.PropertyField(bt);
if (bt.enumValueIndex < 0)
var brain = (Brain) target;
var brainToCopy = EditorGUILayout.ObjectField(
"Copy Brain Parameters from : ", null, typeof(Brain), false) as Brain;
if (brainToCopy != null)
bt.enumValueIndex = (int) BrainType.Player;
brain.brainParameters = brainToCopy.brainParameters.Clone();
var serializedBrain = serializedObject;
serializedBrain.Update();
EditorGUILayout.PropertyField(serializedBrain.FindProperty("brainParameters"), true);
myBrain.UpdateCoreBrains();
myBrain.coreBrain.OnInspector();
#if !NET_4_6 && ENABLE_TENSORFLOW
EditorGUILayout.HelpBox ("You cannot have ENABLE_TENSORFLOW without NET_4_6", MessageType.Error);
#endif
// Draws a horizontal thick line
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
}
}

15
UnitySDK/Assets/ML-Agents/Editor/BrainEditor.cs.meta


fileFormatVersion: 2
guid: f1895a43ed0f54ffd9ee06234c4399e7
timeCreated: 1503270350
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: 7b07bebd03994ed08559c725da882b62
timeCreated: 1537834304

175
UnitySDK/Assets/ML-Agents/Editor/ResetParameterDrawer.cs


namespace MLAgents
{
/// <summary>
/// PropertyDrawer for ResetParameters. Defines how ResetParameters are displayed in the
/// Inspector.
/// </summary>
private ResetParameters _Dictionary;
private const float lineHeight = 17f;
private ResetParameters _parameters;
// The height of a line in the Unity Inspectors
private const float LineHeight = 17f;
// This is the prefix for the key when you add a reset parameter
private const string NewKeyPrefix = "Param-";
/// <summary>
/// Computes the height of the Drawer depending on the property it is showing
/// </summary>
/// <param name="property">The property that is being drawn.</param>
/// <param name="label">The label of the property being drawn.</param>
/// <returns>The vertical space needed to draw the property.</returns>
CheckInitialize(property, label);
return (_Dictionary.Count + 2) * lineHeight;
LazyInitializeParameters(property, label);
return (_parameters.Count + 2) * LineHeight;
/// <inheritdoc />
CheckInitialize(property, label);
position.height = lineHeight;
LazyInitializeParameters(property, label);
position.height = LineHeight;
position.y += LineHeight;
var width = position.width / 2 - 24;
var keyRect = new Rect(position.x + 20, position.y, width, position.height);
var valueRect = new Rect(position.x + width + 30, position.y, width, position.height);
DrawAddRemoveButtons(keyRect, valueRect);
foreach (var item in _Dictionary)
foreach (var parameter in _parameters)
var key = item.Key;
var value = item.Value;
position.y += lineHeight;
// This is the rectangle for the key
var keyRect = position;
keyRect.x += 20;
keyRect.width /= 2;
keyRect.width -= 24;
var key = parameter.Key;
var value = parameter.Value;
keyRect.y += LineHeight;
valueRect.y += LineHeight;
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
MarkSceneAsDirty();
_Dictionary.Remove(key);
_Dictionary.Add(newKey, value);
_parameters.Remove(key);
_parameters.Add(newKey, value);
// This is the Rectangle for the value
var valueRect = position;
valueRect.x = position.width / 2 + 15;
valueRect.width = keyRect.width - 18;
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
_Dictionary[key] = value;
MarkSceneAsDirty();
_parameters[key] = value;
EditorGUI.EndProperty();
}
// This is the rectangle for the Add button
position.y += lineHeight;
var AddButtonRect = position;
AddButtonRect.x += 20;
AddButtonRect.width /= 2;
AddButtonRect.width -= 24;
if (GUI.Button(AddButtonRect, new GUIContent("Add New",
"Add a new item to the default reset paramters"), EditorStyles.miniButton))
/// <summary>
/// Draws the Add and Remove buttons.
/// </summary>
/// <param name="addRect">The rectangle for the Add New button.</param>
/// <param name="removeRect">The rectangle for the Remove Last button.</param>
private void DrawAddRemoveButtons(Rect addRect, Rect removeRect)
{
// This is the Add button
if (_parameters.Count == 0)
{
addRect.width *= 2;
}
if (GUI.Button(addRect,
new GUIContent("Add New", "Add a new item to the default reset parameters"),
EditorStyles.miniButton))
{
MarkSceneAsDirty();
AddParameter();
}
// If there are no items in the ResetParameters, Hide the Remove button
if (_parameters.Count == 0)
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
AddNewItem();
return;
// This is the rectangle for the Remove button
var RemoveButtonRect = position;
RemoveButtonRect.x = position.width / 2 + 15;
RemoveButtonRect.width = AddButtonRect.width - 18;
if (GUI.Button(RemoveButtonRect, new GUIContent("Remove Last",
"Remove the last item to the default reset paramters"), EditorStyles.miniButton))
// This is the Remove button
if (GUI.Button(removeRect,
new GUIContent(
"Remove Last", "Remove the last item from the default reset parameters"),
EditorStyles.miniButton))
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
RemoveLastItem();
MarkSceneAsDirty();
RemoveLastParameter();
EditorGUI.EndProperty();
private void CheckInitialize(SerializedProperty property, GUIContent label)
/// <summary>
/// Signals that the property has been modified and requires the scene to be saved for
/// the changes to persist. Only works when the Editor is not playing.
/// </summary>
private static void MarkSceneAsDirty()
if (_Dictionary == null)
if (!EditorApplication.isPlaying)
var target = property.serializedObject.targetObject;
_Dictionary = fieldInfo.GetValue(target) as ResetParameters;
if (_Dictionary == null)
{
_Dictionary = new ResetParameters();
fieldInfo.SetValue(target, _Dictionary);
}
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
private void ClearResetParamters()
/// <summary>
/// Ensures that the state of the Drawer is synchronized with the property.
/// </summary>
/// <param name="property">The SerializedProperty of the ResetParameters
/// to make the custom GUI for.</param>
/// <param name="label">The label of this property.</param>
private void LazyInitializeParameters(SerializedProperty property, GUIContent label)
_Dictionary.Clear();
if (_parameters != null)
{
return;
}
var target = property.serializedObject.targetObject;
_parameters = fieldInfo.GetValue(target) as ResetParameters;
if (_parameters == null)
{
_parameters = new ResetParameters();
fieldInfo.SetValue(target, _parameters);
}
private void RemoveLastItem()
/// <summary>
/// Removes the last ResetParameter from the ResetParameters
/// </summary>
private void RemoveLastParameter()
if (_Dictionary.Count > 0)
if (_parameters.Count > 0)
string key = _Dictionary.Keys.ToList()[_Dictionary.Count - 1];
_Dictionary.Remove(key);
string key = _parameters.Keys.ToList()[_parameters.Count - 1];
_parameters.Remove(key);
private void AddNewItem()
/// <summary>
/// Adds a new ResetParameter to the ResetParameters with a default name.
/// </summary>
private void AddParameter()
string key = "Param-" + _Dictionary.Count.ToString();
string key = NewKeyPrefix + _parameters.Count;
_Dictionary.Add(key, value);
_parameters.Add(key, value);
}
catch (Exception e)
{

2
UnitySDK/Assets/ML-Agents/Editor/Tests/DemonstrationTests.cs


{
vectorObservationSize = 3,
numStackedVectorObservations = 2,
cameraResolutions = new [] {new resolution()},
cameraResolutions = new [] {new Resolution()},
vectorActionDescriptions = new [] {"TestActionA", "TestActionB"},
vectorActionSize = new [] {2, 2},
vectorActionSpaceType = SpaceType.discrete

62
UnitySDK/Assets/ML-Agents/Editor/Tests/MLAgentsEditModeTest.cs


// It is left empty because we are not testing any brain behavior
public class TestBrain : Brain
{
public int numberOfCallsToInitialize = 0;
public int numberOfCallsToDecideAction = 0;
public static TestBrain Instantiate()
{
return CreateInstance<TestBrain>();
}
protected override void Initialize()
{
numberOfCallsToInitialize++;
}
protected override void DecideAction()
{
base.DecideAction();
numberOfCallsToDecideAction++;
agentInfos.Clear();
}
}

public class EditModeTestInitialization
{
private Brain GenerateTestBrain()
{
return ScriptableObject.CreateInstance<TestBrain>();
}
[Test]
public void TestAcademy()
{

GameObject acaGO = new GameObject("TestAcademy");
acaGO.AddComponent<TestAcademy>();
TestAcademy aca = acaGO.GetComponent<TestAcademy>();
GameObject brainGO = new GameObject("TestBrain");
brainGO.transform.parent = acaGO.transform;
brainGO.AddComponent<TestBrain>();
TestBrain brain = brainGO.GetComponent<TestBrain>();
TestBrain brain = TestBrain.Instantiate();
brain.brainParameters = new BrainParameters();
brain.brainParameters.vectorObservationSize = 0;
agent1.GiveBrain(brain);

GameObject acaGO = new GameObject("TestAcademy");
acaGO.AddComponent<TestAcademy>();
TestAcademy aca = acaGO.GetComponent<TestAcademy>();
GameObject brainGO = new GameObject("TestBrain");
brainGO.transform.parent = acaGO.transform;
brainGO.AddComponent<TestBrain>();
TestBrain brain = brainGO.GetComponent<TestBrain>();
TestBrain brain = TestBrain.Instantiate();
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod(

agent2.agentParameters.onDemandDecision = true;
// agent2 will request decisions only when RequestDecision is called
brain.brainParameters.vectorObservationSize = 0;
brain.brainParameters.cameraResolutions = new resolution[0];
brain.brainParameters.cameraResolutions = new Resolution[0];
agent1.GiveBrain(brain);
agent2.GiveBrain(brain);

GameObject acaGO = new GameObject("TestAcademy");
acaGO.AddComponent<TestAcademy>();
TestAcademy aca = acaGO.GetComponent<TestAcademy>();
GameObject brainGO = new GameObject("TestBrain");
brainGO.transform.parent = acaGO.transform;
brainGO.AddComponent<TestBrain>();
TestBrain brain = brainGO.GetComponent<TestBrain>();
TestBrain brain = TestBrain.Instantiate();
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod(

agent2.agentParameters.onDemandDecision = true;
// agent2 will request decisions only when RequestDecision is called
brain.brainParameters.vectorObservationSize = 0;
brain.brainParameters.cameraResolutions = new resolution[0];
brain.brainParameters.cameraResolutions = new Resolution[0];
agent1.GiveBrain(brain);
agent2.GiveBrain(brain);

GameObject acaGO = new GameObject("TestAcademy");
acaGO.AddComponent<TestAcademy>();
TestAcademy aca = acaGO.GetComponent<TestAcademy>();
GameObject brainGO = new GameObject("TestBrain");
brainGO.transform.parent = acaGO.transform;
brainGO.AddComponent<TestBrain>();
TestBrain brain = brainGO.GetComponent<TestBrain>();
TestBrain brain = TestBrain.Instantiate();
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod(

agent1.agentParameters.maxStep = 20;
agent2.agentParameters.maxStep = 30;
brain.brainParameters.vectorObservationSize = 0;
brain.brainParameters.cameraResolutions = new resolution[0];
brain.brainParameters.cameraResolutions = new Resolution[0];
agent1.GiveBrain(brain);
agent2.GiveBrain(brain);

GameObject acaGO = new GameObject("TestAcademy");
acaGO.AddComponent<TestAcademy>();
TestAcademy aca = acaGO.GetComponent<TestAcademy>();
GameObject brainGO = new GameObject("TestBrain");
brainGO.transform.parent = acaGO.transform;
brainGO.AddComponent<TestBrain>();
TestBrain brain = brainGO.GetComponent<TestBrain>();
TestBrain brain = TestBrain.Instantiate();
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod(

agent1.agentParameters.resetOnDone = false;
agent2.agentParameters.resetOnDone = false;
brain.brainParameters.vectorObservationSize = 0;
brain.brainParameters.cameraResolutions = new resolution[0];
brain.brainParameters.cameraResolutions = new Resolution[0];
agent1.GiveBrain(brain);
agent2.GiveBrain(brain);

GameObject acaGO = new GameObject("TestAcademy");
acaGO.AddComponent<TestAcademy>();
TestAcademy aca = acaGO.GetComponent<TestAcademy>();
GameObject brainGO = new GameObject("TestBrain");
brainGO.transform.parent = acaGO.transform;
brainGO.AddComponent<TestBrain>();
TestBrain brain = brainGO.GetComponent<TestBrain>();
TestBrain brain = TestBrain.Instantiate();
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod(

// agent2 will request decisions only when RequestDecision is called
agent1.agentParameters.maxStep = 20;
brain.brainParameters.vectorObservationSize = 0;
brain.brainParameters.cameraResolutions = new resolution[0];
brain.brainParameters.cameraResolutions = new Resolution[0];
agent1.GiveBrain(brain);
agent2.GiveBrain(brain);

5
UnitySDK/Assets/ML-Agents/Examples/3DBall/Prefabs/Game.prefab


m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: e35c6159207d7448e988c8cf0c137ab6, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2}
m_StaticBatchInfo:

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: edd958d75ed1448138de86f3335ea4fa, type: 2}
m_StaticBatchInfo:

m_Script: {fileID: 11500000, guid: aaba48bf82bee4751aa7b89569e57f73, type: 3}
m_Name:
m_EditorClassIdentifier:
brain: {fileID: 0}
brain: {fileID: 11400000, guid: 97d8f9d40dc8c452f932f7caa9549c7d, type: 2}
agentParameters:
agentCameras: []
maxStep: 5000

279
UnitySDK/Assets/ML-Agents/Examples/3DBall/Scenes/3DBall.unity


--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
serializedVersion: 8
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3

m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44824862, g: 0.49827534, b: 0.57558274, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0

m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 10
serializedVersion: 9
m_AtlasSize: 1024
m_TextureWidth: 1024
m_TextureHeight: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1

propertyPath: m_Name
value: Game12
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: ball
value:
objectReference: {fileID: 174802794}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
m_IsPrefabParent: 0

propertyPath: m_Name
value: Game22
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
--- !u!114 &157026687
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 35813a1be64e144f887d7d5f15b963fa, type: 3}
m_Name: (Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)
m_EditorClassIdentifier:
brain: {fileID: 667765197}
--- !u!1001 &159612743
Prefab:
m_ObjectHideFlags: 0

propertyPath: m_Name
value: Game31
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
--- !u!1 &174802794 stripped
GameObject:
m_PrefabParentObject: {fileID: 1536511242562482, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
m_PrefabInternal: {fileID: 119733639}
--- !u!1001 &292233615
Prefab:
m_ObjectHideFlags: 0

propertyPath: m_Name
value: Game13
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
m_IsPrefabParent: 0

propertyPath: m_Name
value: Game21
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
m_IsPrefabParent: 0

propertyPath: m_Name
value: Game23
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
m_IsPrefabParent: 0

m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RenderingLayerMask: 4294967295
m_Materials:
- {fileID: 2100000, guid: ea4e6e61f90ae46daaf643b945c080ed, type: 2}
m_StaticBatchInfo:

m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &548284581
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 41e9bda8f3cf1492fa74926a530f6f70, type: 3}
m_Name: (Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)
m_EditorClassIdentifier:
broadcast: 1
keyContinuousPlayerActions:
- key: 273
index: 1
value: 1
- key: 274
index: 1
value: -1
- key: 275
index: 0
value: -1
- key: 276
index: 0
value: 1
axisContinuousPlayerActions: []
discretePlayerActions: []
brain: {fileID: 667765197}
--- !u!114 &667765197
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 114938382745838118, guid: 00a1ebe742cf2394d8c21484e3a02412,
type: 2}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1456409882}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c676a8ddf5a5f4f64b35e9ed5028679d, type: 3}
m_Name:
m_EditorClassIdentifier:
brainParameters:
vectorObservationSize: 8
numStackedVectorObservations: 1
vectorActionSize: 02000000
test: 010000000200000003000000
cameraResolutions: []
vectorActionDescriptions:
-
-
vectorActionSpaceType: 1
brainType: 0
CoreBrains:
- {fileID: 548284581}
- {fileID: 1806797620}
- {fileID: 157026687}
- {fileID: 1159453570}
instanceID: 98474
--- !u!1001 &764818074
Prefab:
m_ObjectHideFlags: 0

propertyPath: m_Name
value: Game32
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
m_IsPrefabParent: 0

propertyPath: m_Name
value: Game34
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
--- !u!114 &1159453570
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8b23992c8eb17439887f5e944bf04a40, type: 3}
m_Name: (Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)
m_EditorClassIdentifier:
broadcast: 1
graphModel: {fileID: 4900000, guid: 93f91f35982184949a09d9ce97965cd5, type: 3}
graphScope:
graphPlaceholders: []
BatchSizePlaceholderName: batch_size
VectorObservationPlacholderName: vector_observation
RecurrentInPlaceholderName: recurrent_in
RecurrentOutPlaceholderName: recurrent_out
VisualObservationPlaceholderName: []
ActionPlaceholderName: action
PreviousActionPlaceholderName: prev_action
brain: {fileID: 667765197}
--- !u!1001 &1318922267
Prefab:
m_ObjectHideFlags: 0

propertyPath: m_RootOrder
value: 5
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_Name
value: Game11

propertyPath: m_Name
value: Game33
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
--- !u!1 &1456409882
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 1518777817328868, guid: 00a1ebe742cf2394d8c21484e3a02412,
type: 2}
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1456409884}
- component: {fileID: 667765197}
- component: {fileID: 1456409883}
m_Layer: 0
m_Name: Ball3DBrain
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1456409883
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 114933696884682882, guid: 00a1ebe742cf2394d8c21484e3a02412,
type: 2}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1456409882}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ccaa8f43c15264209b137d8dc26a8d63, type: 3}
m_Name:
m_EditorClassIdentifier:
rotationSpeed: 2
--- !u!4 &1456409884
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 4244963715435272, guid: 00a1ebe742cf2394d8c21484e3a02412,
type: 2}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1456409882}
m_LocalRotation: {x: -0, y: -0, z: 0.00000000273576, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1583402088}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1583402087
GameObject:
m_ObjectHideFlags: 0

m_LocalRotation: {x: -0.069583125, y: 0.0049145464, z: 0.0702813, w: 0.99508524}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 5, y: 0.19999993, z: 5}
m_Children:
- {fileID: 1456409884}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

m_Script: {fileID: 11500000, guid: eb15e3c3d55e54abaafb74c635b6a458, type: 3}
m_Name:
m_EditorClassIdentifier:
broadcastHub:
broadcastingBrains: []
_brainsToControl: []
maxSteps: 0
trainingConfiguration:
width: 600

propertyPath: m_Name
value: Game24
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
--- !u!114 &1806797620
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 943466ab374444748a364f9d6c3e2fe2, type: 3}
m_Name: (Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)(Clone)
m_EditorClassIdentifier:
broadcast: 1
brain: {fileID: 667765197}
--- !u!1001 &1825513289
Prefab:
m_ObjectHideFlags: 0

- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_Name
value: Game14
objectReference: {fileID: 0}
- target: {fileID: 114980646877373948, guid: ff026d63a00abdc48ad6ddcff89aba04,
type: 2}
propertyPath: brain
value:
objectReference: {fileID: 667765197}
- target: {fileID: 1665577603478558, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: ff026d63a00abdc48ad6ddcff89aba04, type: 2}

9
UnitySDK/Assets/ML-Agents/Examples/3DBall/Scripts/Ball3DDecision.cs


using UnityEngine;
using MLAgents;
public class Ball3DDecision : MonoBehaviour, Decision
public class Ball3DDecision : Decision
public float[] Decide(
public override float[] Decide(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

if (gameObject.GetComponent<Brain>().brainParameters.vectorActionSpaceType
== SpaceType.continuous)
if (brainParameters.vectorActionSpaceType == SpaceType.continuous)
{
List<float> act = new List<float>();

return new float[1] { 1f };
}
public List<float> MakeMemory(
public override List<float> MakeMemory(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

6
UnitySDK/Assets/ML-Agents/Examples/Basic/Scripts/BasicDecision.cs


using UnityEngine;
using MLAgents;
public class BasicDecision : MonoBehaviour, Decision
public class BasicDecision : Decision
public float[] Decide(
public override float[] Decide(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

return new float[1] { 1f };
}
public List<float> MakeMemory(
public override List<float> MakeMemory(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

6
UnitySDK/Assets/ML-Agents/Examples/Reacher/Scripts/ReacherDecision.cs


using UnityEngine;
using MLAgents;
public class ReacherDecision : MonoBehaviour, Decision {
public class ReacherDecision : Decision {
public float[] Decide (List<float> state, List<Texture2D> observation, float reward, bool done, List<float> memory)
public override float[] Decide (List<float> state, List<Texture2D> observation, float reward, bool done, List<float> memory)
{
float[] action = new float[4];
for (int i = 0; i < 4; i++) {

}
public List<float> MakeMemory (List<float> state, List<Texture2D> observation, float reward, bool done, List<float> memory)
public override List<float> MakeMemory (List<float> state, List<Texture2D> observation, float reward, bool done, List<float> memory)
{
return new List<float>();

17
UnitySDK/Assets/ML-Agents/Examples/SharedAssets/Scripts/RandomDecision.cs


namespace MLAgents
{
public class RandomDecision : MonoBehaviour, Decision
public class RandomDecision : Decision
BrainParameters brainParameters;
SpaceType actionSpaceType;
public void Awake()
{
brainParameters =
gameObject.GetComponent<Brain>().brainParameters;
actionSpaceType = brainParameters.vectorActionSpaceType;
}
public float[] Decide(
public override float[] Decide(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

if (actionSpaceType == SpaceType.continuous)
if (brainParameters.vectorActionSpaceType == SpaceType.continuous)
{
List<float> act = new List<float>();

}
}
public List<float> MakeMemory(
public override List<float> MakeMemory(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

6
UnitySDK/Assets/ML-Agents/Examples/Template/Scripts/TemplateDecision.cs


using UnityEngine;
using MLAgents;
public class TemplateDecision : MonoBehaviour, Decision
public class TemplateDecision : Decision
public float[] Decide(
public override float[] Decide(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

return new float[0];
}
public List<float> MakeMemory(
public override List<float> MakeMemory(
List<float> vectorObs,
List<Texture2D> visualObs,
float reward,

73
UnitySDK/Assets/ML-Agents/Scripts/Academy.cs


"docs/Learning-Environment-Design-Academy.md")]
public abstract class Academy : MonoBehaviour
{
[SerializeField]
public BroadcastHub broadcastHub = new BroadcastHub();
private const string kApiVersion = "API-5";
// Fields provided in the Inspector

/// </summary>
private void InitializeEnvironment()
{
// Retrieve Brain and initialize Academy
var brains = GetBrains(gameObject);
MLAgents.Communicator communicator = null;
Communicator communicator = null;
var exposedBrains = broadcastHub.broadcastingBrains.Where(x => x != null).ToList();;
var controlledBrains = broadcastHub.broadcastingBrains.Where(
x => x != null && x is LearningBrain && broadcastHub.IsControlled(x));
foreach (LearningBrain brain in controlledBrains)
{
brain.SetToControlledExternally();
}
communicator = new MLAgents.RPCCommunicator(
new MLAgents.CommunicatorParameters
communicator = new RPCCommunicator(
new CommunicatorParameters
{
port = ReadArgs()
});

catch
{
communicator = null;
var externalBrain = brains.FirstOrDefault(b => b.brainType == BrainType.External);
if (externalBrain != null)
if (controlledBrains.ToList().Count > 0)
communicator = new MLAgents.RPCCommunicator(
new MLAgents.CommunicatorParameters
communicator = new RPCCommunicator(
new CommunicatorParameters
{
port = 5005
});

brainBatcher = new Batcher(communicator);
// Initialize Brains and communicator (if present)
foreach (var brain in brains)
foreach (var trainingBrain in exposedBrains)
brain.InitializeBrain(this, brainBatcher);
trainingBrain.SetBatcher(brainBatcher);
}
if (communicator != null)

new CommunicatorObjects.UnityRLInitializationOutput();
academyParameters.Name = gameObject.name;
academyParameters.Version = kApiVersion;
foreach (var brain in brains)
foreach (var brain in exposedBrains)
bp.ToProto(
brain.gameObject.name,
(CommunicatorObjects.BrainTypeProto)
brain.brainType));
bp.ToProto(brain.name, broadcastHub.IsControlled(brain)));
new MLAgents.CommunicatorObjects.EnvironmentParametersProto();
new CommunicatorObjects.EnvironmentParametersProto();
foreach (var key in resetParameters.Keys)
{
academyParameters.EnvironmentParameters.FloatParameters.Add(

{
lastCommunicatorMessageNumber = brainBatcher.GetNumberMessageReceived();
if (brainBatcher.GetCommand() ==
MLAgents.CommunicatorObjects.CommandProto.Reset)
CommunicatorObjects.CommandProto.Reset)
{
UpdateResetParameters();

}
if (brainBatcher.GetCommand() ==
MLAgents.CommunicatorObjects.CommandProto.Quit)
CommunicatorObjects.CommandProto.Quit)
{
#if UNITY_EDITOR
EditorApplication.isPlaying = false;

void FixedUpdate()
{
EnvironmentStep();
}
/// <summary>
/// Helper method that retrieves the Brain objects that are currently
/// specified as children of the Academy within the Editor.
/// </summary>
/// <param name="academy">Academy.</param>
/// <returns>
/// List of brains currently attached to academy.
/// </returns>
static List<Brain> GetBrains(GameObject academy)
{
List<Brain> brains = new List<Brain>();
var transform = academy.transform;
for (var i = 0; i < transform.childCount; i++)
{
var child = transform.GetChild(i);
var brain = child.GetComponent<Brain>();
if (brain != null && child.gameObject.activeSelf)
{
brains.Add(brain);
}
}
return brains;
}
}
}

21
UnitySDK/Assets/ML-Agents/Scripts/ActionMasker.cs


// indices for each branch.
if (_startingActionIndices == null)
{
_startingActionIndices = CreateActionStartinIndices();
_startingActionIndices = Utilities.CumSum(_brainParameters.vectorActionSize);
}
// Perform the masking

{
Array.Clear(_currentMask, 0, _currentMask.Length);
}
}
/// <summary>
/// Generates an array containing the starting indicies of each branch in the vector action
/// Makes a cumulative sum.
/// </summary>
/// <returns></returns>
private int[] CreateActionStartinIndices()
{
var vectorActionSize = _brainParameters.vectorActionSize;
var runningSum = 0;
var result = new int[vectorActionSize.Length + 1];
for (var actionIndex = 0;
actionIndex < vectorActionSize.Length; actionIndex++)
{
runningSum += vectorActionSize[actionIndex];
result[actionIndex + 1] = runningSum;
}
return result;
}
/// <summary>

4
UnitySDK/Assets/ML-Agents/Scripts/Agent.cs


"Vector Observation size mismatch between continuous " +
"agent {0} and brain {1}. " +
"Was Expecting {2} but received {3}. ",
gameObject.name, brain.gameObject.name,
gameObject.name, brain.name,
brain.brainParameters.vectorObservationSize,
info.vectorObservation.Count));
}

throw new UnityAgentsException(string.Format(
"Not enough cameras for agent {0} : Bain {1} expecting at " +
"least {2} cameras but only {3} were present.",
gameObject.name, brain.gameObject.name,
gameObject.name, brain.name,
brain.brainParameters.cameraResolutions.Length,
agentParameters.agentCameras.Count));
}

2
UnitySDK/Assets/ML-Agents/Scripts/Batcher.cs


/// Is used by the academy to send the AcademyParameters to the communicator.
/// </summary>
/// <returns>The External Initialization Parameters received.</returns>
/// <param name="academyParameters">The Unity Initialization Paramters to be sent.</param>
/// <param name="academyParameters">The Unity Initialization Parameters to be sent.</param>
public CommunicatorObjects.UnityRLInitializationInput SendAcademyParameters(
CommunicatorObjects.UnityRLInitializationOutput academyParameters)
{

315
UnitySDK/Assets/ML-Agents/Scripts/Brain.cs


using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine.UI;
using System.Linq;
// Class contains all necessary environment parameters
// to be defined and sent to external agent
public enum BrainType
{
Player,
Heuristic,
External,
Internal
}
public enum SpaceType
/// <summary>
/// Brain receive data from Agents through calls to SendState. The brain then updates the
/// actions of the agents at each FixedUpdate.
/// The Brain encapsulates the decision making process. Every Agent must be assigned a Brain,
/// but you can use the same Brain with more than one Agent. You can also create several
/// Brains, attach each of the Brain to one or more than one Agent.
/// Brain assets has several important properties that you can set using the Inspector window.
/// These properties must be appropriate for the Agents using the Brain. For example, the
/// Vector Observation Space Size property must match the length of the feature
/// vector created by an Agent exactly.
/// </summary>
public abstract class Brain : ScriptableObject
discrete,
continuous
};
[SerializeField] public BrainParameters brainParameters;
protected Dictionary<Agent, AgentInfo> agentInfos =
new Dictionary<Agent, AgentInfo>(1024);
protected Batcher brainBatcher;
/** Only need to be modified in the brain's inpector.
* Defines what is the resolution of the camera
*/
[System.Serializable]
public struct resolution
{
public int width;
/**< \brief The width of the observation in pixels */
public int height;
/**< \brief The height of the observation in pixels */
public bool blackAndWhite;
/**< \brief If true, the image will be in black and white.
* If false, it will be in colors RGB */
}
/** Should be modified via the Editor Inspector.
* Defines brain-specific parameters
*/
[System.Serializable]
public class BrainParameters
{
public int vectorObservationSize = 1;
/**< \brief If continuous : The length of the float vector that represents
* the state
* <br> If discrete : The number of possible values the state can take*/
[Range(1, 50)] public int numStackedVectorObservations = 1;
public int[] vectorActionSize = new int[1]{1};
/**< \brief If continuous : The length of the float vector that represents
* the action
* <br> If discrete : The number of possible values the action can take*/
public resolution[] cameraResolutions;
/**<\brief The list of observation resolutions for the brain */
public string[] vectorActionDescriptions;
/**< \brief The list of strings describing what the actions correpond to */
[System.NonSerialized]
private bool _isInitialized;
public SpaceType vectorActionSpaceType = SpaceType.discrete;
/**< \brief Defines if the action is discrete or continuous */
/// Converts a Brain into to a Protobuff BrainInfoProto so it can be sent
/// Sets the Batcher of the Brain. The brain will call the batcher at every step and give
/// it the agent's data using SendBrainInfo at each DecideAction call.
/// <returns>The BrainInfoProto generated.</returns>
/// <param name="name">The name of the brain.</param>
/// <param name="type">The type of brain.</param>
public CommunicatorObjects.BrainParametersProto
ToProto(string name, CommunicatorObjects.BrainTypeProto type)
/// <param name="batcher"> The Batcher the brain will use for the current session</param>
public void SetBatcher(Batcher batcher)
var brainParametersProto = new CommunicatorObjects.BrainParametersProto
{
VectorObservationSize = vectorObservationSize,
NumStackedVectorObservations = numStackedVectorObservations,
VectorActionSize = {vectorActionSize},
VectorActionSpaceType =
(CommunicatorObjects.SpaceTypeProto)vectorActionSpaceType,
BrainName = name,
BrainType = type
};
brainParametersProto.VectorActionDescriptions.AddRange(vectorActionDescriptions);
foreach (resolution res in cameraResolutions)
if (batcher == null)
brainParametersProto.CameraResolutions.Add(
new CommunicatorObjects.ResolutionProto
{