浏览代码

Merge branch 'main' into develop-soccer-groupman-mod

/develop/soccer-groupman/mod
Andrew Cohen 3 年前
当前提交
18be47e8
共有 323 个文件被更改,包括 1069 次插入652 次删除
  1. 1
      .github/workflows/pre-commit.yml
  2. 3
      .gitignore
  3. 7
      .pre-commit-config.yaml
  4. 2
      .yamato/com.unity.ml-agents-pack.yml
  5. 14
      .yamato/com.unity.ml-agents-test.yml
  6. 8
      .yamato/pytest-gpu.yml
  7. 6
      .yamato/test_versions.metafile
  8. 2
      DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Editor.asmdef
  9. 1
      DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs
  10. 2
      DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef
  11. 15
      DevProject/Packages/manifest.json
  12. 51
      DevProject/Packages/packages-lock.json
  13. 4
      DevProject/ProjectSettings/EditorBuildSettings.asset
  14. 18
      DevProject/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json
  15. 4
      DevProject/ProjectSettings/ProjectVersion.txt
  16. 3
      Project/Assets/ML-Agents/Editor/Tests/SampleExporter.cs
  17. 7
      Project/Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBall.demo.meta
  18. 7
      Project/Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBallHard.demo.meta
  19. 7
      Project/Assets/ML-Agents/Examples/Basic/Demos/ExpertBasic.demo.meta
  20. 6
      Project/Assets/ML-Agents/Examples/Basic/Scripts/BasicActuatorComponent.cs
  21. 4
      Project/Assets/ML-Agents/Examples/Basic/Scripts/BasicSensorComponent.cs
  22. 7
      Project/Assets/ML-Agents/Examples/Crawler/Demos/ExpertCrawler.demo.meta
  23. 7
      Project/Assets/ML-Agents/Examples/GridWorld/Demos/ExpertGridWorld.demo.meta
  24. 8
      Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs
  25. 7
      Project/Assets/ML-Agents/Examples/Hallway/Demos/ExpertHallway.demo.meta
  26. 6
      Project/Assets/ML-Agents/Examples/Match3/Scripts/Match3ExampleActuatorComponent.cs
  27. 7
      Project/Assets/ML-Agents/Examples/PushBlock/Demos/ExpertPushBlock.demo.meta
  28. 7
      Project/Assets/ML-Agents/Examples/Pyramids/Demos/ExpertPyramid.demo.meta
  29. 2
      Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/CollisionCallbacks.cs.meta
  30. 2
      Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/SensorBase.cs
  31. 2
      Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs
  32. 2
      Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerEnvController.cs
  33. 7
      Project/Assets/ML-Agents/Examples/Walker/Demos/ExpertWalker.demo.meta
  34. 8
      Project/Assets/ML-Agents/TestScenes/TestCompressedTexture/TestTextureSensor.cs
  35. 24
      Project/Packages/manifest.json
  36. 16
      Project/ProjectSettings/EditorSettings.asset
  37. 3
      Project/ProjectSettings/ProjectVersion.txt
  38. 19
      README.md
  39. 2
      com.unity.ml-agents.extensions/Documentation~/Grid-Sensor.md
  40. 2
      com.unity.ml-agents.extensions/Documentation~/Match3.md
  41. 24
      com.unity.ml-agents.extensions/Documentation~/com.unity.ml-agents.extensions.md
  42. 4
      com.unity.ml-agents.extensions/Editor/Input/InputActuatorComponentEditor.cs
  43. 1
      com.unity.ml-agents.extensions/Runtime/AssemblyInfo.cs
  44. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs
  45. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs
  46. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs
  47. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs
  48. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs
  49. 4
      com.unity.ml-agents.extensions/Runtime/Input/IInputActionAssetProvider.cs
  50. 4
      com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs
  51. 6
      com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs
  52. 9
      com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs
  53. 4
      com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs
  54. 69
      com.unity.ml-agents.extensions/Runtime/Match3/Match3Actuator.cs
  55. 6
      com.unity.ml-agents.extensions/Runtime/Match3/Match3ActuatorComponent.cs
  56. 12
      com.unity.ml-agents.extensions/Runtime/Match3/Match3Sensor.cs
  57. 30
      com.unity.ml-agents.extensions/Runtime/Sensors/GridSensor.cs
  58. 10
      com.unity.ml-agents.extensions/Runtime/Sensors/PhysicsBodySensor.cs
  59. 12
      com.unity.ml-agents.extensions/Tests/Editor/Match3/Match3SensorTests.cs
  60. 8
      com.unity.ml-agents.extensions/Tests/Editor/Sensors/ChannelHotShapeTests.cs
  61. 6
      com.unity.ml-agents.extensions/Tests/Editor/Sensors/ChannelShapeTests.cs
  62. 1
      com.unity.ml-agents.extensions/Tests/Editor/Unity.ML-Agents.Extensions.EditorTests.asmdef
  63. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs
  64. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs
  65. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs
  66. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs
  67. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs
  68. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs
  69. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/TestPushBlockActions.cs
  70. 3
      com.unity.ml-agents.extensions/Tests/Runtime/Unity.ML-Agents.Extensions.Tests.asmdef
  71. 6
      com.unity.ml-agents.extensions/package.json
  72. 24
      com.unity.ml-agents/CHANGELOG.md
  73. 12
      com.unity.ml-agents/CONTRIBUTING.md
  74. 6
      com.unity.ml-agents/Documentation~/com.unity.ml-agents.md
  75. 16
      com.unity.ml-agents/Editor/BehaviorParametersEditor.cs
  76. 8
      com.unity.ml-agents/Runtime/Academy.cs
  77. 14
      com.unity.ml-agents/Runtime/Actuators/ActuatorComponent.cs
  78. 29
      com.unity.ml-agents/Runtime/Actuators/ActuatorDiscreteActionMask.cs
  79. 4
      com.unity.ml-agents/Runtime/Actuators/ActuatorManager.cs
  80. 45
      com.unity.ml-agents/Runtime/Actuators/IActionReceiver.cs
  81. 2
      com.unity.ml-agents/Runtime/Actuators/IActuator.cs
  82. 26
      com.unity.ml-agents/Runtime/Actuators/IDiscreteActionMask.cs
  83. 2
      com.unity.ml-agents/Runtime/Actuators/VectorActuator.cs
  84. 109
      com.unity.ml-agents/Runtime/Agent.cs
  85. 7
      com.unity.ml-agents/Runtime/Analytics/Events.cs
  86. 26
      com.unity.ml-agents/Runtime/Analytics/InferenceAnalytics.cs
  87. 34
      com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs
  88. 5
      com.unity.ml-agents/Runtime/AssemblyInfo.cs
  89. 62
      com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs
  90. 4
      com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
  91. 2
      com.unity.ml-agents/Runtime/Demonstrations/DemonstrationRecorder.cs
  92. 2
      com.unity.ml-agents/Runtime/Grpc/AssemblyInfo.cs
  93. 2
      com.unity.ml-agents/Runtime/IMultiAgentGroup.cs
  94. 44
      com.unity.ml-agents/Runtime/Inference/ApplierImpl.cs
  95. 70
      com.unity.ml-agents/Runtime/Inference/BarracudaModelExtensions.cs
  96. 472
      com.unity.ml-agents/Runtime/Inference/BarracudaModelParamLoader.cs
  97. 10
      com.unity.ml-agents/Runtime/Inference/TensorApplier.cs
  98. 93
      com.unity.ml-agents/Runtime/Inference/TensorGenerator.cs
  99. 12
      com.unity.ml-agents/Runtime/Policies/BrainParameters.cs
  100. 2
      com.unity.ml-agents/Runtime/Policies/HeuristicPolicy.cs

1
.github/workflows/pre-commit.yml


- uses: actions/setup-dotnet@v1
with:
dotnet-version: '3.1.x'
- run: dotnet tool install -g dotnet-format --version 4.1.131201
- uses: pre-commit/action@v2.0.0
markdown-link-check:

3
.gitignore


# Environemnt logfile
*Project.log
# Custom settings asset
*.settings.asset*
# Visual Studio 2015 cache directory
/Project/.vs/

7
.pre-commit-config.yaml


types: [markdown]
exclude: ".*localized.*"
- repo: https://github.com/dotnet/format
rev: "7e343070a0355c86f72bdee226b5e19ffcbac931" # TODO - update to a tagged version when one that includes the hook is ready.
hooks:
- id: dotnet-format
args: [--folder, --include]
# "Local" hooks, see https://pre-commit.com/#repository-local-hooks
- repo: local
hooks:

name: validate release links
language: script
entry: utils/validate_release_links.py

2
.yamato/com.unity.ml-agents-pack.yml


commands:
- |
python3 -m pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade
unity-downloader-cli -u 2018.4 -c editor --wait --fast
unity-downloader-cli -u 2019.4 -c editor --wait --fast
./.Editor/Unity -projectPath Project -batchMode -executeMethod Unity.MLAgents.SampleExporter.ExportCuratedSamples -logFile -
npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
upm-ci project pack --project-path Project

14
.yamato/com.unity.ml-agents-test.yml


test_editors:
- version: 2018.4
# 2018.4 doesn't support code-coverage
enableCodeCoverage: !!bool false
# We want some scene tests to run in the DevProject, but packages there only support 2019+
- version: 2019.4
enableCodeCoverage: !!bool true
# We want some scene tests to run in the DevProject, but packages there only support 2020+
enableNoDefaultPackages: !!bool false
- version: 2019.4
enableNoDefaultPackages: !!bool true
- version: 2020.2
- version: 2020.2
- version: 2021.1
enableCodeCoverage: !!bool true
testProject: DevProject
enableNoDefaultPackages: !!bool true

{% endfor %}
{% endfor %}
{% endfor %}

8
.yamato/pytest-gpu.yml


python3 -m pytest -m "not check_environment_trains" --junitxml=junit/test-results.xml -p no:warnings
triggers:
cancel_old_ci: true
recurring:
- branch: main
frequency: daily
expression: |
(push.branch eq "main" OR
push.branch match "release.+") AND
push.changes.any match "ml-agents/**" AND
NOT push.changes.all match "**/*.md"
artifacts:
logs:
paths:

6
.yamato/test_versions.metafile


# For each "other" test, we only run it against a single version of the
# editor to reduce the number of yamato jobs
test_editors:
- version: 2018.4
extra_test: llapi
- version: 2020.2
- version: 2020.3
- version: 2021.1
extra_test: llapi

2
DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Editor.asmdef


{
"name": "Unity.ML-Agents.Performance.Tests",
"name": "Unity.ML-Agents.DevTests.Editor",
"references": [
"Unity.ML-Agents.Editor",
"Unity.ML-Agents",

1
DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs


[SetUp]
public void Setup()
{
Academy.Instance.Dispose();
SceneManager.LoadScene("ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene");
}

2
DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef


{
"name": "Runtime",
"name": "Unity.ML-Agents.DevTests.Runtime",
"references": [
"Unity.ML-Agents"
],

15
DevProject/Packages/manifest.json


"com.unity.2d.sprite": "1.0.0",
"com.unity.2d.tilemap": "1.0.0",
"com.unity.ads": "3.6.1",
"com.unity.analytics": "3.3.5",
"com.unity.analytics": "3.5.3",
"com.unity.collab-proxy": "1.2.16",
"com.unity.ide.rider": "1.1.4",
"com.unity.collab-proxy": "1.3.9",
"com.unity.ide.rider": "2.0.7",
"com.unity.ide.visualstudio": "2.0.7",
"com.unity.ide.vscode": "1.2.3",
"com.unity.inputsystem": "1.1.0-preview.3",
"com.unity.ml-agents": "file:../../com.unity.ml-agents",

"com.unity.package-validation-suite": "0.19.0-preview",
"com.unity.purchasing": "2.2.1",
"com.unity.test-framework": "1.1.20",
"com.unity.purchasing": "2.2.2",
"com.unity.test-framework": "1.1.22",
"com.unity.textmeshpro": "2.0.1",
"com.unity.timeline": "1.2.12",
"com.unity.textmeshpro": "3.0.1",
"com.unity.timeline": "1.4.6",
"com.unity.ugui": "1.0.0",
"com.unity.xr.legacyinputhelpers": "2.1.7",
"com.unity.modules.ai": "1.0.0",

51
DevProject/Packages/packages-lock.json


"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.analytics": {
"version": "3.3.5",
"version": "3.5.3",
"depth": 0,
"source": "registry",
"dependencies": {

},
"com.unity.barracuda": {
"version": "1.3.1-preview",
"version": "1.3.2-preview",
"depth": 1,
"source": "registry",
"dependencies": {

"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.collab-proxy": {
"version": "1.2.16",
"version": "1.3.9",
"depth": 0,
"source": "registry",
"dependencies": {},

"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.ide.rider": {
"version": "1.1.4",
"version": "2.0.7",
"depth": 0,
"source": "registry",
"dependencies": {

},
"com.unity.ide.visualstudio": {
"version": "2.0.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.9"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.ide.vscode": {
"version": "1.2.3",
"depth": 0,

"depth": 0,
"source": "local",
"dependencies": {
"com.unity.barracuda": "1.3.1-preview",
"com.unity.barracuda": "1.3.2-preview",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0"
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.ml-agents.extensions": {

"dependencies": {
"com.unity.ml-agents": "1.8.0-preview"
"com.unity.ml-agents": "2.0.0-exp.1"
}
},
"com.unity.multiplayer-hlapi": {

"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.purchasing": {
"version": "2.2.1",
"version": "2.2.2",
"depth": 0,
"source": "registry",
"dependencies": {

"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.test-framework": {
"version": "1.1.20",
"version": "1.1.22",
"depth": 0,
"source": "registry",
"dependencies": {

"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.textmeshpro": {
"version": "2.0.1",
"version": "3.0.1",
"depth": 0,
"source": "registry",
"dependencies": {

},
"com.unity.timeline": {
"version": "1.2.12",
"version": "1.4.6",
"dependencies": {},
"dependencies": {
"com.unity.modules.director": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.ugui": {

"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.uielementsnative": "1.0.0"
}
},
"com.unity.modules.uielementsnative": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}

4
DevProject/ProjectSettings/EditorBuildSettings.asset


- enabled: 1
path: Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity
guid: 9bafc50b1e55b43b2b1ae9620f1f8311
m_configObjects: {}
m_configObjects:
com.unity.ml-agents.settings: {fileID: 11400000, guid: 7017f4eb06bef4889a3608a54b1cc59e,
type: 2}

18
DevProject/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json


"m_Name": "Settings",
"m_Path": "ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json",
"m_Dictionary": {
"m_DictionaryValues": []
"m_DictionaryValues": [
{
"type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "Path",
"value": "{\"m_Value\":\"{ProjectPath}\"}"
},
{
"type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "HistoryPath",
"value": "{\"m_Value\":\"{ProjectPath}\"}"
},
{
"type": "System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"key": "IncludeAssemblies",
"value": "{\"m_Value\":\"Assembly-CSharp,Runtime,Unity.ML-Agents,Unity.ML-Agents.Extensions\"}"
}
]
}
}

4
DevProject/ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2019.4.19f1
m_EditorVersionWithRevision: 2019.4.19f1 (ca5b14067cec)
m_EditorVersion: 2020.3.0f1
m_EditorVersionWithRevision: 2020.3.0f1 (c7b5465681fb)

3
Project/Assets/ML-Agents/Editor/Tests/SampleExporter.cs


struct MLAgentsSampleJson
{
#pragma warning disable 649
// ReSharper disable once CollectionNeverUpdated.Local
#pragma warning restore 649
}
struct PackageSampleJson

7
Project/Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBall.demo.meta


fileFormatVersion: 2
guid: bbf6756da134740eaa002a1b84f655cb
ScriptedImporter:
fileIDToRecycleName:
11400000: Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBall.demo
internalIDToNameTable:
- first:
114: 11400000
second: Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBall.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

7
Project/Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBallHard.demo.meta


fileFormatVersion: 2
guid: 6942431e411b146be9a597663eca89af
ScriptedImporter:
fileIDToRecycleName:
11400000: Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBallHard.demo
internalIDToNameTable:
- first:
114: 11400000
second: Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBallHard.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

7
Project/Assets/ML-Agents/Examples/Basic/Demos/ExpertBasic.demo.meta


fileFormatVersion: 2
guid: 414224ce8b3e247ad936b17f574b10ab
ScriptedImporter:
fileIDToRecycleName:
11400000: Assets/ML-Agents/Examples/Basic/Demos/ExpertBasic.demo
internalIDToNameTable:
- first:
114: 11400000
second: Assets/ML-Agents/Examples/Basic/Demos/ExpertBasic.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

6
Project/Assets/ML-Agents/Examples/Basic/Scripts/BasicActuatorComponent.cs


/// Creates a BasicActuator.
/// </summary>
/// <returns></returns>
#pragma warning disable 672
public override IActuator CreateActuator()
#pragma warning restore 672
public override IActuator[] CreateActuators()
return new BasicActuator(basicController);
return new IActuator[] { new BasicActuator(basicController) };
}
public override ActionSpec ActionSpec

4
Project/Assets/ML-Agents/Examples/Basic/Scripts/BasicSensorComponent.cs


}
/// <inheritdoc/>
public override int[] GetObservationShape()
public override ObservationSpec GetObservationSpec()
return new[] { BasicController.k_Extents };
return ObservationSpec.Vector(BasicController.k_Extents);
}
/// <inheritdoc/>

7
Project/Assets/ML-Agents/Examples/Crawler/Demos/ExpertCrawler.demo.meta


fileFormatVersion: 2
guid: 34586a8d0f1c342a49973b36a609e73b
ScriptedImporter:
fileIDToRecycleName:
11400002: Assets/ML-Agents/Examples/Crawler/Demos/ExpertCrawler.demo
internalIDToNameTable:
- first:
114: 11400002
second: Assets/ML-Agents/Examples/Crawler/Demos/ExpertCrawler.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

7
Project/Assets/ML-Agents/Examples/GridWorld/Demos/ExpertGridWorld.demo.meta


fileFormatVersion: 2
guid: 0092f2e4aece345aea4730a37eeebf68
ScriptedImporter:
fileIDToRecycleName:
11400002: Assets/ML-Agents/Examples/GridWorld/Demos/ExpertGridWorld.demo
internalIDToNameTable:
- first:
114: 11400002
second: Assets/ML-Agents/Examples/GridWorld/Demos/ExpertGridWorld.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

8
Project/Assets/ML-Agents/Examples/GridWorld/Scripts/GridAgent.cs


if (positionX == 0)
{
actionMask.WriteMask(0, new[] { k_Left });
actionMask.SetActionEnabled(0, k_Left, false);
actionMask.WriteMask(0, new[] { k_Right });
actionMask.SetActionEnabled(0, k_Right, false);
actionMask.WriteMask(0, new[] { k_Down });
actionMask.SetActionEnabled(0, k_Down, false);
actionMask.WriteMask(0, new[] { k_Up });
actionMask.SetActionEnabled(0, k_Up, false);
}
}
}

7
Project/Assets/ML-Agents/Examples/Hallway/Demos/ExpertHallway.demo.meta


fileFormatVersion: 2
guid: 41c6af18564fe425fa1c047d603ee34e
ScriptedImporter:
fileIDToRecycleName:
11400000: Assets/ML-Agents/Examples/Hallway/Demos/ExpertHallway.demo
internalIDToNameTable:
- first:
114: 11400000
second: Assets/ML-Agents/Examples/Hallway/Demos/ExpertHallway.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

6
Project/Assets/ML-Agents/Examples/Match3/Scripts/Match3ExampleActuatorComponent.cs


public class Match3ExampleActuatorComponent : Match3ActuatorComponent
{
/// <inheritdoc/>
#pragma warning disable 672
public override IActuator CreateActuator()
#pragma warning restore 672
public override IActuator[] CreateActuators()
return new Match3ExampleActuator(board, ForceHeuristic, agent, ActuatorName, seed);
return new IActuator[] { new Match3ExampleActuator(board, ForceHeuristic, agent, ActuatorName, seed) };
}
}
}

7
Project/Assets/ML-Agents/Examples/PushBlock/Demos/ExpertPushBlock.demo.meta


fileFormatVersion: 2
guid: 7f11f35191533404c9957443a681aaee
ScriptedImporter:
fileIDToRecycleName:
11400002: Assets/ML-Agents/Examples/PushBlock/Demos/ExpertPushBlock.demo
internalIDToNameTable:
- first:
114: 11400002
second: Assets/ML-Agents/Examples/PushBlock/Demos/ExpertPushBlock.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

7
Project/Assets/ML-Agents/Examples/Pyramids/Demos/ExpertPyramid.demo.meta


fileFormatVersion: 2
guid: 2f9d53c90f11846d7a6499ce0f1dfebb
ScriptedImporter:
fileIDToRecycleName:
11400000: Assets/ML-Agents/Examples/Pyramids/Demos/ExpertPyramid.demo
internalIDToNameTable:
- first:
114: 11400000
second: Assets/ML-Agents/Examples/Pyramids/Demos/ExpertPyramid.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

2
Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/CollisionCallbacks.cs.meta


fileFormatVersion: 2
guid: 506de7b261f374159a5cdfdb0ff48c0c
guid: df05ec10e50114a9d92106879d04d89d
MonoImporter:
externalObjects: {}
serializedVersion: 2

2
Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/SensorBase.cs


public abstract void WriteObservation(float[] output);
/// <inheritdoc/>
public abstract int[] GetObservationShape();
public abstract ObservationSpec GetObservationSpec();
/// <inheritdoc/>
public abstract string GetName();

2
Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs


dirToGo += transform.right * right * m_LateralSpeed;
rotateDir = -transform.up * rotate * m_RotateSpeed;
transform.Rotate(rotateDir, Time.deltaTime * 100f);
agentRb.AddForce(dirToGo * m_SoccerSettings.agentRunSpeed,
ForceMode.VelocityChange);

2
Project/Assets/ML-Agents/Examples/Soccer/Scripts/SoccerEnvController.cs


foreach (var item in AgentsList)
{
var randomPosX = Random.Range(-5f, 5f);
// var randomPosZ = Random.Range(-5f, 5f);
// var randomPosZ = Random.Range(-5f, 5f);
var newStartPos = item.Agent.initialPos + new Vector3(randomPosX, 0f, 0f);//randomPosZ);
var rot = item.Agent.rotSign * Random.Range(80.0f, 100.0f);
var newRot = Quaternion.Euler(0, rot, 0);

7
Project/Assets/ML-Agents/Examples/Walker/Demos/ExpertWalker.demo.meta


fileFormatVersion: 2
guid: a4b02e2c382c247919eb63ce72e90a3b
ScriptedImporter:
fileIDToRecycleName:
11400002: Assets/ML-Agents/Examples/Walker/Demos/ExpertWalker.demo
internalIDToNameTable:
- first:
114: 11400002
second: Assets/ML-Agents/Examples/Walker/Demos/ExpertWalker.demo
serializedVersion: 2
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
assetBundleName:
assetBundleVariant:

8
Project/Assets/ML-Agents/TestScenes/TestCompressedTexture/TestTextureSensor.cs


{
Texture2D m_Texture;
string m_Name;
int[] m_Shape;
private ObservationSpec m_ObservationSpec;
SensorCompressionType m_CompressionType;
/// <summary>

var width = texture.width;
var height = texture.height;
m_Name = name;
m_Shape = new[] { height, width, 3 };
m_ObservationSpec = ObservationSpec.Visual(height, width, 3);
m_CompressionType = compressionType;
}

}
/// <inheritdoc/>
public int[] GetObservationShape()
public ObservationSpec GetObservationSpec()
return m_Shape;
return m_ObservationSpec;
}
/// <inheritdoc/>

24
Project/Packages/manifest.json


{
"dependencies": {
"com.unity.ads": "2.0.8",
"com.unity.analytics": "3.2.3",
"com.unity.barracuda": "1.2.1-preview",
"com.unity.collab-proxy": "1.2.15",
"com.unity.2d.sprite": "1.0.0",
"com.unity.2d.tilemap": "1.0.0",
"com.unity.ads": "3.6.1",
"com.unity.collab-proxy": "1.2.16",
"com.unity.ide.rider": "1.1.4",
"com.unity.ide.vscode": "1.2.3",
"com.unity.package-manager-ui": "2.0.13",
"com.unity.purchasing": "2.2.1",
"com.unity.textmeshpro": "1.4.1",
"com.unity.multiplayer-hlapi": "1.0.8",
"com.unity.nuget.newtonsoft-json": "2.0.0",
"com.unity.test-framework": "1.1.22",
"com.unity.textmeshpro": "2.0.1",
"com.unity.timeline": "1.2.6",
"com.unity.ugui": "1.0.0",
"com.unity.xr.legacyinputhelpers": "2.1.7",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",

"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0",
"com.unity.nuget.newtonsoft-json": "2.0.0"
"com.unity.modules.xr": "1.0.0"
},
"testables": [
"com.unity.ml-agents",

16
Project/ProjectSettings/EditorSettings.asset


--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 7
serializedVersion: 9
m_ExternalVersionControlSupport: Hidden Meta Files
m_SerializationMode: 2
m_LineEndingsForNewScripts: 1

m_EtcTextureFastCompressor: 1
m_EtcTextureNormalCompressor: 2
m_EtcTextureBestCompressor: 4
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref
m_EnableTextureStreamingInEditMode: 1
m_AsyncShaderCompilation: 1
m_EnterPlayModeOptionsEnabled: 0
m_EnterPlayModeOptions: 3
m_ShowLightmapResolutionOverlay: 1
m_UseLegacyProbeSampleCount: 1
m_AssetPipelineMode: 1
m_CacheServerMode: 0
m_CacheServerEndpoint:
m_CacheServerNamespacePrefix: default
m_CacheServerEnableDownload: 1
m_CacheServerEnableUpload: 1

3
Project/ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2018.4.32f1
m_EditorVersion: 2019.4.20f1
m_EditorVersionWithRevision: 2019.4.20f1 (6dd1c08eedfa)

19
README.md


# Unity ML-Agents Toolkit
[![docs badge](https://img.shields.io/badge/docs-reference-blue.svg)](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/)
[![docs badge](https://img.shields.io/badge/docs-reference-blue.svg)](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/)
[![license badge](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE)

- 18+ [example Unity environments](docs/Learning-Environment-Examples.md)
- Support for multiple environment configurations and training scenarios
- Flexible Unity SDK that can be integrated into your game or custom Unity scene
- Training using two deep reinforcement learning algorithms, Proximal Policy
Optimization (PPO) and Soft Actor-Critic (SAC)
- Built-in support for Imitation Learning through Behavioral Cloning (BC) or
Generative Adversarial Imitation Learning (GAIL)
- Self-play mechanism for training agents in adversarial scenarios
- Support for training single-agent, multi-agent cooperative, and multi-agent
competitive scenarios via several Deep Reinforcement Learning algorithms (PPO, SAC, MA-POCA, self-play).
- Support for learning from demonstrations through two Imitation Learning algorithms (BC and GAIL).
- Easily definable Curriculum Learning scenarios for complex tasks
- Train robust agents using environment randomization
- Flexible agent control with On Demand Decision Making

## Releases & Documentation
**Our latest, stable release is `Release 14`. Click
[here](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/Readme.md)
**Our latest, stable release is `Release 15`. Click
[here](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/Readme.md)
to get started with the latest release of ML-Agents.**
The table below lists all our releases, including our `main` branch which is

| **Version** | **Release Date** | **Source** | **Documentation** | **Download** | **Python Package** | **Unity Package** |
|:-------:|:------:|:-------------:|:-------:|:------------:|:------------:|:------------:|
| **main (unstable)** | -- | [source](https://github.com/Unity-Technologies/ml-agents/tree/main) | [docs](https://github.com/Unity-Technologies/ml-agents/tree/main/docs/Readme.md) | [download](https://github.com/Unity-Technologies/ml-agents/archive/main.zip) | -- | -- |
| **Release 14** | **March 5, 2021** | **[source](https://github.com/Unity-Technologies/ml-agents/tree/release_14)** | **[docs](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/Readme.md)** | **[download](https://github.com/Unity-Technologies/ml-agents/archive/release_14.zip)** | **[0.24.1](https://pypi.org/project/mlagents/0.24.1/)** | **[1.8.1](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.8/manual/index.html)** |
| **Release 15** | **March 17, 2021** | **[source](https://github.com/Unity-Technologies/ml-agents/tree/release_15)** | **[docs](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/Readme.md)** | **[download](https://github.com/Unity-Technologies/ml-agents/archive/release_15.zip)** | **[0.25.0](https://pypi.org/project/mlagents/0.25.0/)** | **[1.9.0](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.9/manual/index.html)** |
| **Release 13** | **February 17, 2021** | **[source](https://github.com/Unity-Technologies/ml-agents/tree/release_13)** | **[docs](https://github.com/Unity-Technologies/ml-agents/tree/release_13_docs/docs/Readme.md)** | **[download](https://github.com/Unity-Technologies/ml-agents/archive/release_13.zip)** | **[0.24.0](https://pypi.org/project/mlagents/0.24.0/)** | **[1.8.0](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.8/manual/index.html)** |
| **Release 14** | March 5, 2021 | [source](https://github.com/Unity-Technologies/ml-agents/tree/release_14) | [docs](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/Readme.md) | [download](https://github.com/Unity-Technologies/ml-agents/archive/release_14.zip) | [0.24.1](https://pypi.org/project/mlagents/0.24.1/) | [1.8.1](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.8/manual/index.html) |
| **Release 13** | February 17, 2021 | [source](https://github.com/Unity-Technologies/ml-agents/tree/release_13) | [docs](https://github.com/Unity-Technologies/ml-agents/tree/release_13_docs/docs/Readme.md) | [download](https://github.com/Unity-Technologies/ml-agents/archive/release_13.zip) | [0.24.0](https://pypi.org/project/mlagents/0.24.0/) | [1.8.0](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.8/manual/index.html) |
| **Release 12** | December 22, 2020 | [source](https://github.com/Unity-Technologies/ml-agents/tree/release_12) | [docs](https://github.com/Unity-Technologies/ml-agents/tree/release_12_docs/docs/Readme.md) | [download](https://github.com/Unity-Technologies/ml-agents/archive/release_12.zip) | [0.23.0](https://pypi.org/project/mlagents/0.23.0/) | [1.7.2](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.7/manual/index.html) |
| **Release 11** | December 21, 2020 | [source](https://github.com/Unity-Technologies/ml-agents/tree/release_11) | [docs](https://github.com/Unity-Technologies/ml-agents/tree/release_11_docs/docs/Readme.md) | [download](https://github.com/Unity-Technologies/ml-agents/archive/release_11.zip) | [0.23.0](https://pypi.org/project/mlagents/0.23.0/) | [1.7.0](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.7/manual/index.html) |
| **Release 10** | November 18, 2020 | [source](https://github.com/Unity-Technologies/ml-agents/tree/release_10) | [docs](https://github.com/Unity-Technologies/ml-agents/tree/release_10_docs/docs/Readme.md) | [download](https://github.com/Unity-Technologies/ml-agents/archive/release_10.zip) | [0.22.0](https://pypi.org/project/mlagents/0.22.0/) | [1.6.0](https://docs.unity3d.com/Packages/com.unity.ml-agents@1.6/manual/index.html) |

2
com.unity.ml-agents.extensions/Documentation~/Grid-Sensor.md


An image can be thought of as a matrix of a predefined width (W) and a height (H) and each pixel can be thought of as simply an array of length 3 (in the case of RGB), `[Red, Green, Blue]` holding the different channel information of the color (channel) intensities at that pixel location. Thus an image is just a 3 dimensional matrix of size WxHx3. A Grid Observation can be thought of as a generalization of this setup where in place of a pixel there is a "cell" which is an array of length N representing different channel intensities at that cell position. From a Convolutional Neural Network point of view, the introduction of multiple channels in an "image" isn't a new concept. One such example is using an RGB-Depth image which is used in several robotics applications. The distinction of Grid Observations is what the data within the channels represents. Instead of limiting the channels to color intensities, the channels within a cell of a Grid Observation generalize to any data that can be represented by a single number (float or int).
Before jumping into the details of the Grid Sensor, an important thing to note is the agent performance and qualitatively different behavior over raycasts. Unity MLAgent's comes with a suite of example environments. One in particular, the [Food Collector](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/Learning-Environment-Examples.md#food-collector), has been the focus of the Grid Sensor development.
Before jumping into the details of the Grid Sensor, an important thing to note is the agent performance and qualitatively different behavior over raycasts. Unity MLAgent's comes with a suite of example environments. One in particular, the [Food Collector](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/Learning-Environment-Examples.md#food-collector), has been the focus of the Grid Sensor development.
The Food Collector environment can be described as:
* Set-up: A multi-agent environment where agents compete to collect food.

2
com.unity.ml-agents.extensions/Documentation~/Match3.md


This implementation includes:
* C# implementation catered toward a Match-3 setup including concepts around encoding for moves based on [Human Like Playtesting with Deep Learning](https://www.researchgate.net/publication/328307928_Human-Like_Playtesting_with_Deep_Learning)
* An example Match-3 scene with ML-Agents implemented (located under /Project/Assets/ML-Agents/Examples/Match3). More information, on Match-3 example [here](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/docs/Learning-Environment-Examples.md#match-3).
* An example Match-3 scene with ML-Agents implemented (located under /Project/Assets/ML-Agents/Examples/Match3). More information, on Match-3 example [here](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/docs/Learning-Environment-Examples.md#match-3).
### Feedback
If you are a Match-3 developer and are trying to leverage ML-Agents for this scenario, [we want to hear from you](https://forms.gle/TBsB9jc8WshgzViU9). Additionally, we are also looking for interested Match-3 teams to speak with us for 45 minutes. If you are interested, please indicate that in the [form](https://forms.gle/TBsB9jc8WshgzViU9). If selected, we will provide gift cards as a token of appreciation.

24
com.unity.ml-agents.extensions/Documentation~/com.unity.ml-agents.extensions.md


recommended ways to install the package:
### Local Installation
[Clone the repository](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/Installation.md#clone-the-ml-agents-toolkit-repository-optional) and follow the
[Local Installation for Development](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/Installation.md#advanced-local-installation-for-development-1)
[Clone the repository](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/Installation.md#clone-the-ml-agents-toolkit-repository-optional) and follow the
[Local Installation for Development](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/Installation.md#advanced-local-installation-for-development-1)
![Package Manager git URL](https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/images/unity_package_manager_git_url.png)
![Package Manager git URL](https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/images/unity_package_manager_git_url.png)
git+https://github.com/Unity-Technologies/ml-agents.git?path=com.unity.ml-agents.extensions#release_14
git+https://github.com/Unity-Technologies/ml-agents.git?path=com.unity.ml-agents.extensions#release_15
"com.unity.ml-agents.extensions": "git+https://github.com/Unity-Technologies/ml-agents.git?path=com.unity.ml-agents.extensions#release_14",
"com.unity.ml-agents.extensions": "git+https://github.com/Unity-Technologies/ml-agents.git?path=com.unity.ml-agents.extensions#release_15",
```
See [Git dependencies](https://docs.unity3d.com/Manual/upm-git.html#subfolder) for more information. Note that this
may take several minutes to resolve the packages the first time that you add it.

This version of the Unity ML-Agents Extensions package is compatible with the
following versions of the Unity Editor:
This version of the Unity ML-Agents package is compatible with the following
versions of the Unity Editor:
- If using the `InputActuatorComponent`
- 2019.4 or later
- install the `com.unity.inputsystem` package version `1.1.0-preview.3` or later.
- Else 2018.4 and later
- 2019.4 and later
If using the `InputActuatorComponent`
- install the `com.unity.inputsystem` package version `1.1.0-preview.3` or later.
## Known Limitations
- For the `InputActuatorComponent`

## Need Help?
The main [README](https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/README.md) contains links for contacting the team or getting support.
The main [README](https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/README.md) contains links for contacting the team or getting support.

4
com.unity.ml-agents.extensions/Editor/Input/InputActuatorComponentEditor.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using Unity.MLAgents.Extensions.Input;
using UnityEditor;

}
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_OR_NEWER
#endif // MLA_INPUT_SYSTEM

1
com.unity.ml-agents.extensions/Runtime/AssemblyInfo.cs


[assembly: InternalsVisibleTo("Unity.ML-Agents.Extensions.EditorTests")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Extensions.Editor")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Extensions.Tests")]

4
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using Unity.MLAgents.Actuators;
using UnityEngine;
using UnityEngine.InputSystem;

}
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

4
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using Unity.MLAgents.Actuators;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

}
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

4
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using Unity.MLAgents.Actuators;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;

}
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

4
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using Unity.MLAgents.Actuators;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;

}
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

4
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using System;
using Unity.MLAgents.Actuators;
using UnityEngine;

}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

4
com.unity.ml-agents.extensions/Runtime/Input/IInputActionAssetProvider.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using UnityEngine.InputSystem;
namespace Unity.MLAgents.Extensions.Input

(InputActionAsset, IInputActionCollection2) GetInputActionAsset();
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

4
com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using System;
using Unity.MLAgents.Actuators;
using UnityEngine.InputSystem;

void WriteToHeuristic(InputAction action, in ActionBuffers actionBuffers);
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

6
com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Policies;

/// <see cref="Agent"/>'s <see cref="BehaviorParameters"/> indicate that the Agent is running in Heuristic Mode,
/// this Actuator will write actions from the <see cref="InputSystem"/> to the <see cref="ActionBuffers"/> object.
/// </summary>
public class InputActionActuator : IActuator, IHeuristicProvider, IBuiltInActuator
public class InputActionActuator : IActuator, IBuiltInActuator
{
readonly BehaviorParameters m_BehaviorParameters;
readonly InputAction m_Action;

}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

9
com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using System;
using System.Collections.Generic;
using Unity.Collections;

return inputControlScheme;
}
#pragma warning disable 672
/// <inheritdoc cref="ActuatorComponent.CreateActuator"/>
public override IActuator CreateActuator() { return null; }
#pragma warning restore 672
/// <summary>
///
/// </summary>

}
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

4
com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs


#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_SYSTEM
using System;
using Unity.Collections;
using UnityEngine.InputSystem;

}
}
}
#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_SYSTEM

69
com.unity.ml-agents.extensions/Runtime/Match3/Match3Actuator.cs


/// <param name="agent"></param>
/// <param name="name"></param>
public Match3Actuator(AbstractBoard board,
bool forceHeuristic,
int seed,
Agent agent,
string name)
bool forceHeuristic,
int seed,
Agent agent,
string name)
{
m_Board = board;
m_Rows = board.Rows;

/// <inheritdoc/>
public void WriteDiscreteActionMask(IDiscreteActionMask actionMask)
{
const int branch = 0;
bool foundValidMove = false;
actionMask.WriteMask(0, InvalidMoveIndices());
}
}
var numMoves = m_Board.NumMoves();
/// <inheritdoc/>
public string Name { get; }
var currentMove = Move.FromMoveIndex(0, m_Board.Rows, m_Board.Columns);
for (var i = 0; i < numMoves; i++)
{
if (m_Board.IsMoveValid(currentMove))
{
foundValidMove = true;
}
else
{
actionMask.SetActionEnabled(branch, i, false);
}
currentMove.Next(m_Board.Rows, m_Board.Columns);
}
/// <inheritdoc/>
public void ResetData()
{
}
/// <inheritdoc/>
public BuiltInActuatorType GetBuiltInActuatorType()
{
return BuiltInActuatorType.Match3Actuator;
}
IEnumerable<int> InvalidMoveIndices()
{
var numValidMoves = m_Board.NumMoves();
foreach (var move in m_Board.InvalidMoves())
{
numValidMoves--;
if (numValidMoves == 0)
if (!foundValidMove)
{
// If all the moves are invalid and we mask all the actions out, this will cause an assert
// later on in IDiscreteActionMask. Instead, fire a callback to the user if they provided one,

"an invalid move will be passed to AbstractBoard.MakeMove()."
);
}
// This means the last move won't be returned as an invalid index.
yield break;
actionMask.SetActionEnabled(branch, numMoves - 1, true);
yield return move.MoveIndex;
/// <inheritdoc/>
public string Name { get; }
/// <inheritdoc/>
public void ResetData()
{
}
/// <inheritdoc/>
public BuiltInActuatorType GetBuiltInActuatorType()
{
return BuiltInActuatorType.Match3Actuator;
}
public void Heuristic(in ActionBuffers actionsOut)
{
var discreteActions = actionsOut.DiscreteActions;

var bestMoveIndex = 0;
var bestMovePoints = -1;
var numMovesAtCurrentScore = 0;

6
com.unity.ml-agents.extensions/Runtime/Match3/Match3ActuatorComponent.cs


public bool ForceHeuristic;
/// <inheritdoc/>
#pragma warning disable 672
public override IActuator CreateActuator()
#pragma warning restore 672
public override IActuator[] CreateActuators()
return new Match3Actuator(board, ForceHeuristic, seed, agent, ActuatorName);
return new IActuator[] { new Match3Actuator(board, ForceHeuristic, seed, agent, ActuatorName) };
}
/// <inheritdoc/>

12
com.unity.ml-agents.extensions/Runtime/Match3/Match3Sensor.cs


{
private Match3ObservationType m_ObservationType;
private AbstractBoard m_Board;
private int[] m_Shape;
private ObservationSpec m_ObservationSpec;
private int[] m_SparseChannelMapping;
private string m_Name;

m_NumSpecialTypes = board.NumSpecialTypes;
m_ObservationType = obsType;
m_Shape = obsType == Match3ObservationType.Vector ?
new[] { m_Rows * m_Columns * (m_NumCellTypes + SpecialTypeSize) } :
new[] { m_Rows, m_Columns, m_NumCellTypes + SpecialTypeSize };
m_ObservationSpec = obsType == Match3ObservationType.Vector
? ObservationSpec.Vector(m_Rows * m_Columns * (m_NumCellTypes + SpecialTypeSize))
: ObservationSpec.Visual(m_Rows, m_Columns, m_NumCellTypes + SpecialTypeSize);
// See comment in GetCompressedObservation()
var cellTypePaddedSize = 3 * ((m_NumCellTypes + 2) / 3);

}
/// <inheritdoc/>
public int[] GetObservationShape()
public ObservationSpec GetObservationSpec()
return m_Shape;
return m_ObservationSpec;
}
/// <inheritdoc/>

30
com.unity.ml-agents.extensions/Runtime/Sensors/GridSensor.cs


protected bool Initialized = false;
/// <summary>
/// Array holding the dimensions of the resulting tensor
/// Cached ObservationSpec
private int[] m_Shape;
private ObservationSpec m_ObservationSpec;
//
// Debug Parameters

// Default root reference to current game object
if (rootReference == null)
rootReference = gameObject;
m_Shape = new[] { GridNumSideX, GridNumSideZ, ObservationPerCell };
m_ObservationSpec = ObservationSpec.Visual(GridNumSideX, GridNumSideZ, ObservationPerCell);
compressedImgs = new List<byte[]>();
byteSizesBytesList = new List<byte[]>();

CellActivity[i] = DebugDefaultColor;
}
}
}
/// <summary>Gets the shape of the grid observation</summary>
/// <returns>integer array shape of the grid observation</returns>
public int[] GetFloatObservationShape()
{
m_Shape = new[] { GridNumSideX, GridNumSideZ, ObservationPerCell };
return m_Shape;
}
/// <inheritdoc/>

/// <summary>Gets the observation shape</summary>
/// <returns>int[] of the observation shape</returns>
public ObservationSpec GetObservationSpec()
{
// Lazy update
var shape = m_ObservationSpec.Shape;
if (shape[0] != GridNumSideX || shape[1] != GridNumSideZ || shape[2] != ObservationPerCell)
{
m_ObservationSpec = ObservationSpec.Visual(GridNumSideX, GridNumSideZ, ObservationPerCell);
}
return m_ObservationSpec;
}
/// <inheritdoc/>
m_Shape = new[] { GridNumSideX, GridNumSideZ, ObservationPerCell };
return m_Shape;
var shape = m_ObservationSpec.Shape;
return new int[] { shape[0], shape[1], shape[2] };
}
/// <inheritdoc/>

10
com.unity.ml-agents.extensions/Runtime/Sensors/PhysicsBodySensor.cs


/// </summary>
public class PhysicsBodySensor : ISensor, IBuiltInSensor
{
int[] m_Shape;
ObservationSpec m_ObservationSpec;
string m_SensorName;
PoseExtractor m_PoseExtractor;

}
var numTransformObservations = m_PoseExtractor.GetNumPoseObservations(settings);
m_Shape = new[] { numTransformObservations + numJointExtractorObservations };
m_ObservationSpec = ObservationSpec.Vector(numTransformObservations + numJointExtractorObservations);
}
#if UNITY_2020_1_OR_NEWER

}
var numTransformObservations = m_PoseExtractor.GetNumPoseObservations(settings);
m_Shape = new[] { numTransformObservations + numJointExtractorObservations };
m_ObservationSpec = ObservationSpec.Vector(numTransformObservations + numJointExtractorObservations);
public int[] GetObservationShape()
public ObservationSpec GetObservationSpec()
return m_Shape;
return m_ObservationSpec;
}
/// <inheritdoc/>

12
com.unity.ml-agents.extensions/Tests/Editor/Match3/Match3SensorTests.cs


var expectedShape = new[] { 3 * 3 * 2 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(expectedShape, sensor.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
var expectedObs = new float[]
{

var expectedShape = new[] { 3 * 3 * (2 + 3) };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(expectedShape, sensor.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
var expectedObs = new float[]
{

var expectedShape = new[] { 3, 3, 2 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(expectedShape, sensor.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.None, sensor.GetCompressionType());

var expectedShape = new[] { 3, 3, 2 + 3 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(expectedShape, sensor.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.None, sensor.GetCompressionType());

var expectedShape = new[] { 3, 3, 2 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(expectedShape, sensor.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.PNG, sensor.GetCompressionType());

var expectedShape = new[] { 3, 3, 2 + 3 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(expectedShape, sensor.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.PNG, sensor.GetCompressionType());

8
com.unity.ml-agents.extensions/Tests/Editor/Sensors/ChannelHotShapeTests.cs


gridSensor.Start();
int[] expectedShape = { 10, 10, 1 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetFloatObservationShape());
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
}

gridSensor.Start();
int[] expectedShape = { 10, 10, 2 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetFloatObservationShape());
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
}

gridSensor.Start();
int[] expectedShape = { 10, 10, 3 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetFloatObservationShape());
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
}

gridSensor.Start();
int[] expectedShape = { 10, 10, 6 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetFloatObservationShape());
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
}

6
com.unity.ml-agents.extensions/Tests/Editor/Sensors/ChannelShapeTests.cs


gridSensor.Start();
int[] expectedShape = { 10, 10, 1 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetFloatObservationShape());
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
}
[Test]

gridSensor.Start();
int[] expectedShape = { 10, 10, 2 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetFloatObservationShape());
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
}
[Test]

gridSensor.Start();
int[] expectedShape = { 10, 10, 7 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetFloatObservationShape());
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
}
}
}

1
com.unity.ml-agents.extensions/Tests/Editor/Unity.ML-Agents.Extensions.EditorTests.asmdef


"references": [
"Unity.ML-Agents.Extensions.Editor",
"Unity.ML-Agents.Extensions.TestUtils",
"Unity.ML-Agents.Extensions.Tests",
"Unity.ML-Agents.Extensions",
"Unity.ML-Agents"
],

4
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs


#if MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_TESTS
using NUnit.Framework;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Extensions.Input;

}
}
}
#endif // MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_TESTS

4
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs


#if MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_TESTS
using NUnit.Framework;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Extensions.Input;

}
}
}
#endif // MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_TESTS

4
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs


#if MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_TESTS
using NUnit.Framework;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Extensions.Input;

}
}
}
#endif // MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_TESTS

4
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs


#if MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_TESTS
using System;
using NUnit.Framework;
using Unity.MLAgents.Actuators;

}
}
}
#endif // MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_TESTS

4
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs


#if MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_TESTS
using NUnit.Framework;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Extensions.Input;

}
}
}
#endif // MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_TESTS

4
com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs


#if MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_TESTS
using NUnit.Framework;
using Unity.Barracuda;
using Unity.MLAgents.Actuators;

}
}
}
#endif // MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_TESTS

4
com.unity.ml-agents.extensions/Tests/Runtime/Input/TestPushBlockActions.cs


#if MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#if MLA_INPUT_TESTS
//------------------------------------------------------------------------------
// <auto-generated>
// This code was auto-generated by com.unity.inputsystem:InputActionCodeGenerator

void OnJump(InputAction.CallbackContext context);
}
}
#endif // MLA_INPUT_TESTS && UNITY_2019_4_OR_NEWER
#endif // MLA_INPUT_TESTS

3
com.unity.ml-agents.extensions/Tests/Runtime/Unity.ML-Agents.Extensions.Tests.asmdef


{
"name": "Unity.ML-Agents.Extensions.Tests",
"references": [
"Unity.ML-Agents.Extensions"
"Unity.ML-Agents.Extensions",
"Unity.ML-Agents"
],
"optionalUnityReferences": [
"TestAssemblies"

6
com.unity.ml-agents.extensions/package.json


{
"name": "com.unity.ml-agents.extensions",
"displayName": "ML Agents Extensions",
"version": "0.2.0-preview",
"unity": "2018.4",
"version": "0.3.0-preview",
"unity": "2019.4",
"com.unity.ml-agents": "1.8.1-preview"
"com.unity.ml-agents": "2.0.0-exp.1"
}
}

24
com.unity.ml-agents/CHANGELOG.md


## [Unreleased]
### Major Changes
#### com.unity.ml-agents (C#)
- The minimum supported Unity version was updated to 2019.4. (#5166)
- Several breaking interface changes were made. See the
[Migration Guide](https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Migrating.md) for more
details.
- Some methods previously marked as `Obsolete` have been removed. If you were using these methods, you need to replace them with their supported counterpart.
- The interface for disabling discrete actions in `IDiscreteActionMask` has changed.
`WriteMask(int branch, IEnumerable<int> actionIndices)` was replaced with
`SetActionEnabled(int branch, int actionIndex, bool isEnabled)`. (#5060)
- IActuator now implements IHeuristicProvider. (#5110)
- `ISensor.GetObservationShape()` was removed, and `GetObservationSpec()` was added. (#5127)
- The `.onnx` models input names have changed. All input placeholders will now use the prefix `obs_` removing the distinction between visual and vector observations. Models created with this version will not be usable with previous versions of the package (#5080)
- The `.onnx` models discrete action output now contains the discrete actions values and not the logits. Models created with this version will not be usable with previous versions of the package (#5080)
- Added ML-Agents package settings. (#5027)
#### com.unity.ml-agents / com.unity.ml-agents.extensions (C#)
#### com.unity.ml-agents (C#)
- The `BufferSensor` and `BufferSensorComponent` have been added. They allow the Agent to observe variable number of entities. (#4909)
- The `BufferSensor` and `BufferSensorComponent` have been added. They allow the Agent to observe variable number of entities. For an example, see the [Sorter environment](https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Examples.md#sorter). (#4909)
end episodes in groups. (#4923)
end episodes in groups. For examples, see the [Cooperative Push Block](https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Examples.md#cooperative-push-block), [Dungeon Escape](https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Examples.md#dungeon-escape) and [Soccer](https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Examples.md#soccer-twos) environments. (#4923)
#### ml-agents / ml-agents-envs / gym-unity (Python)
- The MA-POCA trainer has been added. This is a new trainer that enables Agents to learn how to work together in groups. Configure
`poca` as the trainer in the configuration YAML after instantiating a `SimpleMultiAgentGroup` to use this feature. (#5005)

- Updated com.unity.barracuda to 1.3.2-preview. (#5084)
- Added 3D Ball to the `com.unity.ml-agents` samples. (#5077)
- Make com.unity.modules.unityanalytics an optional dependency. (#5109)
#### ml-agents / ml-agents-envs / gym-unity (Python)
- The `encoding_size` setting for RewardSignals has been deprecated. Please use `network_settings` instead. (#4982)
- Sensor names are now passed through to `ObservationSpec.name`. (#5036)

12
com.unity.ml-agents/CONTRIBUTING.md


Several static checks are run on the codebase using the
[pre-commit framework](https://pre-commit.com/) during CI. To execute the same
checks locally, run `pip install pre-commit` and then `pre-commit run --all-files`.
checks locally, run:
```bash
pip install pre-commit>=2.8.0
pip install identify>==2.1.3
pre-commit run --all-files
```
Some hooks (for example, `black`) will output the corrected version of the code;
others (like `mypy`) may require more effort to fix. You can optionally run
`pre-commit install` to install it as a git hook; after this it will run on all

[`black`](https://github.com/psf/black).
C# code is formatted using [`dotnet-format`](https://github.com/dotnet/format).
You must have [dotnet](https://dotnet.microsoft.com/download) and
`dotnet-format` installed first.
You must have [dotnet](https://dotnet.microsoft.com/download) installed first
(but don't need to install `dotnet-format` - `pre-commit` will do that for you).
### Python type annotations

6
com.unity.ml-agents/Documentation~/com.unity.ml-agents.md


This version of the Unity ML-Agents package is compatible with the following
versions of the Unity Editor:
- 2018.4 and later
- 2019.4 and later
## Known Limitations

[unity ML-Agents Toolkit]: https://github.com/Unity-Technologies/ml-agents
[unity inference engine]: https://docs.unity3d.com/Packages/com.unity.barracuda@latest/index.html
[package manager documentation]: https://docs.unity3d.com/Manual/upm-ui-install.html
[installation instructions]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Installation.md
[installation instructions]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Installation.md
[ML-Agents GitHub repo]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/com.unity.ml-agents.extensions
[ML-Agents GitHub repo]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/com.unity.ml-agents.extensions

16
com.unity.ml-agents/Editor/BehaviorParametersEditor.cs


using Unity.MLAgents.Policies;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Sensors.Reflection;
using CheckTypeEnum = Unity.MLAgents.Inference.BarracudaModelParamLoader.FailedCheck.CheckTypeEnum;
namespace Unity.MLAgents.Editor
{

{
if (check != null)
{
EditorGUILayout.HelpBox(check, MessageType.Warning);
switch (check.CheckType)
{
case CheckTypeEnum.Info:
EditorGUILayout.HelpBox(check.Message, MessageType.Info);
break;
case CheckTypeEnum.Warning:
EditorGUILayout.HelpBox(check.Message, MessageType.Warning);
break;
case CheckTypeEnum.Error:
EditorGUILayout.HelpBox(check.Message, MessageType.Error);
break;
default:
break;
}
}
}
}

8
com.unity.ml-agents/Runtime/Academy.cs


* API. For more information on each of these entities, in addition to how to
* set-up a learning environment and train the behavior of characters in a
* Unity scene, please browse our documentation pages on GitHub:
* https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/docs/
* https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/docs/
*/
namespace Unity.MLAgents

/// fall back to inference or heuristic decisions. (You can also set agents to always use
/// inference or heuristics.)
/// </remarks>
[HelpURL("https://github.com/Unity-Technologies/ml-agents/tree/release_14_docs/" +
[HelpURL("https://github.com/Unity-Technologies/ml-agents/tree/release_15_docs/" +
"docs/Learning-Environment-Design.md")]
public class Academy : IDisposable
{

/// Unity package version of com.unity.ml-agents.
/// This must match the version string in package.json and is checked in a unit test.
/// </summary>
internal const string k_PackageVersion = "1.8.1-preview";
internal const string k_PackageVersion = "2.0.0-exp.1";
const int k_EditorTrainingPort = 5004;

// No arg passed, or malformed port number.
#if UNITY_EDITOR
// Try connecting on the default editor port
return k_EditorTrainingPort;
return MLAgentsSettingsManager.Settings.ConnectTrainer ? MLAgentsSettingsManager.Settings.EditorPort : -1;
#else
// This is an executable, so we don't try to connect.
return -1;

14
com.unity.ml-agents/Runtime/Actuators/ActuatorComponent.cs


public abstract class ActuatorComponent : MonoBehaviour
{
/// <summary>
/// Create the IActuator. This is called by the Agent when it is initialized.
/// </summary>
/// <returns>Created IActuator object.</returns>
[Obsolete("Use CreateActuators instead.")]
public abstract IActuator CreateActuator();
/// <summary>
public virtual IActuator[] CreateActuators()
{
#pragma warning disable 618
return new[] { CreateActuator() };
#pragma warning restore 618
}
public abstract IActuator[] CreateActuators();
/// <summary>
/// The specification of the possible actions for this ActuatorComponent.

29
com.unity.ml-agents/Runtime/Actuators/ActuatorDiscreteActionMask.cs


}
/// <inheritdoc/>
public void WriteMask(int branch, IEnumerable<int> actionIndices)
public void SetActionEnabled(int branch, int actionIndex, bool isEnabled)
// Perform the masking
foreach (var actionIndex in actionIndices)
#if DEBUG
if (branch >= m_NumBranches || actionIndex >= m_BranchSizes[CurrentBranchOffset + branch])
#if DEBUG
if (branch >= m_NumBranches || actionIndex >= m_BranchSizes[CurrentBranchOffset + branch])
{
throw new UnityAgentsException(
"Invalid Action Masking: Action Mask is too large for specified branch.");
}
throw new UnityAgentsException(
"Invalid Action Masking: Action Mask is too large for specified branch.");
}
m_CurrentMask[actionIndex + m_StartingActionIndices[CurrentBranchOffset + branch]] = true;
}
m_CurrentMask[actionIndex + m_StartingActionIndices[CurrentBranchOffset + branch]] = !isEnabled;
}
void LazyInitialize()

}
}
/// <inheritdoc/>
public bool[] GetMask()
/// <summary>
/// Get the current mask for an agent.
/// </summary>
/// <returns>A mask for the agent. A boolean array of length equal to the total number of
/// actions.</returns>
internal bool[] GetMask()
{
#if DEBUG
if (m_CurrentMask != null)

/// <summary>
/// Resets the current mask for an agent.
/// </summary>
public void ResetMask()
internal void ResetMask()
{
if (m_CurrentMask != null)
{

4
com.unity.ml-agents/Runtime/Actuators/ActuatorManager.cs


discreteStart,
numDiscreteActions);
}
var heuristic = actuator as IHeuristicProvider;
heuristic?.Heuristic(new ActionBuffers(continuousActions, discreteActions));
actuator.Heuristic(new ActionBuffers(continuousActions, discreteActions));
continuousStart += numContinuousActions;
discreteStart += numDiscreteActions;
}

45
com.unity.ml-agents/Runtime/Actuators/IActionReceiver.cs


return (ContinuousActions.GetHashCode() * 397) ^ DiscreteActions.GetHashCode();
}
}
/// <summary>
/// Packs the continuous and discrete actions into one float array. The array passed into this method
/// must have a Length that is greater than or equal to the sum of the Lengths of
/// <see cref="ContinuousActions"/> and <see cref="DiscreteActions"/>.
/// </summary>
/// <param name="destination">A float array to pack actions into whose length is greater than or
/// equal to the addition of the Lengths of this objects <see cref="ContinuousActions"/> and
/// <see cref="DiscreteActions"/> segments.</param>
[Obsolete("PackActions has been deprecated.")]
public void PackActions(in float[] destination)
{
Debug.Assert(destination.Length >= ContinuousActions.Length + DiscreteActions.Length,
$"argument '{nameof(destination)}' is not large enough to pack the actions into.\n" +
$"{nameof(destination)}.Length: {destination.Length}\n" +
$"{nameof(ContinuousActions)}.Length + {nameof(DiscreteActions)}.Length: {ContinuousActions.Length + DiscreteActions.Length}");
var start = 0;
if (ContinuousActions.Length > 0)
{
Array.Copy(ContinuousActions.Array,
ContinuousActions.Offset,
destination,
start,
ContinuousActions.Length);
start = ContinuousActions.Length;
}
if (start >= destination.Length)
{
return;
}
if (DiscreteActions.Length > 0)
{
Array.Copy(DiscreteActions.Array,
DiscreteActions.Offset,
destination,
start,
DiscreteActions.Length);
}
}
}
/// <summary>

/// </param>
/// <remarks>
/// When using Discrete Control, you can prevent the Agent from using a certain
/// action by masking it with <see cref="IDiscreteActionMask.WriteMask"/>.
/// action by masking it with <see cref="IDiscreteActionMask.SetActionEnabled"/>.
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#actions
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#actions
/// </remarks>
/// <seealso cref="IActionReceiver.OnActionReceived"/>
void WriteDiscreteActionMask(IDiscreteActionMask actionMask);

2
com.unity.ml-agents/Runtime/Actuators/IActuator.cs


/// <summary>
/// Abstraction that facilitates the execution of actions.
/// </summary>
public interface IActuator : IActionReceiver
public interface IActuator : IActionReceiver, IHeuristicProvider
{
/// <summary>
/// The specification of the actions for this IActuator.

26
com.unity.ml-agents/Runtime/Actuators/IDiscreteActionMask.cs


public interface IDiscreteActionMask
{
/// <summary>
/// Modifies an action mask for discrete control agents.
/// Set whether or not the action index for the given branch is allowed.
/// When used, the agent will not be able to perform the actions passed as argument
/// at the next decision for the specified action branch. The actionIndices correspond
/// By default, all discrete actions are allowed.
/// If isEnabled is false, the agent will not be able to perform the actions passed as argument
/// at the next decision for the specified action branch. The actionIndex correspond
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#actions
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#actions
/// <param name="actionIndices">The indices of the masked actions.</param>
void WriteMask(int branch, IEnumerable<int> actionIndices);
/// <summary>
/// Get the current mask for an agent.
/// </summary>
/// <returns>A mask for the agent. A boolean array of length equal to the total number of
/// actions.</returns>
bool[] GetMask();
/// <summary>
/// Resets the current mask for an agent.
/// </summary>
void ResetMask();
/// <param name="actionIndex">Index of the action</param>
/// <param name="isEnabled">Whether the action is allowed or now.</param>
void SetActionEnabled(int branch, int actionIndex, bool isEnabled);
}
}

2
com.unity.ml-agents/Runtime/Actuators/VectorActuator.cs


/// <summary>
/// IActuator implementation that forwards calls to an <see cref="IActionReceiver"/> and an <see cref="IHeuristicProvider"/>.
/// </summary>
internal class VectorActuator : IActuator, IHeuristicProvider, IBuiltInActuator
internal class VectorActuator : IActuator, IBuiltInActuator
{
IActionReceiver m_ActionReceiver;
IHeuristicProvider m_HeuristicProvider;

109
com.unity.ml-agents/Runtime/Agent.cs


/// [OnDisable()]: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnDisable.html]
/// [OnBeforeSerialize()]: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnBeforeSerialize.html
/// [OnAfterSerialize()]: https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAfterSerialize.html
/// [Agents]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md
/// [Reinforcement Learning in Unity]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design.md
/// [Agents]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md
/// [Reinforcement Learning in Unity]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design.md
/// [Unity ML-Agents Toolkit manual]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Readme.md
/// [Unity ML-Agents Toolkit manual]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Readme.md
[HelpURL("https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/" +
[HelpURL("https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/" +
"docs/Learning-Environment-Design-Agents.md")]
[Serializable]
[RequireComponent(typeof(BehaviorParameters))]

/// Whether or not the Agent has been initialized already
bool m_Initialized;
/// Keeps track of the actions that are masked at each step.
DiscreteActionMasker m_ActionMasker;
/// <summary>
/// Set of DemonstrationWriters that the Agent will write its step information to.
/// If you use a DemonstrationRecorder component, this will automatically register its DemonstrationWriter.

/// with the current behavior of Agent.
/// </summary>
IActuator m_VectorActuator;
/// <summary>
/// This is used to avoid allocation of a float array every frame if users are still using the old
/// OnActionReceived method.
/// </summary>
float[] m_LegacyActionCache;
/// <summary>
/// This is used to avoid allocation of a float array during legacy calls to Heuristic.
/// </summary>
float[] m_LegacyHeuristicCache;
/// Currect MultiAgentGroup ID. Default to 0 (meaning no group)
int m_GroupId;

/// for information about mixing reward signals from curiosity and Generative Adversarial
/// Imitation Learning (GAIL) with rewards supplied through this method.
///
/// [Agents - Rewards]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#rewards
/// [Reward Signals]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/ML-Agents-Overview.md#a-quick-note-on-reward-signals
/// [Agents - Rewards]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#rewards
/// [Reward Signals]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/ML-Agents-Overview.md#a-quick-note-on-reward-signals
/// </remarks>
/// <param name="reward">The new value of the reward.</param>
public void SetReward(float reward)

/// for information about mixing reward signals from curiosity and Generative Adversarial
/// Imitation Learning (GAIL) with rewards supplied through this method.
///
/// [Agents - Rewards]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#rewards
/// [Reward Signals]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/ML-Agents-Overview.md#a-quick-note-on-reward-signals
/// [Agents - Rewards]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#rewards
/// [Reward Signals]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/ML-Agents-Overview.md#a-quick-note-on-reward-signals
///</remarks>
/// <param name="increment">Incremental reward value.</param>
public void AddReward(float increment)

/// implementing a simple heuristic function can aid in debugging agent actions and interactions
/// with its environment.
///
/// [Demonstration Recorder]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#recording-demonstrations
/// [Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#actions
/// [Demonstration Recorder]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#recording-demonstrations
/// [Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#actions
/// [GameObject]: https://docs.unity3d.com/Manual/GameObjects.html
/// </remarks>
/// <example>

/// <seealso cref="IActionReceiver.OnActionReceived"/>
public virtual void Heuristic(in ActionBuffers actionsOut)
{
// Disable deprecation warnings so we can call the legacy overload.
#pragma warning disable CS0618
// The default implementation of Heuristic calls the
// obsolete version for backward compatibility
switch (m_PolicyFactory.BrainParameters.VectorActionSpaceType)
{
case SpaceType.Continuous:
Heuristic(m_LegacyHeuristicCache);
Array.Copy(m_LegacyHeuristicCache, actionsOut.ContinuousActions.Array, m_LegacyActionCache.Length);
actionsOut.DiscreteActions.Clear();
break;
case SpaceType.Discrete:
Heuristic(m_LegacyHeuristicCache);
var discreteActionSegment = actionsOut.DiscreteActions;
for (var i = 0; i < actionsOut.DiscreteActions.Length; i++)
{
discreteActionSegment[i] = (int)m_LegacyHeuristicCache[i];
}
actionsOut.ContinuousActions.Clear();
break;
}
#pragma warning restore CS0618
Debug.LogWarning("Heuristic method called but not implemented. Returning placeholder actions.");
}
/// <summary>

var param = m_PolicyFactory.BrainParameters;
m_VectorActuator = new AgentVectorActuator(this, this, param.ActionSpec);
m_ActuatorManager = new ActuatorManager(attachedActuators.Length + 1);
m_LegacyActionCache = new float[m_VectorActuator.TotalNumberOfActions()];
m_LegacyHeuristicCache = new float[m_VectorActuator.TotalNumberOfActions()];
m_ActuatorManager.Add(m_VectorActuator);

/// For more information about observations, see [Observations and Sensors].
///
/// [GameObject]: https://docs.unity3d.com/Manual/GameObjects.html
/// [Observations and Sensors]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#observations-and-sensors
/// [Observations and Sensors]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#observations-and-sensors
/// </remarks>
public virtual void CollectObservations(VectorSensor sensor)
{

/// </param>
/// <remarks>
/// When using Discrete Control, you can prevent the Agent from using a certain
/// action by masking it with <see cref="IDiscreteActionMask.WriteMask(int, IEnumerable{int})"/>.
/// action by masking it with <see cref="IDiscreteActionMask.SetActionEnabled"/>.
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#actions
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#actions
public virtual void WriteDiscreteActionMask(IDiscreteActionMask actionMask)
{
if (m_ActionMasker == null)
{
m_ActionMasker = new DiscreteActionMasker(actionMask);
}
// Disable deprecation warnings so we can call the legacy overload.
#pragma warning disable CS0618
CollectDiscreteActionMasks(m_ActionMasker);
#pragma warning restore CS0618
}
public virtual void WriteDiscreteActionMask(IDiscreteActionMask actionMask) { }
/// <summary>
/// Implement `OnActionReceived()` to specify agent behavior at every step, based

///
/// For more information about implementing agent actions see [Agents - Actions].
///
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs/Learning-Environment-Design-Agents.md#actions
/// [Agents - Actions]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs/Learning-Environment-Design-Agents.md#actions
public virtual void OnActionReceived(ActionBuffers actions)
{
var actionSpec = m_PolicyFactory.BrainParameters.ActionSpec;
// For continuous and discrete actions together, we don't need to fall back to the legacy method
if (actionSpec.NumContinuousActions > 0 && actionSpec.NumDiscreteActions > 0)
{
// Nothing implemented.
return;
}
if (!actions.ContinuousActions.IsEmpty())
{
Array.Copy(actions.ContinuousActions.Array,
m_LegacyActionCache,
actionSpec.NumContinuousActions);
}
else
{
for (var i = 0; i < m_LegacyActionCache.Length; i++)
{
m_LegacyActionCache[i] = (float)actions.DiscreteActions[i];
}
}
// Disable deprecation warnings so we can call the legacy overload.
#pragma warning disable CS0618
OnActionReceived(m_LegacyActionCache);
#pragma warning restore CS0618
}
public virtual void OnActionReceived(ActionBuffers actions) { }
/// <summary>
/// Implement `OnEpisodeBegin()` to set up an Agent instance at the beginning

7
com.unity.ml-agents/Runtime/Analytics/Events.cs


public static EventObservationSpec FromSensor(ISensor sensor)
{
var shape = sensor.GetObservationShape();
var dimProps = (sensor as IDimensionPropertiesSensor)?.GetDimensionProperties();
var obsSpec = sensor.GetObservationSpec();
var shape = obsSpec.Shape;
var dimProps = obsSpec.DimensionProperties;
dimInfos[i].Flags = dimProps != null ? (int)dimProps[i] : 0;
dimInfos[i].Flags = (int)dimProps[i];
}
var builtInSensorType =

26
com.unity.ml-agents/Runtime/Analytics/InferenceAnalytics.cs


using System;
using System.Diagnostics;
using Unity.Barracuda;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Inference;

#if MLA_UNITY_ANALYTICS_MODULE
#endif
#if MLA_UNITY_ANALYTICS_MODULE
#endif
#endif // MLA_UNITY_ANALYTICS_MODULE
#endif // UNITY_EDITOR
namespace Unity.MLAgents.Analytics

return true;
}
#if UNITY_EDITOR
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
#else
if (result == AnalyticsResult.Ok)
{
s_EventRegistered = true;
}
#elif MLA_UNITY_ANALYTICS_MODULE
#endif
#endif
if (s_EventRegistered && s_SentModels == null)
{
s_SentModels = new HashSet<NNModel>();

/// <param name="actionSpec">ActionSpec for the Agent. Used to generate information about the action space.</param>
/// <param name="actuators">List of IActuators for the Agent. Used to generate information about the action space.</param>
/// <returns></returns>
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
public static void InferenceModelSet(
NNModel nnModel,
string behaviorName,

var data = GetEventForModel(nnModel, behaviorName, inferenceDevice, sensors, actionSpec, actuators);
// Note - to debug, use JsonUtility.ToJson on the event.
// Debug.Log(JsonUtility.ToJson(data, true));
#if UNITY_EDITOR
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
if (AnalyticsUtils.s_SendEditorAnalytics)
{
EditorAnalytics.SendEventWithLimit(k_EventName, data, k_EventVersion);

inferenceEvent.BarracudaModelProducer = "tensorflow_to_barracuda.py";
}
#if UNITY_2019_3_OR_NEWER && UNITY_EDITOR
#if UNITY_EDITOR
var barracudaPackageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(Tensor).Assembly);
inferenceEvent.BarracudaPackageVersion = barracudaPackageInfo.version;
#else

34
com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs


using System;
using System.Collections.Generic;
using System.Diagnostics;
#if MLA_UNITY_ANALYTICS_MODULE
#if UNITY_EDITOR
using UnityEditor.Analytics;
#endif
#endif
using UnityEditor.Analytics;
#endif
namespace Unity.MLAgents.Analytics

static bool EnableAnalytics()
{
#if MLA_UNITY_ANALYTICS_MODULE
#else
AnalyticsResult result = AnalyticsResult.UnsupportedPlatform;
#endif
#else
return false;
#endif // UNITY_EDITOR
}
s_EventsRegistered = true;

}
return s_EventsRegistered;
#else
return false;
#endif // MLA_UNITY_ANALYTICS_MODULE
}
/// <summary>

/// <param name="packageVersion"></param>
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
public static void SetTrainerInformation(string packageVersion, string communicationVersion)
{
s_TrainerPackageVersion = packageVersion;

public static bool IsAnalyticsEnabled()
{
#if UNITY_EDITOR
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
return EditorAnalytics.enabled;
#else
return false;

[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
public static void TrainingEnvironmentInitialized(TrainingEnvironmentInitializedEvent tbiEvent)
{
if (!IsAnalyticsEnabled())

// Debug.Log(
// $"Would send event {k_TrainingEnvironmentInitializedEventName} with body {JsonUtility.ToJson(tbiEvent, true)}"
// );
#if UNITY_EDITOR
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
#else
return;
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
public static void RemotePolicyInitialized(
string fullyQualifiedBehaviorName,
IList<ISensor> sensors,

// Debug.Log(
// $"Would send event {k_RemotePolicyInitializedEventName} with body {JsonUtility.ToJson(data, true)}"
// );
#if UNITY_EDITOR
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
#else
return;
#endif
}

return fullyQualifiedBehaviorName.Substring(0, lastQuestionIndex);
}
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
public static void TrainingBehaviorInitialized(TrainingBehaviorInitializedEvent tbiEvent)
{
if (!IsAnalyticsEnabled())

// Debug.Log(
// $"Would send event {k_TrainingBehaviorInitializedEventName} with body {JsonUtility.ToJson(tbiEvent, true)}"
// );
#if UNITY_EDITOR
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
if (AnalyticsUtils.s_SendEditorAnalytics)
{
EditorAnalytics.SendEventWithLimit(k_TrainingBehaviorInitializedEventName, tbiEvent);

5
com.unity.ml-agents/Runtime/AssemblyInfo.cs


using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Unity.ML-Agents.Editor.Tests")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Runtime.Sensor.Tests")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Runtime.Utils.Tests")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Runtime.Tests")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Extensions.Tests")]

62
com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs


using UnityEngine;
using System.Runtime.CompilerServices;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Analytics;
using Unity.MLAgents.Analytics;
[assembly: InternalsVisibleTo("Unity.ML-Agents.Runtime.Utils.Tests")]
namespace Unity.MLAgents
{

/// <returns>The protobuf version of the AgentInfo.</returns>
public static AgentInfoProto ToAgentInfoProto(this AgentInfo ai)
{
if(ai.groupId > 0)
if (ai.groupId > 0)
{
var trainerCanHandle = Academy.Instance.TrainerCapabilities == null || Academy.Instance.TrainerCapabilities.MultiAgentGroups;
if (!trainerCanHandle)

/// <returns></returns>
public static ObservationProto GetObservationProto(this ISensor sensor, ObservationWriter observationWriter)
{
var shape = sensor.GetObservationShape();
var obsSpec = sensor.GetObservationSpec();
var shape = obsSpec.Shape;
ObservationProto observationProto = null;
var compressionType = sensor.GetCompressionType();
// Check capabilities if we need to concatenate PNGs

floatDataProto.Data.Add(0.0f);
}
observationWriter.SetTarget(floatDataProto.Data, sensor.GetObservationShape(), 0);
observationWriter.SetTarget(floatDataProto.Data, sensor.GetObservationSpec(), 0);
sensor.Write(observationWriter);
observationProto = new ObservationProto

observationProto.CompressedChannelMapping.AddRange(compressibleSensor.GetCompressedChannelMapping());
}
}
// Add the dimension properties if any to the observationProto
var dimensionPropertySensor = sensor as IDimensionPropertiesSensor;
if (dimensionPropertySensor != null)
// Add the dimension properties to the observationProto
var dimensionProperties = obsSpec.DimensionProperties;
for (int i = 0; i < dimensionProperties.Length; i++)
{
observationProto.DimensionProperties.Add((int)dimensionProperties[i]);
}
// Checking trainer compatibility with variable length observations
if (dimensionProperties == new InplaceArray<DimensionProperty>(DimensionProperty.VariableSize, DimensionProperty.None))
var dimensionProperties = dimensionPropertySensor.GetDimensionProperties();
for (int i = 0; i < dimensionProperties.Length; i++)
{
observationProto.DimensionProperties.Add((int)dimensionProperties[i]);
}
// Checking trainer compatibility with variable length observations
if (dimensionProperties.Length == 2)
var trainerCanHandleVarLenObs = Academy.Instance.TrainerCapabilities == null || Academy.Instance.TrainerCapabilities.VariableLengthObservation;
if (!trainerCanHandleVarLenObs)
if (dimensionProperties[0] == DimensionProperty.VariableSize &&
dimensionProperties[1] == DimensionProperty.None)
{
var trainerCanHandleVarLenObs = Academy.Instance.TrainerCapabilities == null || Academy.Instance.TrainerCapabilities.VariableLengthObservation;
if (!trainerCanHandleVarLenObs)
{
throw new UnityAgentsException("Variable Length Observations are not supported by the trainer");
}
}
throw new UnityAgentsException("Variable Length Observations are not supported by the trainer");
observationProto.Shape.AddRange(shape);
for (var i = 0; i < shape.Length; i++)
{
observationProto.Shape.Add(shape[i]);
}
var sensorName = sensor.GetName();
if (!string.IsNullOrEmpty(sensorName))
{

// Add the observation type, if any, to the observationProto
var typeSensor = sensor as ITypedSensor;
if (typeSensor != null)
{
observationProto.ObservationType = (ObservationTypeProto)typeSensor.GetObservationType();
}
else
{
observationProto.ObservationType = ObservationTypeProto.Default;
}
observationProto.ObservationType = (ObservationTypeProto)obsSpec.ObservationType;
return observationProto;
}

}
#region Analytics
internal static TrainingEnvironmentInitializedEvent ToTrainingEnvironmentInitializedEvent(
this TrainingEnvironmentInitialized inputProto)
{

NumNetworkHiddenUnits = inputProto.NumNetworkHiddenUnits,
};
}
#endregion
}

4
com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs


using System.Linq;
using UnityEngine;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Analytics;
using Unity.MLAgents.Analytics;
namespace Unity.MLAgents
{

var pythonPackageVersion = initializationInput.RlInitializationInput.PackageVersion;
var pythonCommunicationVersion = initializationInput.RlInitializationInput.CommunicationVersion;
TrainingAnalytics.SetTrainerInformation(pythonPackageVersion, pythonCommunicationVersion);
var communicationIsCompatible = CheckCommunicationVersionsAreCompatible(

2
com.unity.ml-agents/Runtime/Demonstrations/DemonstrationRecorder.cs


/// See [Imitation Learning - Recording Demonstrations] for more information.
///
/// [GameObject]: https://docs.unity3d.com/Manual/GameObjects.html
/// [Imitation Learning - Recording Demonstrations]: https://github.com/Unity-Technologies/ml-agents/blob/release_14_docs/docs//Learning-Environment-Design-Agents.md#recording-demonstrations
/// [Imitation Learning - Recording Demonstrations]: https://github.com/Unity-Technologies/ml-agents/blob/release_15_docs/docs//Learning-Environment-Design-Agents.md#recording-demonstrations
/// </remarks>
[RequireComponent(typeof(Agent))]
[AddComponentMenu("ML Agents/Demonstration Recorder", (int)MenuGroup.Default)]

2
com.unity.ml-agents/Runtime/Grpc/AssemblyInfo.cs


[assembly: InternalsVisibleTo("Unity.ML-Agents")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Editor")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Editor.Tests")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Runtime.Sensor.Tests")]
[assembly: InternalsVisibleTo("Unity.ML-Agents.Runtime.Utils.Tests")]

2
com.unity.ml-agents/Runtime/IMultiAgentGroup.cs


/// <summary>
/// Register agent to the MultiAgentGroup.
/// </summary>
/// <param name="agent">The Agent to register.</param>
/// <param name="agent">The Agent to unregister.</param>
void UnregisterAgent(Agent agent);
}
}

44
com.unity.ml-agents/Runtime/Inference/ApplierImpl.cs


}
/// <summary>
/// The Applier for the Discrete Action output tensor.
/// </summary>
internal class DiscreteActionOutputApplier : TensorApplier.IApplier
{
readonly ActionSpec m_ActionSpec;
public DiscreteActionOutputApplier(ActionSpec actionSpec, int seed, ITensorAllocator allocator)
{
m_ActionSpec = actionSpec;
}
public void Apply(TensorProxy tensorProxy, IList<int> actionIds, Dictionary<int, ActionBuffers> lastActions)
{
var agentIndex = 0;
var actionSize = tensorProxy.shape[tensorProxy.shape.Length - 1];
for (var i = 0; i < actionIds.Count; i++)
{
var agentId = actionIds[i];
if (lastActions.ContainsKey(agentId))
{
var actionBuffer = lastActions[agentId];
if (actionBuffer.IsEmpty())
{
actionBuffer = new ActionBuffers(m_ActionSpec);
lastActions[agentId] = actionBuffer;
}
var discreteBuffer = actionBuffer.DiscreteActions;
for (var j = 0; j < actionSize; j++)
{
discreteBuffer[j] = (int)tensorProxy.data[agentIndex, j];
}
}
agentIndex++;
}
}
}
/// <summary>
internal class DiscreteActionOutputApplier : TensorApplier.IApplier
internal class LegacyDiscreteActionOutputApplier : TensorApplier.IApplier
{
readonly int[] m_ActionSize;
readonly Multinomial m_Multinomial;

public DiscreteActionOutputApplier(ActionSpec actionSpec, int seed, ITensorAllocator allocator)
public LegacyDiscreteActionOutputApplier(ActionSpec actionSpec, int seed, ITensorAllocator allocator)
{
m_ActionSize = actionSpec.BranchSizes;
m_Multinomial = new Multinomial(seed);

70
com.unity.ml-agents/Runtime/Inference/BarracudaModelExtensions.cs


using System.Collections.Generic;
using System.Linq;
using Unity.Barracuda;
using FailedCheck = Unity.MLAgents.Inference.BarracudaModelParamLoader.FailedCheck;
namespace Unity.MLAgents.Inference
{

names.Sort();
return names.ToArray();
}
/// <summary>
/// Get the version of the model.
/// </summary>
/// <param name="model">
/// The Barracuda engine model for loading static parameters.
/// </param>
/// <returns>The api version of the model</returns>
public static int GetVersion(this Model model)
{
return (int)model.GetTensorByName(TensorNames.VersionNumber)[0];
}
/// <summary>

else
{
return model.outputs.Contains(TensorNames.DiscreteActionOutput) &&
(int)model.GetTensorByName(TensorNames.DiscreteActionOutputShape)[0] > 0;
(int)model.DiscreteOutputSize() > 0;
/// This method gets the tensor representing the list of branch size and returns the
/// sum of all the elements in the Tensor.
/// - In version 1.X this tensor contains a single number, the sum of all branch
/// size values.
/// - In version 2.X this tensor contains a 1D Tensor with each element corresponding
/// to a branch size.
/// Since this method does the sum of all elements in the tensor, the output
/// will be the same on both 1.X and 2.X.
/// </summary>
/// <param name="model">
/// The Barracuda engine model for loading static parameters.

else
{
var discreteOutputShape = model.GetTensorByName(TensorNames.DiscreteActionOutputShape);
return discreteOutputShape == null ? 0 : (int)discreteOutputShape[0];
if (discreteOutputShape == null)
{
return 0;
}
else
{
int result = 0;
for (int i = 0; i < discreteOutputShape.length; i++)
{
result += (int)discreteOutputShape[i];
}
return result;
}
}
}

/// <param name="failedModelChecks">Output list of failure messages</param>
///
/// <returns>True if the model contains all the expected tensors.</returns>
public static bool CheckExpectedTensors(this Model model, List<string> failedModelChecks)
public static bool CheckExpectedTensors(this Model model, List<FailedCheck> failedModelChecks)
failedModelChecks.Add($"Required constant \"{TensorNames.VersionNumber}\" was not found in the model file.");
failedModelChecks.Add(
FailedCheck.Warning($"Required constant \"{TensorNames.VersionNumber}\" was not found in the model file.")
);
return false;
}

{
failedModelChecks.Add($"Required constant \"{TensorNames.MemorySize}\" was not found in the model file.");
failedModelChecks.Add(
FailedCheck.Warning($"Required constant \"{TensorNames.MemorySize}\" was not found in the model file.")
);
return false;
}

!model.outputs.Contains(TensorNames.DiscreteActionOutput))
{
failedModelChecks.Add("The model does not contain any Action Output Node.");
failedModelChecks.Add(
FailedCheck.Warning("The model does not contain any Action Output Node.")
);
return false;
}

if (model.GetTensorByName(TensorNames.ActionOutputShapeDeprecated) == null)
{
failedModelChecks.Add("The model does not contain any Action Output Shape Node.");
failedModelChecks.Add(
FailedCheck.Warning("The model does not contain any Action Output Shape Node.")
);
failedModelChecks.Add($"Required constant \"{TensorNames.IsContinuousControlDeprecated}\" was not found in the model file. " +
"This is only required for model that uses a deprecated model format.");
failedModelChecks.Add(
FailedCheck.Warning($"Required constant \"{TensorNames.IsContinuousControlDeprecated}\" was " +
"not found in the model file. " +
"This is only required for model that uses a deprecated model format.")
);
return false;
}
}

model.GetTensorByName(TensorNames.ContinuousActionOutputShape) == null)
{
failedModelChecks.Add("The model uses continuous action but does not contain Continuous Action Output Shape Node.");
failedModelChecks.Add(
FailedCheck.Warning("The model uses continuous action but does not contain Continuous Action Output Shape Node.")
);
failedModelChecks.Add("The model uses discrete action but does not contain Discrete Action Output Shape Node.");
failedModelChecks.Add(
FailedCheck.Warning("The model uses discrete action but does not contain Discrete Action Output Shape Node.")
);
return false;
}
}

472
com.unity.ml-agents/Runtime/Inference/BarracudaModelParamLoader.cs


/// </summary>
internal class BarracudaModelParamLoader
{
const long k_ApiVersion = 2;
internal enum ModelApiVersion
{
MLAgents1_0 = 2,
MLAgents2_0 = 3,
MinSupportedVersion = MLAgents1_0,
MaxSupportedVersion = MLAgents2_0
}
internal class FailedCheck
{
public enum CheckTypeEnum
{
Info = 0,
Warning = 1,
Error = 2
}
public CheckTypeEnum CheckType;
public string Message;
public static FailedCheck Info(string message)
{
return new FailedCheck { CheckType = CheckTypeEnum.Info, Message = message };
}
public static FailedCheck Warning(string message)
{
return new FailedCheck { CheckType = CheckTypeEnum.Warning, Message = message };
}
public static FailedCheck Error(string message)
{
return new FailedCheck { CheckType = CheckTypeEnum.Error, Message = message };
}
}
/// <summary>
/// Factory for the ModelParamLoader : Creates a ModelParamLoader and runs the checks

/// <param name="actuatorComponents">Attached actuator components</param>
/// <param name="observableAttributeTotalSize">Sum of the sizes of all ObservableAttributes.</param>
/// <param name="behaviorType">BehaviorType or the Agent to check.</param>
/// <returns>The list the error messages of the checks that failed</returns>
public static IEnumerable<string> CheckModel(Model model, BrainParameters brainParameters,
ISensor[] sensors, ActuatorComponent[] actuatorComponents,
/// <returns>A IEnumerable of the checks that failed</returns>
public static IEnumerable<FailedCheck> CheckModel(
Model model,
BrainParameters brainParameters,
ISensor[] sensors,
ActuatorComponent[] actuatorComponents,
BehaviorType behaviorType = BehaviorType.Default)
BehaviorType behaviorType = BehaviorType.Default
)
List<string> failedModelChecks = new List<string>();
List<FailedCheck> failedModelChecks = new List<FailedCheck>();
if (model == null)
{
var errorMsg = "There is no model for this Brain; cannot run inference. ";

{
errorMsg += "(But can still train)";
}
failedModelChecks.Add(errorMsg);
failedModelChecks.Add(FailedCheck.Info(errorMsg));
return failedModelChecks;
}

return failedModelChecks;
}
var modelApiVersion = (int)model.GetTensorByName(TensorNames.VersionNumber)[0];
if (modelApiVersion == -1)
{
failedModelChecks.Add(
"Model was not trained using the right version of ML-Agents. " +
"Cannot use this model.");
return failedModelChecks;
}
if (modelApiVersion != k_ApiVersion)
var modelApiVersion = model.GetVersion();
if (modelApiVersion < (int)ModelApiVersion.MinSupportedVersion || modelApiVersion > (int)ModelApiVersion.MaxSupportedVersion)
$"Version of the trainer the model was trained with ({modelApiVersion}) " +
$"is not compatible with the Brain's version ({k_ApiVersion}).");
FailedCheck.Warning($"Version of the trainer the model was trained with ({modelApiVersion}) " +
$"is not compatible with the current range of supported versions: " +
$"({(int)ModelApiVersion.MinSupportedVersion} to {(int)ModelApiVersion.MaxSupportedVersion}).")
);
return failedModelChecks;
}

failedModelChecks.Add($"Missing node in the model provided : {TensorNames.MemorySize}");
failedModelChecks.Add(FailedCheck.Warning($"Missing node in the model provided : {TensorNames.MemorySize}"
));
if (modelApiVersion == (int)ModelApiVersion.MLAgents1_0)
{
failedModelChecks.AddRange(
CheckInputTensorPresenceLegacy(model, brainParameters, memorySize, sensors)
);
failedModelChecks.AddRange(
CheckInputTensorShapeLegacy(model, brainParameters, sensors, observableAttributeTotalSize)
);
}
else if (modelApiVersion == (int)ModelApiVersion.MLAgents2_0)
{
failedModelChecks.AddRange(
CheckInputTensorPresence(model, brainParameters, memorySize, sensors)
);
failedModelChecks.AddRange(
CheckInputTensorShape(model, brainParameters, sensors, observableAttributeTotalSize)
);
}
CheckInputTensorPresence(model, brainParameters, memorySize, sensors)
CheckOutputTensorShape(model, brainParameters, actuatorComponents)
failedModelChecks.AddRange(
CheckInputTensorShape(model, brainParameters, sensors, observableAttributeTotalSize)
);
failedModelChecks.AddRange(
CheckOutputTensorShape(model, brainParameters, actuatorComponents)
);
/// present in the BrainParameters.
/// present in the BrainParameters. Tests the models created with the API of version 1.X
/// </summary>
/// <param name="model">
/// The Barracuda engine model for loading static parameters

/// </param>
/// <param name="sensors">Array of attached sensor components</param>
/// <returns>
/// A IEnumerable of string corresponding to the failed input presence checks.
/// A IEnumerable of the checks that failed
static IEnumerable<string> CheckInputTensorPresence(
static IEnumerable<FailedCheck> CheckInputTensorPresenceLegacy(
Model model,
BrainParameters brainParameters,
int memory,

var failedModelChecks = new List<string>();
var failedModelChecks = new List<FailedCheck>();
var tensorsNames = model.GetInputNames();
// If there is no Vector Observation Input but the Brain Parameters expect one.

failedModelChecks.Add(
"The model does not contain a Vector Observation Placeholder Input. " +
"You must set the Vector Observation Space Size to 0.");
FailedCheck.Warning("The model does not contain a Vector Observation Placeholder Input. " +
"You must set the Vector Observation Space Size to 0.")
);
}
// If there are not enough Visual Observation Input compared to what the

{
var sensor = sensors[sensorIndex];
if (sensor.GetObservationShape().Length == 3)
if (sensor.GetObservationSpec().Shape.Length == 3)
"The model does not contain a Visual Observation Placeholder Input " +
$"for sensor component {visObsIndex} ({sensor.GetType().Name}).");
FailedCheck.Warning("The model does not contain a Visual Observation Placeholder Input " +
$"for sensor component {visObsIndex} ({sensor.GetType().Name}).")
);
if (sensor.GetObservationShape().Length == 2)
if (sensor.GetObservationSpec().Shape.Length == 2)
"The model does not contain an Observation Placeholder Input " +
$"for sensor component {sensorIndex} ({sensor.GetType().Name}).");
FailedCheck.Warning("The model does not contain an Observation Placeholder Input " +
$"for sensor component {sensorIndex} ({sensor.GetType().Name}).")
);
}
}

if (expectedVisualObs > visObsIndex)
{
failedModelChecks.Add(
$"The model expects {expectedVisualObs} visual inputs," +
$" but only found {visObsIndex} visual sensors."
);
FailedCheck.Warning($"The model expects {expectedVisualObs} visual inputs," +
$" but only found {visObsIndex} visual sensors.")
);
}
// If the model has a non-negative memory size but requires a recurrent input

!tensorsNames.Any(x => x.EndsWith("_c")))
{
failedModelChecks.Add(
"The model does not contain a Recurrent Input Node but has memory_size.");
FailedCheck.Warning("The model does not contain a Recurrent Input Node but has memory_size.")
);
}
}

if (!tensorsNames.Contains(TensorNames.ActionMaskPlaceholder))
{
failedModelChecks.Add(
"The model does not contain an Action Mask but is using Discrete Control.");
FailedCheck.Warning("The model does not contain an Action Mask but is using Discrete Control.")
);
}
}
return failedModelChecks;
}
/// <summary>
/// Generates failed checks that correspond to inputs expected by the model that are not
/// present in the BrainParameters.
/// </summary>
/// <param name="model">
/// The Barracuda engine model for loading static parameters
/// </param>
/// <param name="brainParameters">
/// The BrainParameters that are used verify the compatibility with the InferenceEngine
/// </param>
/// <param name="memory">
/// The memory size that the model is expecting.
/// </param>
/// <param name="sensors">Array of attached sensor components</param>
/// <returns>
/// A IEnumerable of the checks that failed
/// </returns>
static IEnumerable<FailedCheck> CheckInputTensorPresence(
Model model,
BrainParameters brainParameters,
int memory,
ISensor[] sensors
)
{
var failedModelChecks = new List<FailedCheck>();
var tensorsNames = model.GetInputNames();
for (var sensorIndex = 0; sensorIndex < sensors.Length; sensorIndex++)
{
if (!tensorsNames.Contains(
TensorNames.GetObservationName(sensorIndex)))
{
var sensor = sensors[sensorIndex];
failedModelChecks.Add(
FailedCheck.Warning("The model does not contain an Observation Placeholder Input " +
$"for sensor component {sensorIndex} ({sensor.GetType().Name}).")
);
}
}
// If the model has a non-negative memory size but requires a recurrent input
if (memory > 0)
{
if (!tensorsNames.Any(x => x.EndsWith("_h")) ||
!tensorsNames.Any(x => x.EndsWith("_c")))
{
failedModelChecks.Add(
FailedCheck.Warning("The model does not contain a Recurrent Input Node but has memory_size.")
);
}
}
// If the model uses discrete control but does not have an input for action masks
if (model.HasDiscreteOutputs())
{
if (!tensorsNames.Contains(TensorNames.ActionMaskPlaceholder))
{
failedModelChecks.Add(
FailedCheck.Warning("The model does not contain an Action Mask but is using Discrete Control.")
);
}
}
return failedModelChecks;

/// </param>
/// <param name="memory">The memory size that the model is expecting/</param>
/// <returns>
/// A IEnumerable of string corresponding to the failed output presence checks.
/// A IEnumerable of the checks that failed
static IEnumerable<string> CheckOutputTensorPresence(Model model, int memory)
static IEnumerable<FailedCheck> CheckOutputTensorPresence(Model model, int memory)
var failedModelChecks = new List<string>();
var failedModelChecks = new List<FailedCheck>();
// If there is no Recurrent Output but the model is Recurrent.
if (memory > 0)

!memOutputs.Any(x => x.EndsWith("_c")))
{
failedModelChecks.Add(
"The model does not contain a Recurrent Output Node but has memory_size.");
FailedCheck.Warning("The model does not contain a Recurrent Output Node but has memory_size.")
);
}
}
return failedModelChecks;

/// If the Check failed, returns a string containing information about why the
/// check failed. If the check passed, returns null.
/// </returns>
static string CheckVisualObsShape(
static FailedCheck CheckVisualObsShape(
var shape = sensor.GetObservationShape();
var shape = sensor.GetObservationSpec().Shape;
var heightBp = shape[0];
var widthBp = shape[1];
var pixelBp = shape[2];

if ((widthBp != widthT) || (heightBp != heightT) || (pixelBp != pixelT))
{
return $"The visual Observation of the model does not match. " +
return FailedCheck.Warning($"The visual Observation of the model does not match. " +
$"was expecting [?x{widthT}x{heightT}x{pixelT}].";
$"was expecting [?x{widthT}x{heightT}x{pixelT}] for the {sensor.GetName()} Sensor."
);
}
return null;
}

/// If the Check failed, returns a string containing information about why the
/// check failed. If the check passed, returns null.
/// </returns>
static string CheckRankTwoObsShape(
static FailedCheck CheckRankTwoObsShape(
var shape = sensor.GetObservationShape();
var shape = sensor.GetObservationSpec().Shape;
var dim3T = tensorProxy.Height;
return $"An Observation of the model does not match. " +
var proxyDimStr = $"[?x{dim1T}x{dim2T}]";
if (dim3T > 1)
{
proxyDimStr = $"[?x{dim3T}x{dim2T}x{dim1T}]";
}
return FailedCheck.Warning($"An Observation of the model does not match. " +
$"was expecting [?x{dim1T}x{dim2T}].";
$"was expecting {proxyDimStr} for the {sensor.GetName()} Sensor."
);
}
return null;
}
/// <summary>
/// Checks that the shape of the rank 2 observation input placeholder is the same as the corresponding sensor.
/// </summary>
/// <param name="tensorProxy">The tensor that is expected by the model</param>
/// <param name="sensor">The sensor that produces the visual observation.</param>
/// <returns>
/// If the Check failed, returns a string containing information about why the
/// check failed. If the check passed, returns null.
/// </returns>
static FailedCheck CheckRankOneObsShape(
TensorProxy tensorProxy, ISensor sensor)
{
var shape = sensor.GetObservationSpec().Shape;
var dim1Bp = shape[0];
var dim1T = tensorProxy.Channels;
var dim2T = tensorProxy.Width;
var dim3T = tensorProxy.Height;
if ((dim1Bp != dim1T))
{
var proxyDimStr = $"[?x{dim1T}]";
if (dim2T > 1)
{
proxyDimStr = $"[?x{dim1T}x{dim2T}]";
}
if (dim3T > 1)
{
proxyDimStr = $"[?x{dim3T}x{dim2T}x{dim1T}]";
}
return FailedCheck.Warning($"An Observation of the model does not match. " +
$"Received TensorProxy of shape [?x{dim1Bp}] but " +
$"was expecting {proxyDimStr} for the {sensor.GetName()} Sensor."
);
}
return null;
}

/// the model and the BrainParameters.
/// the model and the BrainParameters. Tests the models created with the API of version 1.X
/// </summary>
/// <param name="model">
/// The Barracuda engine model for loading static parameters

/// </param>
/// <param name="sensors">Attached sensors</param>
/// <param name="observableAttributeTotalSize">Sum of the sizes of all ObservableAttributes.</param>
/// <returns>The list the error messages of the checks that failed</returns>
static IEnumerable<string> CheckInputTensorShape(
/// <returns>A IEnumerable of the checks that failed</returns>
static IEnumerable<FailedCheck> CheckInputTensorShapeLegacy(
var failedModelChecks = new List<string>();
var failedModelChecks = new List<FailedCheck>();
new Dictionary<string, Func<BrainParameters, TensorProxy, ISensor[], int, string>>()
new Dictionary<string, Func<BrainParameters, TensorProxy, ISensor[], int, FailedCheck>>()
{TensorNames.VectorObservationPlaceholder, CheckVectorObsShape},
{TensorNames.VectorObservationPlaceholder, CheckVectorObsShapeLegacy},
{TensorNames.PreviousActionPlaceholder, CheckPreviousActionShape},
{TensorNames.RandomNormalEpsilonPlaceholder, ((bp, tensor, scs, i) => null)},
{TensorNames.ActionMaskPlaceholder, ((bp, tensor, scs, i) => null)},

for (var sensorIndex = 0; sensorIndex < sensors.Length; sensorIndex++)
{
var sens = sensors[sensorIndex];
if (sens.GetObservationShape().Length == 3)
if (sens.GetObservationSpec().Shape.Length == 3)
{
tensorTester[TensorNames.GetVisualObservationName(visObsIndex)] =

if (sens.GetObservationShape().Length == 2)
if (sens.GetObservationSpec().Shape.Length == 2)
{
tensorTester[TensorNames.GetObservationName(sensorIndex)] =
(bp, tensor, scs, i) => CheckRankTwoObsShape(tensor, sens);

if (!tensor.name.Contains("visual_observation"))
{
failedModelChecks.Add(
"Model requires an unknown input named : " + tensor.name);
FailedCheck.Warning("Model contains an unexpected input named : " + tensor.name)
);
}
}
else

/// <summary>
/// Checks that the shape of the Vector Observation input placeholder is the same in the
/// model and in the Brain Parameters.
/// model and in the Brain Parameters. Tests the models created with the API of version 1.X
/// </summary>
/// <param name="brainParameters">
/// The BrainParameters that are used verify the compatibility with the InferenceEngine

/// If the Check failed, returns a string containing information about why the
/// check failed. If the check passed, returns null.
/// </returns>
static string CheckVectorObsShape(
static FailedCheck CheckVectorObsShapeLegacy(
BrainParameters brainParameters, TensorProxy tensorProxy, ISensor[] sensors,
int observableAttributeTotalSize)
{

var totalVectorSensorSize = 0;
foreach (var sens in sensors)
{
if ((sens.GetObservationShape().Length == 1))
if ((sens.GetObservationSpec().Shape.Length == 1))
totalVectorSensorSize += sens.GetObservationShape()[0];
totalVectorSensorSize += sens.GetObservationSpec().Shape[0];
}
}

foreach (var sensorComp in sensors)
{
if (sensorComp.GetObservationShape().Length == 1)
if (sensorComp.GetObservationSpec().Shape.Length == 1)
var vecSize = sensorComp.GetObservationShape()[0];
var vecSize = sensorComp.GetObservationSpec().Shape[0];
if (sensorSizes.Length == 0)
{
sensorSizes = $"[{vecSize}";

}
sensorSizes += "]";
return $"Vector Observation Size of the model does not match. Was expecting {totalVecObsSizeT} " +
return FailedCheck.Warning(
$"Vector Observation Size of the model does not match. Was expecting {totalVecObsSizeT} " +
$"Sensor sizes: {sensorSizes}.";
$"Sensor sizes: {sensorSizes}."
);
/// <summary>
/// Generates failed checks that correspond to inputs shapes incompatibilities between
/// the model and the BrainParameters.
/// </summary>
/// <param name="model">
/// The Barracuda engine model for loading static parameters
/// </param>
/// <param name="brainParameters">
/// The BrainParameters that are used verify the compatibility with the InferenceEngine
/// </param>
/// <param name="sensors">Attached sensors</param>
/// <param name="observableAttributeTotalSize">Sum of the sizes of all ObservableAttributes.</param>
/// <returns>A IEnumerable of the checks that failed</returns>
static IEnumerable<FailedCheck> CheckInputTensorShape(
Model model, BrainParameters brainParameters, ISensor[] sensors,
int observableAttributeTotalSize)
{
var failedModelChecks = new List<FailedCheck>();
var tensorTester =
new Dictionary<string, Func<BrainParameters, TensorProxy, ISensor[], int, FailedCheck>>()
{
{TensorNames.PreviousActionPlaceholder, CheckPreviousActionShape},
{TensorNames.RandomNormalEpsilonPlaceholder, ((bp, tensor, scs, i) => null)},
{TensorNames.ActionMaskPlaceholder, ((bp, tensor, scs, i) => null)},
{TensorNames.SequenceLengthPlaceholder, ((bp, tensor, scs, i) => null)},
{TensorNames.RecurrentInPlaceholder, ((bp, tensor, scs, i) => null)},
};
foreach (var mem in model.memories)
{
tensorTester[mem.input] = ((bp, tensor, scs, i) => null);
}
for (var sensorIndex = 0; sensorIndex < sensors.Length; sensorIndex++)
{
var sens = sensors[sensorIndex];
if (sens.GetObservationSpec().Rank == 3)
{
tensorTester[TensorNames.GetObservationName(sensorIndex)] =
(bp, tensor, scs, i) => CheckVisualObsShape(tensor, sens);
}
if (sens.GetObservationSpec().Rank == 2)
{
tensorTester[TensorNames.GetObservationName(sensorIndex)] =
(bp, tensor, scs, i) => CheckRankTwoObsShape(tensor, sens);
}
if (sens.GetObservationSpec().Rank == 1)
{
tensorTester[TensorNames.GetObservationName(sensorIndex)] =
(bp, tensor, scs, i) => CheckRankOneObsShape(tensor, sens);
}
}
// If the model expects an input but it is not in this list
foreach (var tensor in model.GetInputTensors())
{
if (!tensorTester.ContainsKey(tensor.name))
{
failedModelChecks.Add(FailedCheck.Warning("Model contains an unexpected input named : " + tensor.name
));
}
else
{
var tester = tensorTester[tensor.name];
var error = tester.Invoke(brainParameters, tensor, sensors, observableAttributeTotalSize);
if (error != null)
{
failedModelChecks.Add(error);
}
}
}
return failedModelChecks;
}
/// <summary>
/// Checks that the shape of the Previous Vector Action input placeholder is the same in the
/// model and in the Brain Parameters.

/// <param name="observableAttributeTotalSize">Sum of the sizes of all ObservableAttributes (unused).</param>
/// <returns>If the Check failed, returns a string containing information about why the
/// check failed. If the check passed, returns null.</returns>
static string CheckPreviousActionShape(
static FailedCheck CheckPreviousActionShape(
BrainParameters brainParameters, TensorProxy tensorProxy,
ISensor[] sensors, int observableAttributeTotalSize)
{

{
return "Previous Action Size of the model does not match. " +
$"Received {numberActionsBp} but was expecting {numberActionsT}.";
return FailedCheck.Warning("Previous Action Size of the model does not match. " +
$"Received {numberActionsBp} but was expecting {numberActionsT}."
);
}
return null;
}

/// </param>
/// <param name="actuatorComponents">Array of attached actuator components.</param>
/// <returns>
/// A IEnumerable of string corresponding to the incompatible shapes between model
/// A IEnumerable of error messages corresponding to the incompatible shapes between model
static IEnumerable<string> CheckOutputTensorShape(
static IEnumerable<FailedCheck> CheckOutputTensorShape(
var failedModelChecks = new List<string>();
var failedModelChecks = new List<FailedCheck>();
// If the model expects an output but it is not in this list
var modelContinuousActionSize = model.ContinuousOutputSize();

failedModelChecks.Add(continuousError);
}
var modelSumDiscreteBranchSizes = model.DiscreteOutputSize();
var discreteError = CheckDiscreteActionOutputShape(brainParameters, actuatorComponents, modelSumDiscreteBranchSizes);
FailedCheck discreteError = null;
var modelApiVersion = model.GetVersion();
if (modelApiVersion == (int)ModelApiVersion.MLAgents1_0)
{
var modelSumDiscreteBranchSizes = model.DiscreteOutputSize();
discreteError = CheckDiscreteActionOutputShapeLegacy(brainParameters, actuatorComponents, modelSumDiscreteBranchSizes);
}
if (modelApiVersion == (int)ModelApiVersion.MLAgents2_0)
{
var modelDiscreteBranches = model.GetTensorByName(TensorNames.DiscreteActionOutputShape);
discreteError = CheckDiscreteActionOutputShape(brainParameters, actuatorComponents, modelDiscreteBranches);
}
if (discreteError != null)
{
failedModelChecks.Add(discreteError);

/// The BrainParameters that are used verify the compatibility with the InferenceEngine
/// </param>
/// <param name="actuatorComponents">Array of attached actuator components.</param>
/// <param name="modelDiscreteBranches"> The Tensor of branch sizes.
/// </param>
/// <returns>
/// If the Check failed, returns a string containing information about why the
/// check failed. If the check passed, returns null.
/// </returns>
static FailedCheck CheckDiscreteActionOutputShape(
BrainParameters brainParameters, ActuatorComponent[] actuatorComponents, Tensor modelDiscreteBranches)
{
var discreteActionBranches = brainParameters.ActionSpec.BranchSizes.ToList();
foreach (var actuatorComponent in actuatorComponents)
{
var actionSpec = actuatorComponent.ActionSpec;
discreteActionBranches.AddRange(actionSpec.BranchSizes);
}
int modelDiscreteBranchesLength = modelDiscreteBranches?.length ?? 0;
if (modelDiscreteBranchesLength != discreteActionBranches.Count)
{
return FailedCheck.Warning("Discrete Action Size of the model does not match. The BrainParameters expect " +
$"{discreteActionBranches.Count} branches but the model contains {modelDiscreteBranchesLength}."
);
}
for (int i = 0; i < modelDiscreteBranchesLength; i++)
{
if (modelDiscreteBranches[i] != discreteActionBranches[i])
{
return FailedCheck.Warning($"The number of Discrete Actions of branch {i} does not match. " +
$"Was expecting {discreteActionBranches[i]} but the model contains {modelDiscreteBranches[i]} "
);
}
}
return null;
}
/// <summary>
/// Checks that the shape of the discrete action output is the same in the
/// model and in the Brain Parameters. Tests the models created with the API of version 1.X
/// </summary>
/// <param name="brainParameters">
/// The BrainParameters that are used verify the compatibility with the InferenceEngine
/// </param>
/// <param name="actuatorComponents">Array of attached actuator components.</param>
/// <param name="modelSumDiscreteBranchSizes">
/// The size of the discrete action output that is expected by the model.
/// </param>

/// </returns>
static string CheckDiscreteActionOutputShape(
static FailedCheck CheckDiscreteActionOutputShapeLegacy(
BrainParameters brainParameters, ActuatorComponent[] actuatorComponents, int modelSumDiscreteBranchSizes)
{
// TODO: check each branch size instead of sum of branch sizes

if (modelSumDiscreteBranchSizes != sumOfDiscreteBranchSizes)
{
return "Discrete Action Size of the model does not match. The BrainParameters expect " +
$"{sumOfDiscreteBranchSizes} but the model contains {modelSumDiscreteBranchSizes}.";
return FailedCheck.Warning("Discrete Action Size of the model does not match. The BrainParameters expect " +
$"{sumOfDiscreteBranchSizes} but the model contains {modelSumDiscreteBranchSizes}."
);
}
return null;
}

/// </param>
/// <returns>If the Check failed, returns a string containing information about why the
/// check failed. If the check passed, returns null.</returns>
static string CheckContinuousActionOutputShape(
static FailedCheck CheckContinuousActionOutputShape(
BrainParameters brainParameters, ActuatorComponent[] actuatorComponents, int modelContinuousActionSize)
{
var numContinuousActions = brainParameters.ActionSpec.NumContinuousActions;

if (modelContinuousActionSize != numContinuousActions)
{
return "Continuous Action Size of the model does not match. The BrainParameters and ActuatorComponents expect " +
$"{numContinuousActions} but the model contains {modelContinuousActionSize}.";
return FailedCheck.Warning(
"Continuous Action Size of the model does not match. The BrainParameters and ActuatorComponents expect " +
$"{numContinuousActions} but the model contains {modelContinuousActionSize}."
);
}
return null;
}

10
com.unity.ml-agents/Runtime/Inference/TensorApplier.cs


if (actionSpec.NumDiscreteActions > 0)
{
var tensorName = model.DiscreteOutputName();
m_Dict[tensorName] = new DiscreteActionOutputApplier(actionSpec, seed, allocator);
var modelVersion = model.GetVersion();
if (modelVersion == (int)BarracudaModelParamLoader.ModelApiVersion.MLAgents1_0)
{
m_Dict[tensorName] = new LegacyDiscreteActionOutputApplier(actionSpec, seed, allocator);
}
if (modelVersion == (int)BarracudaModelParamLoader.ModelApiVersion.MLAgents2_0)
{
m_Dict[tensorName] = new DiscreteActionOutputApplier(actionSpec, seed, allocator);
}
}
m_Dict[TensorNames.RecurrentOutput] = new MemoryOutputApplier(memories);

93
com.unity.ml-agents/Runtime/Inference/TensorGenerator.cs


}
readonly Dictionary<string, IGenerator> m_Dict = new Dictionary<string, IGenerator>();
int m_ApiVersion;
/// <summary>
/// Returns a new TensorGenerators object.

return;
}
var model = (Model)barracudaModel;
m_ApiVersion = model.GetVersion();
// Generator for Inputs
m_Dict[TensorNames.BatchSizePlaceholder] =

public void InitializeObservations(List<ISensor> sensors, ITensorAllocator allocator)
{
// Loop through the sensors on a representative agent.
// All vector observations use a shared ObservationGenerator since they are concatenated.
// All other observations use a unique ObservationInputGenerator
var visIndex = 0;
ObservationGenerator vecObsGen = null;
for (var sensorIndex = 0; sensorIndex < sensors.Count; sensorIndex++)
if (m_ApiVersion == (int)BarracudaModelParamLoader.ModelApiVersion.MLAgents1_0)
{
// Loop through the sensors on a representative agent.
// All vector observations use a shared ObservationGenerator since they are concatenated.
// All other observations use a unique ObservationInputGenerator
var visIndex = 0;
ObservationGenerator vecObsGen = null;
for (var sensorIndex = 0; sensorIndex < sensors.Count; sensorIndex++)
{
var sensor = sensors[sensorIndex];
var rank = sensor.GetObservationSpec().Rank;
ObservationGenerator obsGen = null;
string obsGenName = null;
switch (rank)
{
case 1:
if (vecObsGen == null)
{
vecObsGen = new ObservationGenerator(allocator);
}
obsGen = vecObsGen;
obsGenName = TensorNames.VectorObservationPlaceholder;
break;
case 2:
// If the tensor is of rank 2, we use the index of the sensor
// to create the name
obsGen = new ObservationGenerator(allocator);
obsGenName = TensorNames.GetObservationName(sensorIndex);
break;
case 3:
// If the tensor is of rank 3, we use the "visual observation
// index", which only counts the rank 3 sensors
obsGen = new ObservationGenerator(allocator);
obsGenName = TensorNames.GetVisualObservationName(visIndex);
visIndex++;
break;
default:
throw new UnityAgentsException(
$"Sensor {sensor.GetName()} have an invalid rank {rank}");
}
obsGen.AddSensorIndex(sensorIndex);
m_Dict[obsGenName] = obsGen;
}
}
if (m_ApiVersion == (int)BarracudaModelParamLoader.ModelApiVersion.MLAgents2_0)
var sensor = sensors[sensorIndex];
var shape = sensor.GetObservationShape();
var rank = shape.Length;
ObservationGenerator obsGen = null;
string obsGenName = null;
switch (rank)
for (var sensorIndex = 0; sensorIndex < sensors.Count; sensorIndex++)
case 1:
if (vecObsGen == null)
{
vecObsGen = new ObservationGenerator(allocator);
}
obsGen = vecObsGen;
obsGenName = TensorNames.VectorObservationPlaceholder;
break;
case 2:
// If the tensor is of rank 2, we use the index of the sensor
// to create the name
obsGen = new ObservationGenerator(allocator);
obsGenName = TensorNames.GetObservationName(sensorIndex);
break;
case 3:
// If the tensor is of rank 3, we use the "visual observation
// index", which only counts the rank 3 sensors
obsGen = new ObservationGenerator(allocator);
obsGenName = TensorNames.GetVisualObservationName(visIndex);
visIndex++;
break;
default:
throw new UnityAgentsException(
$"Sensor {sensor.GetName()} have an invalid rank {rank}");
var obsGen = new ObservationGenerator(allocator);
var obsGenName = TensorNames.GetObservationName(sensorIndex);
obsGen.AddSensorIndex(sensorIndex);
m_Dict[obsGenName] = obsGen;
obsGen.AddSensorIndex(sensorIndex);
m_Dict[obsGenName] = obsGen;
}
}

12
com.unity.ml-agents/Runtime/Policies/BrainParameters.cs


internal bool hasUpgradedBrainParametersWithActionSpec;
/// <summary>
/// (Deprecated) The number of actions specified by this Brain.
/// </summary>
[Obsolete("NumActions has been deprecated, please use ActionSpec instead.")]
public int NumActions
{
get
{
return ActionSpec.NumContinuousActions > 0 ? ActionSpec.NumContinuousActions : ActionSpec.NumDiscreteActions;
}
}
/// <summary>
/// Deep clones the BrainParameter object.
/// </summary>
/// <returns> A new BrainParameter object with the same values as the original.</returns>

2
com.unity.ml-agents/Runtime/Policies/HeuristicPolicy.cs


{
if (sensor.GetCompressionType() == SensorCompressionType.None)
{
m_ObservationWriter.SetTarget(m_NullList, sensor.GetObservationShape(), 0);
m_ObservationWriter.SetTarget(m_NullList, sensor.GetObservationSpec(), 0);
sensor.Write(m_ObservationWriter);
}
else

部分文件因为文件数量过多而无法显示

正在加载...
取消
保存