浏览代码

Merge branch 'main' into goal-conditioning-sensors-3

/goal-conditioning/sensors-3-pytest-fix
vincentpierre 3 年前
当前提交
d4716caa
共有 174 个文件被更改,包括 1414 次插入1846 次删除
  1. 2
      .gitignore
  2. 100
      .yamato/com.unity.ml-agents-optional-dep-tests.yml
  3. 2
      .yamato/com.unity.ml-agents-pack.yml
  4. 254
      .yamato/com.unity.ml-agents-test.yml
  5. 6
      .yamato/test_versions.metafile
  6. 40
      DevProject/Packages/manifest.json
  7. 311
      DevProject/Packages/packages-lock.json
  8. 4
      DevProject/ProjectSettings/EditorBuildSettings.asset
  9. 4
      DevProject/ProjectSettings/ProjectVersion.txt
  10. 7
      Project/Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBall.demo.meta
  11. 7
      Project/Assets/ML-Agents/Examples/3DBall/Demos/Expert3DBallHard.demo.meta
  12. 7
      Project/Assets/ML-Agents/Examples/Basic/Demos/ExpertBasic.demo.meta
  13. 10
      Project/Assets/ML-Agents/Examples/Basic/Scripts/BasicSensorComponent.cs
  14. 7
      Project/Assets/ML-Agents/Examples/Crawler/Demos/ExpertCrawler.demo.meta
  15. 7
      Project/Assets/ML-Agents/Examples/GridWorld/Demos/ExpertGridWorld.demo.meta
  16. 7
      Project/Assets/ML-Agents/Examples/Hallway/Demos/ExpertHallway.demo.meta
  17. 1001
      Project/Assets/ML-Agents/Examples/Match3/TFModels/Match3VectorObs.onnx
  18. 7
      Project/Assets/ML-Agents/Examples/PushBlock/Demos/ExpertPushBlock.demo.meta
  19. 7
      Project/Assets/ML-Agents/Examples/Pyramids/Demos/ExpertPyramid.demo.meta
  20. 8
      Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/SensorBase.cs
  21. 7
      Project/Assets/ML-Agents/Examples/Walker/Demos/ExpertWalker.demo.meta
  22. 4
      Project/Assets/ML-Agents/TestScenes/TestCompressedTexture/TestTextureSensor.cs
  23. 22
      Project/Assets/ML-Agents/TestScenes/TestCompressedTexture/TestTextureSensorComponent.cs
  24. 40
      Project/Packages/manifest.json
  25. 16
      Project/ProjectSettings/EditorSettings.asset
  26. 4
      Project/ProjectSettings/GraphicsSettings.asset
  27. 114
      Project/ProjectSettings/ProjectSettings.asset
  28. 3
      Project/ProjectSettings/ProjectVersion.txt
  29. 12
      com.unity.ml-agents.extensions/Documentation~/com.unity.ml-agents.extensions.md
  30. 4
      com.unity.ml-agents.extensions/Editor/Input/InputActuatorComponentEditor.cs
  31. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs
  32. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs
  33. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs
  34. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs
  35. 4
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs
  36. 4
      com.unity.ml-agents.extensions/Runtime/Input/IInputActionAssetProvider.cs
  37. 4
      com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs
  38. 4
      com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs
  39. 4
      com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs
  40. 4
      com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs
  41. 161
      com.unity.ml-agents.extensions/Runtime/Match3/Match3Sensor.cs
  42. 26
      com.unity.ml-agents.extensions/Runtime/Match3/Match3SensorComponent.cs
  43. 24
      com.unity.ml-agents.extensions/Runtime/Sensors/ArticulationBodySensorComponent.cs
  44. 15
      com.unity.ml-agents.extensions/Runtime/Sensors/GridSensor.cs
  45. 10
      com.unity.ml-agents.extensions/Runtime/Sensors/PhysicsBodySensor.cs
  46. 24
      com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodySensorComponent.cs
  47. 164
      com.unity.ml-agents.extensions/Tests/Editor/Match3/Match3SensorTests.cs
  48. 10
      com.unity.ml-agents.extensions/Tests/Editor/Match3/match3obs0.png.meta
  49. 2
      com.unity.ml-agents.extensions/Tests/Editor/Match3/match3obs_special0.png
  50. 10
      com.unity.ml-agents.extensions/Tests/Editor/Match3/match3obs_special0.png.meta
  51. 19
      com.unity.ml-agents.extensions/Tests/Editor/Sensors/ChannelHotShapeTests.cs
  52. 15
      com.unity.ml-agents.extensions/Tests/Editor/Sensors/ChannelShapeTests.cs
  53. 27
      com.unity.ml-agents.extensions/Tests/Editor/Sensors/GridSensorTestUtils.cs
  54. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs
  55. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs
  56. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs
  57. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs
  58. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs
  59. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs
  60. 4
      com.unity.ml-agents.extensions/Tests/Runtime/Input/TestPushBlockActions.cs
  61. 14
      com.unity.ml-agents.extensions/Tests/Runtime/Sensors/ArticulationBodySensorTests.cs
  62. 14
      com.unity.ml-agents.extensions/Tests/Runtime/Sensors/RigidBodySensorTests.cs
  63. 5
      com.unity.ml-agents.extensions/package.json
  64. 20
      com.unity.ml-agents/CHANGELOG.md
  65. 2
      com.unity.ml-agents/Documentation~/com.unity.ml-agents.md
  66. 6
      com.unity.ml-agents/Editor/MLAgentsSettingsBuildProvider.cs
  67. 4
      com.unity.ml-agents/Editor/MLAgentsSettingsProvider.cs
  68. 16
      com.unity.ml-agents/Editor/RayPerceptionSensorComponentBaseEditor.cs
  69. 14
      com.unity.ml-agents/Editor/Unity.ML-Agents.Editor.asmdef
  70. 18
      com.unity.ml-agents/Runtime/Agent.cs
  71. 2
      com.unity.ml-agents/Runtime/Analytics/Events.cs
  72. 34
      com.unity.ml-agents/Runtime/Analytics/InferenceAnalytics.cs
  73. 49
      com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs
  74. 44
      com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs
  75. 1
      com.unity.ml-agents/Runtime/Inference/ModelRunner.cs
  76. 31
      com.unity.ml-agents/Runtime/Policies/BarracudaPolicy.cs
  77. 2
      com.unity.ml-agents/Runtime/Policies/BehaviorParameters.cs
  78. 4
      com.unity.ml-agents/Runtime/Policies/HeuristicPolicy.cs
  79. 14
      com.unity.ml-agents/Runtime/Policies/RemotePolicy.cs
  80. 6
      com.unity.ml-agents/Runtime/Sensors/BufferSensor.cs
  81. 10
      com.unity.ml-agents/Runtime/Sensors/BufferSensorComponent.cs
  82. 5
      com.unity.ml-agents/Runtime/Sensors/CameraSensor.cs
  83. 21
      com.unity.ml-agents/Runtime/Sensors/CameraSensorComponent.cs
  84. 24
      com.unity.ml-agents/Runtime/Sensors/ISensor.cs
  85. 14
      com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensor.cs
  86. 9
      com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponent2D.cs
  87. 24
      com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponentBase.cs
  88. 5
      com.unity.ml-agents/Runtime/Sensors/Reflection/ReflectionSensorBase.cs
  89. 5
      com.unity.ml-agents/Runtime/Sensors/RenderTextureSensor.cs
  90. 22
      com.unity.ml-agents/Runtime/Sensors/RenderTextureSensorComponent.cs
  91. 13
      com.unity.ml-agents/Runtime/Sensors/SensorComponent.cs
  92. 27
      com.unity.ml-agents/Runtime/Sensors/StackingSensor.cs
  93. 6
      com.unity.ml-agents/Runtime/Sensors/VectorSensor.cs
  94. 10
      com.unity.ml-agents/Runtime/Unity.ML-Agents.asmdef
  95. 7
      com.unity.ml-agents/Runtime/Utilities.cs
  96. 6
      com.unity.ml-agents/Tests/Editor/AcademyTests.cs
  97. 12
      com.unity.ml-agents/Tests/Editor/Analytics/TrainingAnalyticsTest.cs
  98. 137
      com.unity.ml-agents/Tests/Editor/Communicator/GrpcExtensionsTests.cs
  99. 4
      com.unity.ml-agents/Tests/Editor/Inference/ModelRunnerTest.cs

2
.gitignore


.coverage
coverage.xml
/htmlcov/
**/UserSettings/*

100
.yamato/com.unity.ml-agents-optional-dep-tests.yml


OptionalDependencyTestsLinux:
name : LinuxOptionalDependenciesTests
agent:
type: Unity::VM
image: package-ci/ubuntu:stable
flavor: b1.medium
commands:
- |
curl -L https://artifactory.prd.it.unity3d.com/artifactory/api/gpg/key/public | sudo apt-key add -
sudo sh -c "echo 'deb https://artifactory.prd.it.unity3d.com/artifactory/unity-apt-local bionic main' > /etc/apt/sources.list.d/unity.list"
sudo apt update
sudo apt install -y unity-config
npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
unity-config settings editor-path ./.Editor
unity-config project create opt-deps-test
unity-config project add dependency com.unity.ml-agents/
unity-config project add testable com.unity.ml-agents
unity-config project add dependency com.unity.modules.imageconversion@1.0.0
unity-config project add dependency com.unity.modules.jsonserialize@1.0.0
unity-config project add dependency com.unity.modules.physics@1.0.0
unity-config project add dependency com.unity.modules.physics2d@1.0.0
upm-ci project test -u 2019.4 --type project-tests --project-path opt-deps-test --package-filter com.unity.ml-agents
artifacts:
logs:
paths:
- "upm-ci~/test-results/**/*"
dependencies:
- .yamato/com.unity.ml-agents-pack.yml#pack
triggers:
cancel_old_ci: true
expression: |
(pull_request.target eq "main" OR
pull_request.target match "release.+") AND
NOT pull_request.draft AND
(pull_request.changes.any match "com.unity.ml-agents/**" OR
pull_request.changes.any match ".yamato/com.unity.ml-agents-test.yml")
optional_deps:
- name: Analytics
project: "OptionalDepedencyTests/NoAnalyticsModule"
version: 2020.2
- name: Physics
project: OptionalDepedencyTests/NoPhysicsModule
version: 2020.2
- name: Physics2D
project: OptionalDepedencyTests/NoPhysics2DModule
version: 2020.2
---
{% for optional_dep in optional_deps %}
OptionalDependencyTests_{{ optional_dep.name }}:
name : Test Optional Package Dependencies {{ optional_dep.name }}
agent:
type: Unity::VM
image: package-ci/ubuntu:stable
flavor: b1.medium
commands:
- |
curl -L https://artifactory.prd.it.unity3d.com/artifactory/api/gpg/key/public | sudo apt-key add -
sudo sh -c "echo 'deb https://artifactory.prd.it.unity3d.com/artifactory/unity-apt-local bionic main' > /etc/apt/sources.list.d/unity.list"
sudo apt update
sudo apt install -y unity-config
npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
unity-config settings editor-path ./.Editor
unity-config project create opt-deps-test
unity-config project add dependency com.unity.ml-agents/
unity-config project add testable com.unity.ml-agents
unity-config project add dependency com.unity.modules.imageconversion@1.0.0
unity-config project add dependency com.unity.modules.jsonserialize@1.0.0
{% unless optional_dep.name == "Physics" %}
unity-config project add dependency com.unity.modules.physics@1.0.0
{% endunless %}
{% unless optional_dep.name == "Physics2D" %}
unity-config project add dependency com.unity.modules.physics2d@1.0.0
{% endunless %}
{% unless optional_dep.name == "Analytics" %}
unity-config project add dependency com.unity.modules.unityanalytics@1.0.0
{% endunless %}
upm-ci project test -u {{ optional_dep.version }} --type project-tests --project-path opt-deps-test --package-filter com.unity.ml-agents
artifacts:
logs:
paths:
- "upm-ci~/test-results/**/*"
dependencies:
- .yamato/com.unity.ml-agents-pack.yml#pack
{% for coverage_editor in coverage_test_editors %}
{% for coverage_platform in coverage_test_platforms %}
{% for coverage_package in coverage_test_packages %}
- .yamato/com.unity.ml-agents-coverage.yml#test_coverage_{{ coverage_package.name }}_{{ coverage_platform.name }}_{{ coverage_editor.version }}
{% endfor %}
{% endfor %}
{% endfor %}
triggers:
cancel_old_ci: true
expression: |
(pull_request.target eq "main" OR
pull_request.target match "release.+") AND
NOT pull_request.draft AND
(pull_request.changes.any match "com.unity.ml-agents/**" OR
pull_request.changes.any match ".yamato/com.unity.ml-agents-test.yml")
{% endfor %}

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

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


{% metadata_file .yamato/coverage_tests.metafile %}
- 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+
testProject: Project
enableNoDefaultPackages: !!bool false
- version: 2019.4
enableCodeCoverage: !!bool true
testProject: DevProject
enableNoDefaultPackages: !!bool true
- version: 2020.2
enableCodeCoverage: !!bool true
testProject: DevProject
enableNoDefaultPackages: !!bool true
- version: 2019.4
# We want some scene tests to run in the DevProject, but packages there only support 2020+
testProject: Project
enableNoDefaultPackages: !!bool true
- version: 2020.2
testProject: DevProject
enableNoDefaultPackages: !!bool true
- version: 2021.1
testProject: DevProject
enableNoDefaultPackages: !!bool true
- version: trunk
# Workaround for MLA-1596 - need to make sure we load the right results.
enableCodeCoverage: !!bool false
testProject: DevProject
- version: trunk
# Workaround for MLA-1596 - need to make sure we load the right results.
testProject: DevProject
- name: win
type: Unity::VM
image: package-ci/win10:stable
flavor: b1.large
- name: mac
type: Unity::VM::osx
image: package-ci/mac:stable
flavor: b1.small
- name: linux
type: Unity::VM
image: package-ci/ubuntu:stable
flavor: b1.medium
- name: win
type: Unity::VM
image: package-ci/win10:stable
flavor: b1.large
- name: mac
type: Unity::VM::osx
image: package-ci/mac:stable
flavor: b1.small
- name: linux
type: Unity::VM
image: package-ci/ubuntu:stable
flavor: b1.medium
- name: com.unity.ml-agents
assembly: Unity.ML-Agents
minCoveragePct: 72
- name: com.unity.ml-agents.extensions
assembly: Unity.ML-Agents.Extensions*
minCoveragePct: 75
- name: com.unity.ml-agents
assembly: Unity.ML-Agents
minCoveragePct: 72
- name: com.unity.ml-agents.extensions
assembly: Unity.ML-Agents.Extensions*
minCoveragePct: 75
name: Run All Combinations of Editors/Platforms Tests
dependencies:
{% for editor in test_editors %}
{% for platform in test_platforms %}
- .yamato/com.unity.ml-agents-test.yml#test_com.unity.ml-agents_{{ platform.name }}_{{ editor.version }}
{% endfor %}
{% endfor %}
name: Run All Combinations of Editors/Platforms Tests
dependencies:
{% for coverage_editor in coverage_test_editors %}
{% for coverage_platform in coverage_test_platforms %}
{% for coverage_package in coverage_test_packages %}
- .yamato/com.unity.ml-agents-coverage.yml#test_coverage_{{ coverage_package.name }}_{{ coverage_platform.name }}_{{ coverage_editor.version }}
{% endfor %}
{% endfor %}
{% endfor %}
{% for editor in test_editors %}
{% for platform in test_platforms %}
- .yamato/com.unity.ml-agents-test.yml#test_com.unity.ml-agents_{{ platform.name }}_{{ editor.version }}
{% endfor %}
{% endfor %}
{% for editor in trunk_editor %}
{% for platform in test_platforms %}
- .yamato/com.unity.ml-agents-test.yml#test_com.unity.ml-agents_{{ platform.name }}_{{ editor.version }}
{% endfor %}
{% endfor %}
triggers:
cancel_old_ci: true
recurring:
- branch: main
frequency: daily
{% for editor in trunk_editor %}
{% for platform in test_platforms %}
- .yamato/com.unity.ml-agents-test.yml#test_com.unity.ml-agents_{{ platform.name }}_{{ editor.version }}
{% endfor %}
{% endfor %}
triggers:
cancel_old_ci: true
recurring:
- branch: main
frequency: daily
{% for package in packages %}
{% for package in packages %}
{% for platform in test_platforms %}
{% for platform in test_platforms %}
{% if editor.enableCodeCoverage %}
{% capture coverageOptions %} --enable-code-coverage --code-coverage-options 'generateHtmlReport;assemblyFilters:+{{ package.assembly }}'{% endcapture %}
{% else %}
{% assign coverageOptions = "" %}
{% endif %}
{% if editor.enableNoDefaultPackages %}
{% if editor.enableNoDefaultPackages %}
{% else %}
{% else %}
{% endif %}
{% endif %}
name : {{ package.name }} test {{ editor.version }} on {{ platform.name }}
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.flavor}}
commands:
- npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
- upm-ci project test -u {{ editor.version }} --project-path {{ editor.testProject }} --package-filter {{ package.name }} {{ coverageOptions }} {{ noDefaultPackagesOptions }} --extra-utr-arg "reruncount=2"
{% if editor.enableCodeCoverage %}
- python3 ml-agents/tests/yamato/check_coverage_percent.py upm-ci~/test-results/ {{ package.minCoveragePct }}
{% endif %}
artifacts:
logs:
paths:
- "upm-ci~/test-results/**/*"
dependencies:
- .yamato/com.unity.ml-agents-pack.yml#pack
triggers:
cancel_old_ci: true
{% if platform.name == "linux" %}
expression: |
(pull_request.target eq "main" OR
pull_request.target match "release.+") AND
NOT pull_request.draft AND
(pull_request.changes.any match "com.unity.ml-agents/**" OR
pull_request.changes.any match " {{ editor.testProject }}/**" OR
{% if package.name == "com.unity.ml-agents.extensions" %}
pull_request.changes.any match "com.unity.ml-agents.extensions/**" OR
name : {{ package.name }} test {{ editor.version }} on {{ platform.name }}
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.flavor}}
commands:
- npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
- upm-ci project test -u {{ editor.version }} --project-path {{ editor.testProject }} --package-filter {{ package.name }} {{ noDefaultPackagesOptions }} --extra-utr-arg "reruncount=2"
artifacts:
logs:
paths:
- "upm-ci~/test-results/**/*"
dependencies:
- .yamato/com.unity.ml-agents-pack.yml#pack
{% for coverage_editor in coverage_test_editors %}
{% for coverage_platform in coverage_test_platforms %}
{% for coverage_package in coverage_test_packages %}
- .yamato/com.unity.ml-agents-coverage.yml#test_coverage_{{ coverage_package.name }}_{{ coverage_platform.name }}_{{ coverage_editor.version }}
{% endfor %}
{% endfor %}
{% endfor %}
triggers:
cancel_old_ci: true
{% if platform.name == "linux" %}
expression: |
(pull_request.target eq "main" OR
pull_request.target match "release.+") AND
NOT pull_request.draft AND
(pull_request.changes.any match "com.unity.ml-agents/**" OR
pull_request.changes.any match " {{ editor.testProject }}/**" OR
{% if package.name == "com.unity.ml-agents.extensions" %}
pull_request.changes.any match "com.unity.ml-agents.extensions/**" OR
{% endif %}
pull_request.changes.any match ".yamato/com.unity.ml-agents-test.yml")
pull_request.changes.any match ".yamato/com.unity.ml-agents-test.yml")
{% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endfor %}
{% for package in packages %}
{% for package in packages %}
{% for platform in test_platforms %}
{% for platform in test_platforms %}
{% if editor.enableCodeCoverage %}
{% capture coverageOptions %} --enable-code-coverage --code-coverage-options 'generateHtmlReport;assemblyFilters:+{{ package.assembly }}'{% endcapture %}
{% else %}
{% assign coverageOptions = "" %}
{% endif %}
name : {{ package.name }} test {{ editor.version }} on {{ platform.name }}
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.flavor}}
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 trunk -c editor --wait --fast
- npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
- upm-ci project test -u {{ editor.version }} --project-path {{ editor.testProject }} --package-filter {{ package.name }} {{ coverageOptions }} --extra-create-project-arg="-upmNoDefaultPackages" --extra-utr-arg "reruncount=2"
{% if editor.enableCodeCoverage %}
- python3 ml-agents/tests/yamato/check_coverage_percent.py upm-ci~/test-results/ {{ package.minCoveragePct }}
{% endif %}
artifacts:
logs:
paths:
- "upm-ci~/test-results/**/*"
dependencies:
- .yamato/com.unity.ml-agents-pack.yml#pack
triggers:
cancel_old_ci: true
{% endfor %}
name : {{ package.name }} test {{ editor.version }} on {{ platform.name }}
agent:
type: {{ platform.type }}
image: {{ platform.image }}
flavor: {{ platform.flavor}}
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 trunk -c editor --wait --fast
- npm install upm-ci-utils@stable -g --registry https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-npm
- upm-ci project test -u {{ editor.version }} --project-path {{ editor.testProject }} --package-filter {{ package.name }} --extra-create-project-arg="-upmNoDefaultPackages" --extra-utr-arg "reruncount=2"
artifacts:
logs:
paths:
- "upm-ci~/test-results/**/*"
dependencies:
- .yamato/com.unity.ml-agents-pack.yml#pack
{% for coverage_editor in coverage_test_editors %}
{% for coverage_platform in coverage_test_platforms %}
{% for coverage_package in coverage_test_packages %}
- .yamato/com.unity.ml-agents-coverage.yml#test_coverage_{{ coverage_package.name }}_{{ coverage_platform.name }}_{{ coverage_editor.version }}
{% endfor %}
{% endfor %}
{% endfor %}
triggers:
cancel_old_ci: true
{% endfor %}
{% endfor %}
{% endfor %}

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

40
DevProject/Packages/manifest.json


{
"dependencies": {
"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.collab-proxy": "1.2.16",
"com.unity.ide.rider": "1.1.4",
"com.unity.ide.vscode": "1.2.3",
"com.unity.multiplayer-hlapi": "1.0.8",
"com.unity.purchasing": "2.2.1",
"com.unity.textmeshpro": "2.0.1",
"com.unity.timeline": "1.2.12",
"com.unity.ugui": "1.0.0",
"com.unity.xr.legacyinputhelpers": "2.1.7",
"com.unity.modules.ai": "1.0.0",
"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.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "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.modules.unityanalytics": "1.0.0"
},
"registry": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates",
"testables": [

311
DevProject/Packages/packages-lock.json


{
"dependencies": {
"com.unity.2d.sprite": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.2d.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.ads": {
"version": "3.6.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.analytics": {
"version": "3.3.5",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"version": "1.3.1-preview",
"version": "1.3.2-preview",
"depth": 1,
"source": "registry",
"dependencies": {

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

"dependencies": {},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.ide.rider": {
"version": "1.1.4",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.1"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.ide.vscode": {
"version": "1.2.3",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.inputsystem": {
"version": "1.1.0-preview.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": {
"version": "1.0.8",
"depth": 0,
"source": "registry",
"dependencies": {
"nuget.mono-cecil": "0.1.6-preview"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.nuget.mono-cecil": {
"version": "0.1.6-preview.2",

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

},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.textmeshpro": {
"version": "2.0.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.timeline": {
"version": "1.2.12",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.ugui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.xr.legacyinputhelpers": {
"version": "2.1.7",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.xr": "1.0.0"
},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"nuget.castle-core": {
"version": "1.0.1",
"depth": 2,

},
"nuget.mono-cecil": {
"version": "0.1.6-preview",
"depth": 1,
"depth": 2,
"source": "registry",
"dependencies": {},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"

},
"url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates"
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,

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

"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"com.unity.modules.ui": {
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"com.unity.modules.uielements": {
"com.unity.modules.physics2d": "1.0.0"
"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.ui": {
"com.unity.modules.uielementsnative": {
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"depth": 1,
"com.unity.modules.ui": "1.0.0",
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",

},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"depth": 1,
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "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}

4
DevProject/ProjectSettings/ProjectVersion.txt


m_EditorVersion: 2019.4.20f1
m_EditorVersionWithRevision: 2019.4.20f1 (6dd1c08eedfa)
m_EditorVersion: 2020.3.0f1
m_EditorVersionWithRevision: 2020.3.0f1 (c7b5465681fb)

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:

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


/// Creates a BasicSensor.
/// </summary>
/// <returns></returns>
public override ISensor CreateSensor()
{
return new BasicSensor(basicController);
}
/// <inheritdoc/>
public override int[] GetObservationShape()
public override ISensor[] CreateSensors()
return new[] { BasicController.k_Extents };
return new ISensor[] { new BasicSensor(basicController) };
}
}

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:

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:

1001
Project/Assets/ML-Agents/Examples/Match3/TFModels/Match3VectorObs.onnx
文件差异内容过多而无法显示
查看文件

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:

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


{
/// <summary>
/// Write the observations to the output buffer. This size of the buffer will be product
/// of the sizes returned by <see cref="GetObservationShape"/>.
/// of the Shape array values returned by <see cref="ObservationSpec"/>.
/// </summary>
/// <param name="output"></param>
public abstract void WriteObservation(float[] output);

/// <returns>The number of elements written.</returns>
public virtual int Write(ObservationWriter writer)
{
// TODO reuse buffer for similar agents, don't call GetObservationShape()
// TODO reuse buffer for similar agents
var numFloats = this.ObservationSize();
float[] buffer = new float[numFloats];
WriteObservation(buffer);

}
/// <inheritdoc/>
public virtual SensorCompressionType GetCompressionType()
public virtual CompressionSpec GetCompressionSpec()
return SensorCompressionType.None;
return CompressionSpec.Default();
}
}
}

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:

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


public void Reset() { }
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return m_CompressionType;
return CompressionSpec.Default();
}
}

22
Project/Assets/ML-Agents/TestScenes/TestCompressedTexture/TestTextureSensorComponent.cs


/// <inheritdoc/>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return new StackingSensor(m_Sensor, ObservationStacks);
}
return m_Sensor;
}
/// <inheritdoc/>
public override int[] GetObservationShape()
{
var width = TestTexture.width;
var height = TestTexture.height;
var observationShape = new[] { height, width, 3 };
var stacks = ObservationStacks > 1 ? ObservationStacks : 1;
if (stacks > 1)
{
observationShape[2] *= stacks;
return new ISensor[] { new StackingSensor(m_Sensor, ObservationStacks) };
return observationShape;
return new ISensor[] { m_Sensor };
}
}

40
Project/Packages/manifest.json


{
"dependencies": {
"com.unity.ads": "2.0.8",
"com.unity.collab-proxy": "1.2.15",
"com.unity.ide.rider": "3.0.5",
"com.unity.inputsystem": "1.1.0-preview.3",
"com.unity.package-manager-ui": "2.0.13",
"com.unity.textmeshpro": "1.4.1",
"com.unity.modules.ai": "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.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.nuget.newtonsoft-json": "2.0.0",
"com.unity.test-framework": "1.1.22",
"com.unity.toolchain.macos-x86_64-linux-x86_64": "0.1.20-preview",
"com.unity.ugui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "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.unityanalytics": "1.0.0"
"com.unity.ml-agents.extensions"
"com.unity.ml-agents.extensions",
"com.unity.inputsystem"
]
}

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

4
Project/ProjectSettings/GraphicsSettings.asset


--- !u!30 &1
GraphicsSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
serializedVersion: 13
m_Deferred:
m_Mode: 1
m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}

- {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16001, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 16002, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
type: 0}

m_LightsUseLinearIntensity: 0
m_LightsUseColorTemperature: 0
m_LogWhenShaderIsCompiled: 0
m_AllowEnlightenSupportForUpgradedProject: 1

114
Project/ProjectSettings/ProjectSettings.asset


--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 18
serializedVersion: 20
productGUID: cd7e9a0e0d1d14312ad9e89757262f3b
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0

defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
m_ShowUnitySplashScreen: 1
m_ShowUnitySplashScreen: 0
m_ShowUnitySplashLogo: 1
m_SplashScreenOverlayOpacity: 1
m_SplashScreenAnimation: 1

m_StackTraceTypes: 010000000100000001000000010000000100000001000000
iosShowActivityIndicatorOnLoading: -1
androidShowActivityIndicatorOnLoading: -1
displayResolutionDialog: 0
iosUseCustomAppBackgroundBehavior: 0
iosAllowHTTPDownload: 1
allowedAutorotateToPortrait: 1

disableDepthAndStencilBuffers: 0
androidStartInFullscreen: 1
androidRenderOutsideSafeArea: 0
androidUseSwappy: 0
androidBlitType: 0
defaultIsNativeResolution: 1
macRetinaSupport: 1

usePlayerLog: 1
bakeCollisionMeshes: 1
forceSingleInstance: 0
useFlipModelSwapchain: 1
graphicsJobs: 0
xboxPIXTextureCapture: 0
xboxEnableAvatar: 0
xboxEnableKinect: 0

allowFullscreenSwitch: 1
graphicsJobMode: 0
fullscreenMode: 3
xboxSpeechDB: 0
xboxEnableHeadOrientation: 0

switchNVNShaderPoolsGranularity: 33554432
switchNVNDefaultPoolsGranularity: 16777216
switchNVNOtherPoolsGranularity: 16777216
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
stadiaPresentMode: 0
stadiaTargetFramerate: 0
vulkanNumSwapchainBuffers: 3
vulkanEnableLateAcquireNextImage: 0
m_SupportedAspectRatios:
4:3: 1
5:4: 1

m_HolographicPauseOnTrackingLoss: 1
xboxOneDisableKinectGpuReservation: 0
xboxOneEnable7thCore: 0
isWsaHolographicRemotingEnabled: 0
vrSettings:
cardboard:
depthFormat: 0

hololens:
depthFormat: 1
depthBufferSharingEnabled: 0
lumin:
depthFormat: 0
frameTiming: 2
enableGLCache: 0
glCacheMaxBlobSize: 524288
glCacheMaxFileSize: 8388608
oculus:
sharedDepthBuffer: 0
dashSupport: 0

enable360StereoCapture: 0
protectGraphicsMemory: 0
isWsaHolographicRemotingEnabled: 0
D3DHDRBitDepth: 0
m_ColorGamuts: 00000000
targetPixelDensity: 30
resolutionScalingMode: 0

Android: com.Company.ProductName
buildNumber:
iOS: 0
iPhone: 0
AndroidMinSdkVersion: 16
AndroidMinSdkVersion: 19
aotOptions:
aotOptions: nimt-trampolines=1024
stripEngineCode: 1
iPhoneStrippingLevel: 0
iPhoneScriptCallOptimization: 0

StripUnusedMeshComponents: 0
VertexChannelCompressionMask: 214
iPhoneSdkVersion: 988
iOSTargetOSVersionString: 9.0
iOSTargetOSVersionString: 10.0
tvOSTargetOSVersionString: 9.0
tvOSTargetOSVersionString: 10.0
uIPrerenderedIcon: 0
uIRequiresPersistentWiFi: 0
uIRequiresFullScreen: 1

iPhoneSplashScreen: {fileID: 0}
iPhoneHighResSplashScreen: {fileID: 0}
iPhoneTallHighResSplashScreen: {fileID: 0}
iPhone47inSplashScreen: {fileID: 0}
iPhone55inPortraitSplashScreen: {fileID: 0}
iPhone55inLandscapeSplashScreen: {fileID: 0}
iPhone58inPortraitSplashScreen: {fileID: 0}
iPhone58inLandscapeSplashScreen: {fileID: 0}
iPadPortraitSplashScreen: {fileID: 0}
iPadHighResPortraitSplashScreen: {fileID: 0}
iPadLandscapeSplashScreen: {fileID: 0}
iPadHighResLandscapeSplashScreen: {fileID: 0}
appleTVSplashScreen: {fileID: 0}
appleTVSplashScreen2x: {fileID: 0}
tvOSSmallIconLayers: []

metalEditorSupport: 1
metalAPIValidation: 1
iOSRenderExtraFrameOnPause: 1
iosCopyPluginsCodeInsteadOfSymlink: 0
appleDeveloperTeamID:
iOSManualSigningProvisioningProfileID:
tvOSManualSigningProvisioningProfileID:

AndroidEnableTango: 0
androidEnableBanner: 1
androidUseLowAccuracyLocation: 0
androidUseCustomKeystore: 0
resolutionDialogBanner: {fileID: 0}
AndroidValidateAppBundleSize: 1
AndroidAppBundleSizeToValidate: 150
m_BuildTargetGraphicsJobs:
- m_BuildTarget: MacStandaloneSupport
m_GraphicsJobs: 0
- m_BuildTarget: Switch
m_GraphicsJobs: 0
- m_BuildTarget: MetroSupport
m_GraphicsJobs: 0
- m_BuildTarget: AppleTVSupport
m_GraphicsJobs: 0
- m_BuildTarget: BJMSupport
m_GraphicsJobs: 0
- m_BuildTarget: LinuxStandaloneSupport
m_GraphicsJobs: 0
- m_BuildTarget: PS4Player
m_GraphicsJobs: 0
- m_BuildTarget: iOSSupport
m_GraphicsJobs: 0
- m_BuildTarget: WindowsStandaloneSupport
m_GraphicsJobs: 0
- m_BuildTarget: XboxOnePlayer
m_GraphicsJobs: 0
- m_BuildTarget: LuminSupport
m_GraphicsJobs: 0
- m_BuildTarget: CloudRendering
m_GraphicsJobs: 0
- m_BuildTarget: AndroidPlayer
m_GraphicsJobs: 0
- m_BuildTarget: WebGLSupport
m_GraphicsJobs: 0
m_BuildTargetGraphicsJobMode:
- m_BuildTarget: PS4Player
m_GraphicsJobMode: 0
- m_BuildTarget: XboxOnePlayer
m_GraphicsJobMode: 0
m_BuildTargetEnableVuforiaSettings: []
openGLRequireES32: 0
m_TemplateCustomTags: {}
mobileMTRendering:
Android: 1

ps4ShareFilePath:
ps4ShareOverlayImagePath:
ps4PrivacyGuardImagePath:
ps4ExtraSceSysFile:
ps4NPtitleDatPath:
ps4RemotePlayKeyAssignment: -1
ps4RemotePlayKeyMappingDir:

ps4DownloadDataSize: 0
ps4GarlicHeapSize: 2048
ps4ProGarlicHeapSize: 2560
playerPrefsMaxSize: 32768
ps4Passcode: uGXbEWRK5RhRXdCdG5nG5azdNMK66MuC
ps4pnSessions: 1
ps4pnPresence: 1

ps4UseResolutionFallback: 0
ps4ReprojectionSupport: 0
ps4UseAudio3dBackend: 0
ps4UseLowGarlicFragmentationMode: 1
ps4SocialScreenEnabled: 0
ps4ScriptOptimizationLevel: 0
ps4Audio3dVirtualSpeakerCount: 14

ps4disableAutoHideSplash: 0
ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0
ps4GPU800MHz: 1
ps4attribVROutputEnabled: 0
blurSplashScreenBackground: 1
spritePackerPolicy:
webGLMemorySize: 256
webGLExceptionSupport: 1

webGLCompressionFormat: 1
webGLLinkerTarget: 1
webGLThreadsSupport: 0
webGLWasmStreaming: 0
scriptingDefineSymbols:
1:
7: UNITY_POST_PROCESSING_STACK_V2

allowUnsafeCode: 0
additionalIl2CppArgs:
scriptingRuntimeVersion: 1
gcIncremental: 0
assemblyVersionValidation: 1
gcWBarrierValidation: 0
apiCompatibilityLevelPerPlatform:
Standalone: 3
m_RenderingPath: 1

metroFTAName:
metroFTAFileTypes: []
metroProtocolName:
metroCompilationOverrides: 1
XboxOneProductId:
XboxOneUpdateKey:
XboxOneSandboxId:

XboxOneCapability: []
XboxOneGameRating: {}
XboxOneIsContentPackage: 0
XboxOneEnhancedXboxCompatibilityMode: 0
XboxOneEnableGPUVariability: 0
XboxOneSockets: {}
XboxOneSplashScreen: {fileID: 0}

xboxOneScriptCompiler: 0
XboxOneOverrideIdentityPublisher:
vrEditorSettings:
daydream:
daydreamIconForeground: {fileID: 0}

m_PortalFolderPath:
luminCert:
m_CertPath:
m_PrivateKeyPath:
m_SignPackage: 1
facebookSdkVersion: 7.9.4
facebookAppId:
facebookCookies: 1
facebookLogging: 1
facebookStatus: 1
facebookXfbml: 0
facebookFrictionlessRequests: 1
apiCompatibilityLevel: 3
cloudProjectId:
framebufferDepthMemorylessMode: 0

enableNativePlatformBackendsForNewInputSystem: 0
enableNativePlatformBackendsForNewInputSystem: 1
disableOldInputManagerSupport: 0
legacyClampBlendShapeWeights: 1

3
Project/ProjectSettings/ProjectVersion.txt


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

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


## Requirements
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`

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

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

4
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;

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

4
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;

}
}
}
#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

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


namespace Unity.MLAgents.Extensions.Match3
{
/// <summary>
/// Delegate that provides integer values at a given (x,y) coordinate.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public delegate int GridValueProvider(int x, int y);
/// <summary>
/// Type of observations to generate.
///

/// <summary>
/// Sensor for Match3 games. Can generate either vector, compressed visual,
/// or uncompressed visual observations. Uses AbstractBoard.GetCellType()
/// and AbstractBoard.GetSpecialType() to determine the observation values.
/// or uncompressed visual observations. Uses a GridValueProvider to determine the observation values.
public class Match3Sensor : ISparseChannelSensor, IBuiltInSensor
public class Match3Sensor : ISensor, IBuiltInSensor
private AbstractBoard m_Board;
private int[] m_SparseChannelMapping;
private int m_NumCellTypes;
private int m_NumSpecialTypes;
private ISparseChannelSensor sparseChannelSensorImplementation;
private int SpecialTypeSize
{
get { return m_NumSpecialTypes == 0 ? 0 : m_NumSpecialTypes + 1; }
}
private GridValueProvider m_GridValues;
private int m_OneHotSize;
/// Create a sensor for the board with the specified observation type.
/// Create a sensor for the GridValueProvider with the specified observation type.
/// <param name="board"></param>
/// <param name="obsType"></param>
/// <param name="name"></param>
public Match3Sensor(AbstractBoard board, Match3ObservationType obsType, string name)
/// <remarks>
/// Use Match3Sensor.CellTypeSensor() or Match3Sensor.SpecialTypeSensor() instead of calling
/// the constructor directly.
/// </remarks>
/// <param name="board">The abstract board. This is only used to get the size.</param>
/// <param name="gvp">The GridValueProvider, should be either board.GetCellType or board.GetSpecialType.</param>
/// <param name="oneHotSize">The number of possible values that the GridValueProvider can return.</param>
/// <param name="obsType">Whether to produce vector or visual observations</param>
/// <param name="name">Name of the sensor.</param>
public Match3Sensor(AbstractBoard board, GridValueProvider gvp, int oneHotSize, Match3ObservationType obsType, string name)
m_Board = board;
m_NumCellTypes = board.NumCellTypes;
m_NumSpecialTypes = board.NumSpecialTypes;
m_GridValues = gvp;
m_OneHotSize = oneHotSize;
? ObservationSpec.Vector(m_Rows * m_Columns * (m_NumCellTypes + SpecialTypeSize))
: ObservationSpec.Visual(m_Rows, m_Columns, m_NumCellTypes + SpecialTypeSize);
? ObservationSpec.Vector(m_Rows * m_Columns * oneHotSize)
: ObservationSpec.Visual(m_Rows, m_Columns, oneHotSize);
}
// See comment in GetCompressedObservation()
var cellTypePaddedSize = 3 * ((m_NumCellTypes + 2) / 3);
m_SparseChannelMapping = new int[cellTypePaddedSize + SpecialTypeSize];
// If we have 4 cell types and 2 special types (3 special size), we'd have
// [0, 1, 2, 3, -1, -1, 4, 5, 6]
for (var i = 0; i < m_NumCellTypes; i++)
{
m_SparseChannelMapping[i] = i;
}
/// <summary>
/// Create a sensor that encodes the board cells as observations.
/// </summary>
/// <param name="board">The abstract board.</param>
/// <param name="obsType">Whether to produce vector or visual observations</param>
/// <param name="name">Name of the sensor.</param>
/// <returns></returns>
public static Match3Sensor CellTypeSensor(AbstractBoard board, Match3ObservationType obsType, string name)
{
return new Match3Sensor(board, board.GetCellType, board.NumCellTypes, obsType, name);
}
for (var i = m_NumCellTypes; i < cellTypePaddedSize; i++)
{
m_SparseChannelMapping[i] = -1;
}
for (var i = 0; i < SpecialTypeSize; i++)
{
m_SparseChannelMapping[cellTypePaddedSize + i] = i + m_NumCellTypes;
}
/// <summary>
/// Create a sensor that encodes the cell special types as observations.
/// </summary>
/// <param name="board">The abstract board.</param>
/// <param name="obsType">Whether to produce vector or visual observations</param>
/// <param name="name">Name of the sensor.</param>
/// <returns></returns>
public static Match3Sensor SpecialTypeSensor(AbstractBoard board, Match3ObservationType obsType, string name)
{
var specialSize = board.NumSpecialTypes == 0 ? 0 : board.NumSpecialTypes + 1;
return new Match3Sensor(board, board.GetSpecialType, specialSize, obsType, name);
}
/// <inheritdoc/>

/// <inheritdoc/>
public int Write(ObservationWriter writer)
{
if (m_Board.Rows != m_Rows || m_Board.Columns != m_Columns || m_Board.NumCellTypes != m_NumCellTypes)
{
Debug.LogWarning(
$"Board shape changes since sensor initialization. This may cause unexpected results. " +
$"Old shape: Rows={m_Rows} Columns={m_Columns}, NumCellTypes={m_NumCellTypes} " +
$"Current shape: Rows={m_Board.Rows} Columns={m_Board.Columns}, NumCellTypes={m_Board.NumCellTypes}"
);
}
// if (m_Board.Rows != m_Rows || m_Board.Columns != m_Columns || m_Board.NumCellTypes != m_NumCellTypes)
// {
// Debug.LogWarning(
// $"Board shape changes since sensor initialization. This may cause unexpected results. " +
// $"Old shape: Rows={m_Rows} Columns={m_Columns}, NumCellTypes={m_NumCellTypes} " +
// $"Current shape: Rows={m_Board.Rows} Columns={m_Board.Columns}, NumCellTypes={m_Board.NumCellTypes}"
// );
// }
if (m_ObservationType == Match3ObservationType.Vector)
{

for (var c = 0; c < m_Columns; c++)
{
var val = m_Board.GetCellType(r, c);
for (var i = 0; i < m_NumCellTypes; i++)
var val = m_GridValues(r, c);
for (var i = 0; i < m_OneHotSize; i++)
if (m_NumSpecialTypes > 0)
{
var special = m_Board.GetSpecialType(r, c);
for (var i = 0; i < SpecialTypeSize; i++)
{
writer[offset] = (i == special) ? 1.0f : 0.0f;
offset++;
}
}
}
}

{
for (var c = 0; c < m_Columns; c++)
{
var val = m_Board.GetCellType(r, c);
for (var i = 0; i < m_NumCellTypes; i++)
var val = m_GridValues(r, c);
for (var i = 0; i < m_OneHotSize; i++)
if (m_NumSpecialTypes > 0)
{
var special = m_Board.GetSpecialType(r, c);
for (var i = 0; i < SpecialTypeSize; i++)
{
writer[offset] = (i == special) ? 1.0f : 0.0f;
offset++;
}
}
}
}

// fit in in 2 images, but we'll use 3 here (2 PNGs for the 4 cell type channels, and 1 for
// the special types). Note that we have to also implement the sparse channel mapping.
// Optimize this it later.
var numCellImages = (m_NumCellTypes + 2) / 3;
var numCellImages = (m_OneHotSize + 2) / 3;
converter.EncodeToTexture(m_Board.GetCellType, tempTexture, 3 * i);
bytesOut.AddRange(tempTexture.EncodeToPNG());
}
var numSpecialImages = (SpecialTypeSize + 2) / 3;
for (var i = 0; i < numSpecialImages; i++)
{
converter.EncodeToTexture(m_Board.GetSpecialType, tempTexture, 3 * i);
converter.EncodeToTexture(m_GridValues, tempTexture, 3 * i);
bytesOut.AddRange(tempTexture.EncodeToPNG());
}

{
}
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
internal SensorCompressionType GetCompressionType()
{
return m_ObservationType == Match3ObservationType.CompressedVisual ?
SensorCompressionType.PNG :

/// <inheritdoc/>
public string GetName()
public CompressionSpec GetCompressionSpec()
return m_Name;
return new CompressionSpec(GetCompressionType());
public int[] GetCompressedChannelMapping()
public string GetName()
return m_SparseChannelMapping;
return m_Name;
}
/// <inheritdoc/>

int m_Height;
int m_Width;
private static Color[] s_OneHotColors = { Color.red, Color.green, Color.blue };
public delegate int GridValueProvider(int x, int y);
public OneHotToTextureUtil(int height, int width)
{

26
com.unity.ml-agents.extensions/Runtime/Match3/Match3SensorComponent.cs


public Match3ObservationType ObservationType = Match3ObservationType.Vector;
/// <inheritdoc/>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return new Match3Sensor(board, ObservationType, SensorName);
}
/// <inheritdoc/>
public override int[] GetObservationShape()
{
var board = GetComponent<AbstractBoard>();
if (board == null)
var cellSensor = Match3Sensor.CellTypeSensor(board, ObservationType, SensorName + " (cells)");
if (board.NumSpecialTypes > 0)
return System.Array.Empty<int>();
var specialSensor =
Match3Sensor.SpecialTypeSensor(board, ObservationType, SensorName + " (special)");
return new ISensor[] { cellSensor, specialSensor };
}
else
{
return new ISensor[] { cellSensor };
var specialSize = board.NumSpecialTypes == 0 ? 0 : board.NumSpecialTypes + 1;
return ObservationType == Match3ObservationType.Vector ?
new[] { board.Rows * board.Columns * (board.NumCellTypes + specialSize) } :
new[] { board.Rows, board.Columns, board.NumCellTypes + specialSize };
}
}

24
com.unity.ml-agents.extensions/Runtime/Sensors/ArticulationBodySensorComponent.cs


/// Creates a PhysicsBodySensor.
/// </summary>
/// <returns></returns>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return new PhysicsBodySensor(RootBody, Settings, sensorName);
return new ISensor[] {new PhysicsBodySensor(RootBody, Settings, sensorName)};
/// <inheritdoc/>
public override int[] GetObservationShape()
{
if (RootBody == null)
{
return new[] { 0 };
}
// TODO static method in PhysicsBodySensor?
// TODO only update PoseExtractor when body changes?
var poseExtractor = new ArticulationBodyPoseExtractor(RootBody);
var numPoseObservations = poseExtractor.GetNumPoseObservations(Settings);
var numJointObservations = 0;
foreach(var articBody in poseExtractor.GetEnabledArticulationBodies())
{
numJointObservations += ArticulationBodyJointExtractor.NumObservations(articBody, Settings);
}
return new[] { numPoseObservations + numJointObservations };
}
}
}

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


private Color DebugDefaultColor = new Color(1f, 1f, 1f, 0.25f);
/// <inheritdoc/>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return this;
return new ISensor[] { this };
}
/// <summary>

}
/// <inheritdoc/>
public virtual SensorCompressionType GetCompressionType()
public virtual CompressionSpec GetCompressionSpec()
return CompressionType;
return new CompressionSpec(CompressionType);
}
/// <inheritdoc/>

m_ObservationSpec = ObservationSpec.Visual(GridNumSideX, GridNumSideZ, ObservationPerCell);
}
return m_ObservationSpec;
}
/// <inheritdoc/>
public override int[] GetObservationShape()
{
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


}
#if UNITY_2020_1_OR_NEWER
public PhysicsBodySensor(ArticulationBody rootBody, PhysicsSensorSettings settings, string sensorName=null)
public PhysicsBodySensor(ArticulationBody rootBody, PhysicsSensorSettings settings, string sensorName = null)
{
var poseExtractor = new ArticulationBodyPoseExtractor(rootBody);
m_PoseExtractor = poseExtractor;

var numJointExtractorObservations = 0;
m_JointExtractors = new List<IJointExtractor>(poseExtractor.NumEnabledPoses);
foreach(var articBody in poseExtractor.GetEnabledArticulationBodies())
foreach (var articBody in poseExtractor.GetEnabledArticulationBodies())
{
var jointExtractor = new ArticulationBodyJointExtractor(articBody);
numJointExtractorObservations += jointExtractor.NumObservations(settings);

var numTransformObservations = m_PoseExtractor.GetNumPoseObservations(settings);
m_ObservationSpec = ObservationSpec.Vector(numTransformObservations + numJointExtractorObservations);
}
#endif
/// <inheritdoc/>

public void Reset() { }
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return SensorCompressionType.None;
return CompressionSpec.Default();
}
/// <inheritdoc/>

{
return BuiltInSensorType.PhysicsBodySensor;
}
}
}

24
com.unity.ml-agents.extensions/Runtime/Sensors/RigidBodySensorComponent.cs


/// Creates a PhysicsBodySensor.
/// </summary>
/// <returns></returns>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return new PhysicsBodySensor(GetPoseExtractor(), Settings, _sensorName);
}
/// <inheritdoc/>
public override int[] GetObservationShape()
{
if (RootBody == null)
{
return new[] { 0 };
}
var poseExtractor = GetPoseExtractor();
var numPoseObservations = poseExtractor.GetNumPoseObservations(Settings);
var numJointObservations = 0;
foreach (var rb in poseExtractor.GetEnabledRigidbodies())
{
var joint = rb.GetComponent<Joint>();
numJointObservations += RigidBodyJointExtractor.NumObservations(rb, joint, Settings);
}
return new[] { numPoseObservations + numJointObservations };
return new ISensor[] { new PhysicsBodySensor(GetPoseExtractor(), Settings, _sensorName) };
}
/// <summary>

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


// Whether the expected PNG data should be written to a file.
// Only set this to true if the compressed observation format changes.
private bool WritePNGDataToFile = false;
private const string k_CellObservationPng = "match3obs";
private const string k_SpecialObservationPng = "match3obs_special";
[Test]
public void TestVectorObservations()

var sensorComponent = gameObj.AddComponent<Match3SensorComponent>();
sensorComponent.ObservationType = Match3ObservationType.Vector;
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
var expectedShape = new[] { 3 * 3 * 2 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
var expectedShape = new InplaceArray<int>(3 * 3 * 2);
Assert.AreEqual(expectedShape, sensor.GetObservationSpec().Shape);
var expectedObs = new float[]
{

var sensorComponent = gameObj.AddComponent<Match3SensorComponent>();
sensorComponent.ObservationType = Match3ObservationType.Vector;
var sensor = sensorComponent.CreateSensor();
var sensors = sensorComponent.CreateSensors();
var cellSensor = sensors[0];
var specialSensor = sensors[1];
var expectedShape = new[] { 3 * 3 * (2 + 3) };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
var expectedObs = new float[]
1, 0, 1, 0, 0, /* (0, 0) */ 0, 1, 1, 0, 0, /* (0, 1) */ 1, 0, 1, 0, 0, /* (0, 0) */
1, 0, 0, 0, 1, /* (0, 2) */ 1, 0, 1, 0, 0, /* (0, 0) */ 1, 0, 1, 0, 0, /* (0, 0) */
1, 0, 1, 0, 0, /* (0, 0) */ 1, 0, 0, 1, 0, /* (0, 1) */ 1, 0, 1, 0, 0, /* (0, 0) */
};
SensorTestHelper.CompareObservation(sensor, expectedObs);
}
var expectedShape = new InplaceArray<int>(3 * 3 * 2);
Assert.AreEqual(expectedShape, cellSensor.GetObservationSpec().Shape);
var expectedObs = new float[]
{
1, 0, /* (0) */ 0, 1, /* (1) */ 1, 0, /* (0) */
1, 0, /* (0) */ 1, 0, /* (0) */ 1, 0, /* (0) */
1, 0, /* (0) */ 1, 0, /* (0) */ 1, 0, /* (0) */
};
SensorTestHelper.CompareObservation(cellSensor, expectedObs);
}
{
var expectedShape = new InplaceArray<int>(3 * 3 * 3);
Assert.AreEqual(expectedShape, specialSensor.GetObservationSpec().Shape);
var expectedObs = new float[]
{
1, 0, 0, /* (0) */ 1, 0, 0, /* (1) */ 1, 0, 0, /* (0) */
0, 0, 1, /* (2) */ 1, 0, 0, /* (0) */ 1, 0, 0, /* (0) */
1, 0, 0, /* (0) */ 0, 1, 0, /* (1) */ 1, 0, 0, /* (0) */
};
SensorTestHelper.CompareObservation(specialSensor, expectedObs);
}
}
[Test]
public void TestVisualObservations()

var sensorComponent = gameObj.AddComponent<Match3SensorComponent>();
sensorComponent.ObservationType = Match3ObservationType.UncompressedVisual;
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
var expectedShape = new[] { 3, 3, 2 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
var expectedShape = new InplaceArray<int>(3, 3, 2);
Assert.AreEqual(expectedShape, sensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.None, sensor.GetCompressionType());
Assert.AreEqual(SensorCompressionType.None, sensor.GetCompressionSpec().SensorCompressionType);
var expectedObs = new float[]
{

var sensorComponent = gameObj.AddComponent<Match3SensorComponent>();
sensorComponent.ObservationType = Match3ObservationType.UncompressedVisual;
var sensor = sensorComponent.CreateSensor();
var sensors = sensorComponent.CreateSensors();
var cellSensor = sensors[0];
var specialSensor = sensors[1];
var expectedShape = new[] { 3, 3, 2 + 3 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
{
var expectedShape = new InplaceArray<int>(3, 3, 2);
Assert.AreEqual(expectedShape, cellSensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.None, sensor.GetCompressionType());
Assert.AreEqual(SensorCompressionType.None, cellSensor.GetCompressionSpec().SensorCompressionType);
var expectedObs = new float[]
{
1, 0, 1, 0, 0, /* (0, 0) */ 0, 1, 1, 0, 0, /* (0, 1) */ 1, 0, 1, 0, 0, /* (0, 0) */
1, 0, 0, 0, 1, /* (0, 2) */ 1, 0, 1, 0, 0, /* (0, 0) */ 1, 0, 1, 0, 0, /* (0, 0) */
1, 0, 1, 0, 0, /* (0, 0) */ 1, 0, 0, 1, 0, /* (0, 1) */ 1, 0, 1, 0, 0, /* (0, 0) */
};
SensorTestHelper.CompareObservation(sensor, expectedObs);
var expectedObs = new float[]
{
1, 0, /* (0) */ 0, 1, /* (1) */ 1, 0, /* (0) */
1, 0, /* (0) */ 1, 0, /* (0) */ 1, 0, /* (0) */
1, 0, /* (0) */ 1, 0, /* (0) */ 1, 0, /* (0) */
};
SensorTestHelper.CompareObservation(cellSensor, expectedObs);
var expectedObs3D = new float[,,]
var expectedObs3D = new float[,,]
{
{{1, 0}, {0, 1}, {1, 0}},
{{1, 0}, {1, 0}, {1, 0}},
{{1, 0}, {1, 0}, {1, 0}},
};
SensorTestHelper.CompareObservation(cellSensor, expectedObs3D);
}
{{1, 0, 1, 0, 0}, {0, 1, 1, 0, 0}, {1, 0, 1, 0, 0}},
{{1, 0, 0, 0, 1}, {1, 0, 1, 0, 0}, {1, 0, 1, 0, 0}},
{{1, 0, 1, 0, 0}, {1, 0, 0, 1, 0}, {1, 0, 1, 0, 0}},
};
SensorTestHelper.CompareObservation(sensor, expectedObs3D);
var expectedShape = new InplaceArray<int>(3, 3, 3);
Assert.AreEqual(expectedShape, specialSensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.None, specialSensor.GetCompressionSpec().SensorCompressionType);
var expectedObs = new float[]
{
1, 0, 0, /* (0) */ 1, 0, 0, /* (1) */ 1, 0, 0, /* (0) */
0, 0, 1, /* (2) */ 1, 0, 0, /* (0) */ 1, 0, 0, /* (0) */
1, 0, 0, /* (0) */ 0, 1, 0, /* (1) */ 1, 0, 0, /* (0) */
};
SensorTestHelper.CompareObservation(specialSensor, expectedObs);
var expectedObs3D = new float[,,]
{
{{1, 0, 0}, {1, 0, 0}, {1, 0, 0}},
{{0, 0, 1}, {1, 0, 0}, {1, 0, 0}},
{{1, 0, 0}, {0, 1, 0}, {1, 0, 0}},
};
SensorTestHelper.CompareObservation(specialSensor, expectedObs3D);
}
}
[Test]

var sensorComponent = gameObj.AddComponent<Match3SensorComponent>();
sensorComponent.ObservationType = Match3ObservationType.CompressedVisual;
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
var expectedShape = new[] { 3, 3, 2 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
var expectedShape = new InplaceArray<int>(3, 3, 2);
Assert.AreEqual(expectedShape, sensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.PNG, sensor.GetCompressionType());
Assert.AreEqual(SensorCompressionType.PNG, sensor.GetCompressionSpec().SensorCompressionType);
SavePNGs(pngData, "match3obs");
SavePNGs(pngData, k_CellObservationPng);
var expectedPng = LoadPNGs("match3obs", 1);
var expectedPng = LoadPNGs(k_CellObservationPng, 1);
[Test]
public void TestCompressedVisualObservationsSpecial()

var sensorComponent = gameObj.AddComponent<Match3SensorComponent>();
sensorComponent.ObservationType = Match3ObservationType.CompressedVisual;
var sensor = sensorComponent.CreateSensor();
var expectedShape = new[] { 3, 3, 2 + 3 };
Assert.AreEqual(expectedShape, sensorComponent.GetObservationShape());
Assert.AreEqual(InplaceArray<int>.FromList(expectedShape), sensor.GetObservationSpec().Shape);
var sensors = sensorComponent.CreateSensors();
Assert.AreEqual(SensorCompressionType.PNG, sensor.GetCompressionType());
var paths = new[] { k_CellObservationPng, k_SpecialObservationPng };
var expectedChannels = new[] { 2, 3 };
var concatenatedPngData = sensor.GetCompressedObservation();
var pathPrefix = "match3obs_special";
if (WritePNGDataToFile)
for (var i = 0; i < 2; i++)
// Enable this if the format of the observation changes
SavePNGs(concatenatedPngData, pathPrefix);
var sensor = sensors[i];
var expectedShape = new InplaceArray<int>(3, 3, expectedChannels[i]);
Assert.AreEqual(expectedShape, sensor.GetObservationSpec().Shape);
Assert.AreEqual(SensorCompressionType.PNG, sensor.GetCompressionSpec().SensorCompressionType);
var pngData = sensor.GetCompressedObservation();
if (WritePNGDataToFile)
{
// Enable this if the format of the observation changes
SavePNGs(pngData, paths[i]);
}
var expectedPng = LoadPNGs(paths[i], 1);
Assert.AreEqual(expectedPng, pngData);
var expectedPng = LoadPNGs(pathPrefix, 2);
Assert.AreEqual(expectedPng, concatenatedPngData);
}

}
return bytesOut.ToArray();
}
}
}

10
com.unity.ml-agents.extensions/Tests/Editor/Match3/match3obs0.png.meta


fileFormatVersion: 2
guid: 3e1767bf6c63e46b1a16404dc1afe508
TextureImporter:
fileIDToRecycleName: {}
internalIDToNameTable: []
serializedVersion: 9
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1

maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
- serializedVersion: 2
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0

allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []

spriteID:
internalID: 0
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0

2
com.unity.ml-agents.extensions/Tests/Editor/Match3/match3obs_special0.png

之前 之后
宽度: 3  |  高度: 3  |  大小: 79 B

10
com.unity.ml-agents.extensions/Tests/Editor/Match3/match3obs_special0.png.meta


fileFormatVersion: 2
guid: 2e4ca31cf9cff4505acbefe44b621d6f
TextureImporter:
fileIDToRecycleName: {}
internalIDToNameTable: []
serializedVersion: 9
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 1

maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
applyGammaDecoding: 0
- serializedVersion: 2
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0

allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []

spriteID:
internalID: 0
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0

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


1f, 1f, 10, 10, LayerMask.GetMask("Default"), false, colors);
gridSensor.Start();
int[] expectedShape = { 10, 10, 1 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
var expectedShape = new InplaceArray<int>(10, 10, 1);
Assert.AreEqual(expectedShape, gridSensor.GetObservationSpec().Shape);
}

1f, 1f, 10, 10, LayerMask.GetMask("Default"), false, colors);
gridSensor.Start();
int[] expectedShape = { 10, 10, 2 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
var expectedShape = new InplaceArray<int>(10, 10, 2);
Assert.AreEqual(expectedShape, gridSensor.GetObservationSpec().Shape);
}
[Test]

1f, 1f, 10, 10, LayerMask.GetMask("Default"), false, colors);
gridSensor.Start();
int[] expectedShape = { 10, 10, 3 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
var expectedShape = new InplaceArray<int>(10, 10, 3);
Assert.AreEqual(expectedShape, gridSensor.GetObservationSpec().Shape);
}

1f, 1f, 10, 10, LayerMask.GetMask("Default"), false, colors);
gridSensor.Start();
int[] expectedShape = { 10, 10, 6 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
var expectedShape = new InplaceArray<int>(10, 10, 6);
Assert.AreEqual(expectedShape, gridSensor.GetObservationSpec().Shape);
}
}

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


1f, 1f, 10, 10, LayerMask.GetMask("Default"), false, colors);
gridSensor.Start();
int[] expectedShape = { 10, 10, 1 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
var expectedShape = new InplaceArray<int>(10, 10, 1);
Assert.AreEqual(expectedShape, gridSensor.GetObservationSpec().Shape);
}
[Test]

1f, 1f, 10, 10, LayerMask.GetMask("Default"), false, colors);
gridSensor.Start();
int[] expectedShape = { 10, 10, 2 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
var expectedShape = new InplaceArray<int>(10, 10, 2);
Assert.AreEqual(expectedShape, gridSensor.GetObservationSpec().Shape);
}
[Test]

1f, 1f, 10, 10, LayerMask.GetMask("Default"), false, colors);
gridSensor.Start();
int[] expectedShape = { 10, 10, 7 };
GridObsTestUtils.AssertArraysAreEqual(expectedShape, gridSensor.GetObservationShape());
var expectedShape = new InplaceArray<int>(10, 10, 7);
Assert.AreEqual(expectedShape, gridSensor.GetObservationSpec().Shape);
}
}
}

27
com.unity.ml-agents.extensions/Tests/Editor/Sensors/GridSensorTestUtils.cs


return duplicated;
}
/// <summary>
/// Asserts that 2 int arrays are the same
/// </summary>
/// <param name="expected">The expected array</param>
/// <param name="actual">The actual array</param>
public static void AssertArraysAreEqual(int[] expected, int[] actual)
{
Assert.AreEqual(expected.Length, actual.Length, "Lengths are not the same");
for (int i = 0; i < actual.Length; i++)
{
Assert.AreEqual(expected[i], actual[i], "Got " + Array2Str(actual) + ", expected " + Array2Str(expected));
}
}
/// <summary>
/// Asserts that 2 float arrays are the same
/// </summary>
/// <param name="expected">The expected array</param>
/// <param name="actual">The actual array</param>
public static void AssertArraysAreEqual(float[] expected, float[] actual)
{
Assert.AreEqual(expected.Length, actual.Length, "Lengths are not the same");
for (int i = 0; i < actual.Length; i++)
{
Assert.AreEqual(expected[i], actual[i], "Got " + Array2Str(actual) + ", expected " + Array2Str(expected));
}
}
/// <summary>
/// Asserts that the sub-arrays of the total array are equal to specific subarrays at specific subarray indicies and equal to a default everywhere else.

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

14
com.unity.ml-agents.extensions/Tests/Runtime/Sensors/ArticulationBodySensorTests.cs


var gameObj = new GameObject();
var sensorComponent = gameObj.AddComponent<ArticulationBodySensorComponent>();
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
SensorTestHelper.CompareObservation(sensor, new float[0]);
}

UseLocalSpaceRotations = true
};
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
sensor.Update();
var expected = new[]
{

};
SensorTestHelper.CompareObservation(sensor, expected);
Assert.AreEqual(expected.Length, sensorComponent.GetObservationShape()[0]);
Assert.AreEqual(expected.Length, sensor.GetObservationSpec().Shape[0]);
}
[Test]

#endif
};
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
sensor.Update();
var expected = new[]
{

#endif
};
SensorTestHelper.CompareObservation(sensor, expected);
Assert.AreEqual(expected.Length, sensorComponent.GetObservationShape()[0]);
Assert.AreEqual(expected.Length, sensor.GetObservationSpec().Shape[0]);
// Update the settings to only process joint observations
sensorComponent.Settings = new PhysicsSensorSettings

};
sensor = sensorComponent.CreateSensor();
sensor = sensorComponent.CreateSensors()[0];
sensor.Update();
expected = new[]

0f, // joint2.force
};
SensorTestHelper.CompareObservation(sensor, expected);
Assert.AreEqual(expected.Length, sensorComponent.GetObservationShape()[0]);
Assert.AreEqual(expected.Length, sensor.GetObservationSpec().Shape[0]);
}
}
}

14
com.unity.ml-agents.extensions/Tests/Runtime/Sensors/RigidBodySensorTests.cs


var gameObj = new GameObject();
var sensorComponent = gameObj.AddComponent<RigidBodySensorComponent>();
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
SensorTestHelper.CompareObservation(sensor, new float[0]);
}

UseLocalSpaceRotations = true
};
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
Assert.AreEqual(expected.Length, sensorComponent.GetObservationShape()[0]);
Assert.AreEqual(expected.Length, sensor.GetObservationSpec().Shape[0]);
SensorTestHelper.CompareObservation(sensor, expected);
}

};
sensorComponent.VirtualRoot = virtualRoot;
var sensor = sensorComponent.CreateSensor();
var sensor = sensorComponent.CreateSensors()[0];
sensor.Update();
// Note that the VirtualRoot is ignored from the observations

-1f, 1f, 0f, // Attached vel
0f, -1f, 1f // Leaf vel
};
Assert.AreEqual(expected.Length, sensorComponent.GetObservationShape()[0]);
Assert.AreEqual(expected.Length, sensor.GetObservationSpec().Shape[0]);
SensorTestHelper.CompareObservation(sensor, expected);
// Update the settings to only process joint observations

UseJointForces = true,
};
sensor = sensorComponent.CreateSensor();
sensor = sensorComponent.CreateSensors()[0];
sensor.Update();
expected = new[]

0f, 0f, 0f, // joint2.torque
};
SensorTestHelper.CompareObservation(sensor, expected);
Assert.AreEqual(expected.Length, sensorComponent.GetObservationShape()[0]);
Assert.AreEqual(expected.Length, sensor.GetObservationSpec().Shape[0]);
}
}

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


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

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


## [Unreleased]
### Major Changes
#### com.unity.ml-agents (C#)
#### com.unity.ml-agents / com.unity.ml-agents.extensions (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.

`SetActionEnabled(int branch, int actionIndex, bool isEnabled)`. (#5060)
- IActuator now implements IHeuristicProvider. (#5110)
- `ISensor.GetObservationShape()` was removed, and `GetObservationSpec()` was added. (#5127)
- `ISensor.GetObservationShape()` was removed, and `GetObservationSpec()` was added. The `ITypedSensor`
and `IDimensionPropertiesSensor` interfaces were removed. (#5127)
- `ISensor.GetCompressionType()` was removed, and `GetCompressionSpec()` was added. The `ISparseChannelSensor`
interface was removed. (#5164)
- The abstract method `SensorComponent.GetObservationShape()` was no longer being called, so it has been removed. (#5172)
- `SensorComponent.CreateSensor()` was replaced with `SensorComponent.CreateSensor()`, which returns an `ISensor[]`. (#5181)
- `Match3Sensor` was refactored to produce cell and special type observations separately, and `Match3SensorComponent` now
produces two `Match3Sensor`s (unless there are no special types). Previously trained models will have different observation
sizes and will need to be retrained. (#5181)
#### ml-agents / ml-agents-envs / gym-unity (Python)

- 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)
- Make com.unity.modules.unityanalytics an optional dependency. (#5109)
- Make com.unity.modules.physics and com.unity.modules.physics2d optional dependencies. (#5112)
- The default `InferenceDevice` is now `InferenceDevice.Default`, which is equivalent to `InferenceDevice.Burst`. If you
depend on the previous behavior, you can explicitly set the Agent's `InferenceDevice` to `InferenceDevice.CPU`. (#5175)
#### com.unity.ml-agents (C#)
#### com.unity.ml-agents / com.unity.ml-agents.extensions (C#)
#### ml-agents / ml-agents-envs / gym-unity (Python)

2
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

6
com.unity.ml-agents/Editor/MLAgentsSettingsBuildProvider.cs


private static bool IsPlayerSettingsDirty()
{
#if UNITY_2019_OR_NEWER
#else
return false;
#endif
#if UNITY_2019_OR_NEWER
#endif
}
}
}

4
com.unity.ml-agents/Editor/MLAgentsSettingsProvider.cs


using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEditor;
#if UNITY_2019_4_OR_NEWER
#else
using UnityEngine.Experimental.UIElements;
#endif
[assembly: InternalsVisibleTo("Unity.ML-Agents.DevTests.Editor")]
namespace Unity.MLAgents.Editor

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


protected void OnRayPerceptionInspectorGUI(bool is3d)
{
#if !MLA_UNITY_PHYSICS_MODULE
if (is3d)
{
EditorGUILayout.HelpBox("The Physics Module is not currently present. " +
"Please add it to your project in order to use the Ray Perception APIs in the " +
$"{nameof(RayPerceptionSensorComponent3D)}", MessageType.Warning);
}
#endif
#if !MLA_UNITY_PHYSICS2D_MODULE
if (!is3d)
{
EditorGUILayout.HelpBox("The Physics2D Module is not currently present. " +
"Please add it to your project in order to use the Ray Perception APIs in the " +
$"{nameof(RayPerceptionSensorComponent3D)}", MessageType.Warning);
}
#endif
var so = serializedObject;
so.Update();

14
com.unity.ml-agents/Editor/Unity.ML-Agents.Editor.asmdef


"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
"defineConstraints": [],
"versionDefines": [
{
"name": "com.unity.modules.physics",
"expression": "1.0.0",
"define": "MLA_UNITY_PHYSICS_MODULE"
},
{
"name": "com.unity.modules.physics2d",
"expression": "1.0.0",
"define": "MLA_UNITY_PHYSICS2D_MODULE"
}
]
}

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


internal class AgentVectorActuator : VectorActuator
{
public AgentVectorActuator(IActionReceiver actionReceiver,
IHeuristicProvider heuristicProvider,
ActionSpec actionSpec,
string name = "VectorActuator"
IHeuristicProvider heuristicProvider,
ActionSpec actionSpec,
string name = "VectorActuator"
) : base(actionReceiver, heuristicProvider, actionSpec, name)
{ }

public void SetModel(
string behaviorName,
NNModel model,
InferenceDevice inferenceDevice = InferenceDevice.CPU)
InferenceDevice inferenceDevice = InferenceDevice.Default)
{
if (behaviorName == m_PolicyFactory.BehaviorName &&
model == m_PolicyFactory.Model &&

/// <param name="reward">The new value of the reward.</param>
public void SetReward(float reward)
{
#if DEBUG
#endif
m_CumulativeReward += (reward - m_Reward);
m_Reward = reward;
}

/// <param name="increment">Incremental reward value.</param>
public void AddReward(float increment)
{
#if DEBUG
#endif
m_Reward += increment;
m_CumulativeReward += increment;
}

#if DEBUG
#endif
#if DEBUG
#endif
m_GroupReward += increment;
}

sensors.Capacity += attachedSensorComponents.Length;
foreach (var component in attachedSensorComponents)
{
sensors.Add(component.CreateSensor());
sensors.AddRange(component.CreateSensors());
}
// Support legacy CollectObservations

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


return new EventObservationSpec
{
SensorName = sensor.GetName(),
CompressionType = sensor.GetCompressionType().ToString(),
CompressionType = sensor.GetCompressionSpec().SensorCompressionType.ToString(),
BuiltInSensorType = (int)builtInSensorType,
DimensionInfos = dimInfos,
};

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


#if MLA_UNITY_ANALYTICS_MODULE || !UNITY_2019_4_OR_NEWER
#define MLA_UNITY_ANALYTICS_MODULE_ENABLED
#endif
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Unity.Barracuda;

using Unity.MLAgents.Sensors;
using UnityEngine;
#if MLA_UNITY_ANALYTICS_MODULE_ENABLED
#if MLA_UNITY_ANALYTICS_MODULE
using UnityEngine.Analytics;
#endif

#if MLA_UNITY_ANALYTICS_MODULE_ENABLED
#if MLA_UNITY_ANALYTICS_MODULE
#endif // MLA_UNITY_ANALYTICS_MODULE_ENABLED
#endif // MLA_UNITY_ANALYTICS_MODULE
#endif // UNITY_EDITOR

const int k_MaxNumberOfElements = 1000;
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
#endif
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE_ENABLED
#elif MLA_UNITY_ANALYTICS_MODULE_ENABLED
AnalyticsResult result = AnalyticsResult.UnsupportedPlatform;
if (result == AnalyticsResult.Ok)
{
s_EventRegistered = true;
}
#endif
#else // no editor, no analytics
s_EventRegistered = false;
#endif
return s_EventRegistered;
}

/// <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_ENABLED")]
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
public static void InferenceModelSet(
NNModel nnModel,
string behaviorName,

IList<IActuator> actuators
)
{
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
// The event shouldn't be able to report if this is disabled but if we know we're not going to report
// Lets early out and not waste time gathering all the data
if (!IsAnalyticsEnabled())

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 && MLA_UNITY_ANALYTICS_MODULE_ENABLED
#else
return;
#endif
}

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

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


#if MLA_UNITY_ANALYTICS_MODULE || !UNITY_2019_4_OR_NEWER
#define MLA_UNITY_ANALYTICS_MODULE_ENABLED
#endif
using System;
using System.Collections.Generic;
using System.Diagnostics;

#if MLA_UNITY_ANALYTICS_MODULE_ENABLED
#if MLA_UNITY_ANALYTICS_MODULE
using UnityEngine.Analytics;
#if UNITY_EDITOR
using UnityEditor.Analytics;

namespace Unity.MLAgents.Analytics
{
internal class TrainingAnalytics
internal static class TrainingAnalytics
{
const string k_VendorKey = "unity.ml-agents";
const string k_TrainingEnvironmentInitializedEventName = "ml_agents_training_environment_initialized";

k_TrainingBehaviorInitializedEventName,
k_RemotePolicyInitializedEventName
};
/// <summary>
/// Whether or not we've registered this particular event yet
/// </summary>
static bool s_EventsRegistered = false;
/// <summary>
/// Hourly limit for this event name

const int k_MaxNumberOfElements = 1000;
private static bool s_SentEnvironmentInitialized;
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
/// <summary>
/// Whether or not we've registered this particular event yet
/// </summary>
static bool s_EventsRegistered = false;
#endif
private static Guid s_TrainingSessionGuid;

static bool EnableAnalytics()
internal static bool EnableAnalytics()
#if MLA_UNITY_ANALYTICS_MODULE_ENABLED
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
if (s_EventsRegistered)
{
return true;

#if UNITY_EDITOR
#else
return false;
#endif // UNITY_EDITOR
}
s_EventsRegistered = true;

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

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

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

[Conditional("MLA_UNITY_ANALYTICS_MODULE_ENABLED")]
[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 && MLA_UNITY_ANALYTICS_MODULE_ENABLED
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
if (AnalyticsUtils.s_SendEditorAnalytics)
{
EditorAnalytics.SendEventWithLimit(k_TrainingEnvironmentInitializedEventName, tbiEvent);

[Conditional("MLA_UNITY_ANALYTICS_MODULE_ENABLED")]
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
public static void RemotePolicyInitialized(
string fullyQualifiedBehaviorName,
IList<ISensor> sensors,

{
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
if (!IsAnalyticsEnabled())
return;

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

return fullyQualifiedBehaviorName.Substring(0, lastQuestionIndex);
}
[Conditional("MLA_UNITY_ANALYTICS_MODULE_ENABLED")]
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
if (!IsAnalyticsEnabled())
return;

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

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


var obsSpec = sensor.GetObservationSpec();
var shape = obsSpec.Shape;
ObservationProto observationProto = null;
var compressionType = sensor.GetCompressionType();
var compressionSpec = sensor.GetCompressionSpec();
var compressionType = compressionSpec.SensorCompressionType;
// Check capabilities if we need to concatenate PNGs
if (compressionType == SensorCompressionType.PNG && shape.Length == 3 && shape[2] > 3)
{

if (compressionType != SensorCompressionType.None && shape.Length == 3 && shape[2] > 3)
{
var trainerCanHandleMapping = Academy.Instance.TrainerCapabilities == null || Academy.Instance.TrainerCapabilities.CompressedChannelMapping;
var isTrivialMapping = IsTrivialMapping(sensor);
var isTrivialMapping = compressionSpec.IsTrivialMapping();
if (!trainerCanHandleMapping && !isTrivialMapping)
{
if (!s_HaveWarnedTrainerCapabilitiesMapping)

throw new UnityAgentsException(
$"GetCompressedObservation() returned null data for sensor named {sensor.GetName()}. " +
"You must return a byte[]. If you don't want to use compressed observations, " +
"return SensorCompressionType.None from GetCompressionType()."
"return CompressionSpec.Default() from GetCompressionSpec()."
CompressionType = (CompressionTypeProto)sensor.GetCompressionType(),
CompressionType = (CompressionTypeProto)sensor.GetCompressionSpec().SensorCompressionType,
var compressibleSensor = sensor as ISparseChannelSensor;
if (compressibleSensor != null)
if (compressionSpec.CompressedChannelMapping != null)
observationProto.CompressedChannelMapping.AddRange(compressibleSensor.GetCompressedChannelMapping());
observationProto.CompressedChannelMapping.AddRange(compressionSpec.CompressedChannelMapping);
}
}

};
}
internal static bool IsTrivialMapping(ISensor sensor)
{
var compressibleSensor = sensor as ISparseChannelSensor;
if (compressibleSensor is null)
{
return true;
}
var mapping = compressibleSensor.GetCompressedChannelMapping();
if (mapping == null)
{
return true;
}
// check if mapping equals zero mapping
if (mapping.Length == 3 && mapping.All(m => m == 0))
{
return true;
}
// check if mapping equals identity mapping
for (var i = 0; i < mapping.Length; i++)
{
if (mapping[i] != i)
{
return false;
}
}
return true;
}
#region Analytics
internal static TrainingEnvironmentInitializedEvent ToTrainingEnvironmentInitializedEvent(
this TrainingEnvironmentInitialized inputProto)

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

1
com.unity.ml-agents/Runtime/Inference/ModelRunner.cs


case InferenceDevice.Burst:
executionDevice = WorkerFactory.Type.CSharpBurst;
break;
case InferenceDevice.Default: // fallthrough
default:
executionDevice = WorkerFactory.Type.CSharpBurst;
break;

31
com.unity.ml-agents/Runtime/Policies/BarracudaPolicy.cs


using Unity.Barracuda;
using System.Collections.Generic;
using System.Diagnostics;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Inference;
using Unity.MLAgents.Sensors;

public enum InferenceDevice
{
/// <summary>
/// CPU inference. Corresponds to in WorkerFactory.Type.CSharp Barracuda.
/// Burst is recommended instead; this is kept for legacy compatibility.
/// Default inference. This is currently the same as Burst, but may change in the future.
CPU = 0,
Default = 0,
/// <summary>
/// GPU inference. Corresponds to WorkerFactory.Type.ComputePrecompiled in Barracuda.

/// CPU inference using Burst. Corresponds to WorkerFactory.Type.CSharpBurst in Barracuda.
/// </summary>
Burst = 2,
/// <summary>
/// CPU inference. Corresponds to in WorkerFactory.Type.CSharp Barracuda.
/// Burst is recommended instead; this is kept for legacy compatibility.
/// </summary>
CPU = 3,
}
/// <summary>

/// </summary>
private bool m_AnalyticsSent;
/// <inheritdoc />
/// <summary>
/// Instantiate a BarracudaPolicy with the necessary objects for it to run.
/// </summary>
/// <param name="actionSpec">The action spec of the behavior.</param>
/// <param name="actuators">The actuators used for this behavior.</param>
/// <param name="model">The Neural Network to use.</param>
/// <param name="inferenceDevice">Which device Barracuda will run on.</param>
/// <param name="behaviorName">The name of the behavior.</param>
public BarracudaPolicy(
ActionSpec actionSpec,
IList<IActuator> actuators,

/// <inheritdoc />
public void RequestDecision(AgentInfo info, List<ISensor> sensors)
{
SendAnalytics(sensors);
m_AgentId = info.episodeId;
m_ModelRunner?.PutObservations(info, sensors);
}
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
void SendAnalytics(IList<ISensor> sensors)
{
if (!m_AnalyticsSent)
{
m_AnalyticsSent = true;

m_Actuators
);
}
m_AgentId = info.episodeId;
m_ModelRunner?.PutObservations(info, sensors);
}
/// <inheritdoc />

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


}
[HideInInspector, SerializeField]
InferenceDevice m_InferenceDevice = InferenceDevice.Burst;
InferenceDevice m_InferenceDevice = InferenceDevice.Default;
/// <summary>
/// How inference is performed for this Agent's model.

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


/// Trivial implementation of the IList interface that does nothing.
/// This is only used for "writing" observations that we will discard.
/// </summary>
class NullList : IList<float>
internal class NullList : IList<float>
{
public IEnumerator<float> GetEnumerator()
{

{
foreach (var sensor in sensors)
{
if (sensor.GetCompressionType() == SensorCompressionType.None)
if (sensor.GetCompressionSpec().SensorCompressionType == SensorCompressionType.None)
{
m_ObservationWriter.SetTarget(m_NullList, sensor.GetObservationSpec(), 0);
sensor.Write(m_ObservationWriter);

14
com.unity.ml-agents/Runtime/Policies/RemotePolicy.cs


using System.Diagnostics;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Analytics;

string m_FullyQualifiedBehaviorName;
ActionSpec m_ActionSpec;
ActionBuffers m_LastActionBuffer;
private bool m_AnalyticsSent = false;
bool m_AnalyticsSent;
internal ICommunicator m_Communicator;

/// <inheritdoc />
public void RequestDecision(AgentInfo info, List<ISensor> sensors)
{
SendAnalytics(sensors);
m_AgentId = info.episodeId;
m_Communicator?.PutObservations(m_FullyQualifiedBehaviorName, info, sensors);
}
[Conditional("MLA_UNITY_ANALYTICS_MODULE")]
void SendAnalytics(IList<ISensor> sensors)
{
if (!m_AnalyticsSent)
{
m_AnalyticsSent = true;

m_Actuators
);
}
m_AgentId = info.episodeId;
m_Communicator?.PutObservations(m_FullyQualifiedBehaviorName, info, sensors);
}
/// <inheritdoc />

6
com.unity.ml-agents/Runtime/Sensors/BufferSensor.cs


}
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return SensorCompressionType.None;
return CompressionSpec.Default();
}
/// <inheritdoc/>

{
return BuiltInSensorType.BufferSensor;
}
}

10
com.unity.ml-agents/Runtime/Sensors/BufferSensorComponent.cs


private BufferSensor m_Sensor;
/// <inheritdoc/>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return m_Sensor;
}
/// <inheritdoc/>
public override int[] GetObservationShape()
{
return new[] { MaxNumObservables, ObservableSize };
return new ISensor[] { m_Sensor };
}
/// <summary>

5
com.unity.ml-agents/Runtime/Sensors/CameraSensor.cs


public void Reset() { }
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return m_CompressionType;
return new CompressionSpec(m_CompressionType);
}
/// <summary>

{
return BuiltInSensorType.CameraSensor;
}
}
}

21
com.unity.ml-agents/Runtime/Sensors/CameraSensorComponent.cs


/// Creates the <see cref="CameraSensor"/>
/// </summary>
/// <returns>The created <see cref="CameraSensor"/> object for this component.</returns>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return new StackingSensor(m_Sensor, ObservationStacks);
return new ISensor[] { new StackingSensor(m_Sensor, ObservationStacks) };
return m_Sensor;
}
/// <summary>
/// Computes the observation shape of the sensor.
/// </summary>
/// <returns>The observation shape of the associated <see cref="CameraSensor"/> object.</returns>
public override int[] GetObservationShape()
{
var stacks = ObservationStacks > 1 ? ObservationStacks : 1;
var cameraSensorshape = CameraSensor.GenerateShape(m_Width, m_Height, Grayscale);
if (stacks > 1)
{
cameraSensorshape[cameraSensorshape.Length - 1] *= stacks;
}
return cameraSensorshape;
return new ISensor[] { m_Sensor };
}
/// <summary>

24
com.unity.ml-agents/Runtime/Sensors/ISensor.cs


namespace Unity.MLAgents.Sensors
{
/// <summary>
/// The compression setting for visual/camera observations.
/// </summary>
public enum SensorCompressionType
{
/// <summary>
/// No compression. Data is preserved as float arrays.
/// </summary>
None,
/// <summary>
/// PNG format. Data will be stored in binary format.
/// </summary>
PNG
}
/// <summary>
/// The Dimension property flags of the observations
/// </summary>
[System.Flags]

void Reset();
/// <summary>
/// Return the compression type being used. If no compression is used, return
/// <see cref="SensorCompressionType.None"/>.
/// Return information on the compression type being used. If no compression is used, return
/// <see cref="CompressionSpec.Default()"/>.
/// <returns>Compression type used by the sensor.</returns>
SensorCompressionType GetCompressionType();
/// <returns>CompressionSpec used by the sensor.</returns>
CompressionSpec GetCompressionSpec();
/// <summary>
/// Get the name of the sensor. This is used to ensure deterministic sorting of the sensors

14
com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensor.cs


}
/// <inheritdoc/>
public virtual SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return SensorCompressionType.None;
return CompressionSpec.Default();
}
/// <inheritdoc/>

unscaledCastRadius;
// Do the cast and assign the hit information for each detectable tag.
bool castHit;
float hitFraction;
GameObject hitObject;
var castHit = false;
var hitFraction = 1.0f;
GameObject hitObject = null;
#if MLA_UNITY_PHYSICS_MODULE
RaycastHit rayHit;
if (scaledCastRadius > 0f)
{

// To avoid 0/0, set the fraction to 0.
hitFraction = castHit ? (scaledRayLength > 0 ? rayHit.distance / scaledRayLength : 0.0f) : 1.0f;
hitObject = castHit ? rayHit.collider.gameObject : null;
#endif
#if MLA_UNITY_PHYSICS2D_MODULE
RaycastHit2D rayHit;
if (scaledCastRadius > 0f)
{

castHit = rayHit;
hitFraction = castHit ? rayHit.fraction : 1.0f;
hitObject = castHit ? rayHit.collider.gameObject : null;
#endif
}
var rayOutput = new RayPerceptionOutput.RayOutput

9
com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponent2D.cs


[AddComponentMenu("ML Agents/Ray Perception Sensor 2D", (int)MenuGroup.Sensors)]
public class RayPerceptionSensorComponent2D : RayPerceptionSensorComponentBase
{
/// <summary>
/// Initializes the raycast sensor component.
/// </summary>
public RayPerceptionSensorComponent2D()
{
// Set to the 2D defaults (just in case they ever diverge).
RayLayerMask = Physics2D.DefaultRaycastLayers;
}
/// <inheritdoc/>
public override RayPerceptionCastType GetCastType()
{

24
com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponentBase.cs


set { m_RayLength = value; UpdateSensor(); }
}
// The value of the default layers.
const int k_PhysicsDefaultLayers = -5;
LayerMask m_RayLayerMask = Physics.DefaultRaycastLayers;
LayerMask m_RayLayerMask = k_PhysicsDefaultLayers;
/// <summary>
/// Controls which layers the rays can hit.

/// Returns an initialized raycast sensor.
/// </summary>
/// <returns></returns>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
{
var rayPerceptionInput = GetRayPerceptionInput();

{
var stackingSensor = new StackingSensor(m_RaySensor, ObservationStacks);
return stackingSensor;
return new ISensor[] { stackingSensor };
return m_RaySensor;
return new ISensor[] { m_RaySensor };
}
/// <summary>

anglesOut[2 * i + 2] = 90 + (i + 1) * delta;
}
return anglesOut;
}
/// <summary>
/// Returns the observation shape for this raycast sensor which depends on the number
/// of tags for detected objects and the number of rays.
/// </summary>
/// <returns></returns>
public override int[] GetObservationShape()
{
var numRays = 2 * RaysPerDirection + 1;
var numTags = m_DetectableTags?.Count ?? 0;
var obsSize = (numTags + 2) * numRays;
var stacks = ObservationStacks > 1 ? ObservationStacks : 1;
return new[] { obsSize * stacks };
}
/// <summary>

5
com.unity.ml-agents/Runtime/Sensors/Reflection/ReflectionSensorBase.cs


public void Reset() { }
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return SensorCompressionType.None;
return CompressionSpec.Default();
}
/// <inheritdoc/>

{
return BuiltInSensorType.ReflectionSensor;
}
}
}

5
com.unity.ml-agents/Runtime/Sensors/RenderTextureSensor.cs


public void Reset() { }
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return m_CompressionType;
return new CompressionSpec(m_CompressionType);
}
/// <inheritdoc/>

}
/// <summary>
/// Converts a RenderTexture to a 2D texture.

22
com.unity.ml-agents/Runtime/Sensors/RenderTextureSensorComponent.cs


}
/// <inheritdoc/>
public override ISensor CreateSensor()
public override ISensor[] CreateSensors()
return new StackingSensor(m_Sensor, ObservationStacks);
}
return m_Sensor;
}
/// <inheritdoc/>
public override int[] GetObservationShape()
{
var width = RenderTexture != null ? RenderTexture.width : 0;
var height = RenderTexture != null ? RenderTexture.height : 0;
var observationShape = new[] { height, width, Grayscale ? 1 : 3 };
var stacks = ObservationStacks > 1 ? ObservationStacks : 1;
if (stacks > 1)
{
observationShape[2] *= stacks;
return new ISensor[] { new StackingSensor(m_Sensor, ObservationStacks) };
return observationShape;
return new ISensor[] { m_Sensor };
}
/// <summary>

13
com.unity.ml-agents/Runtime/Sensors/SensorComponent.cs


public abstract class SensorComponent : MonoBehaviour
{
/// <summary>
/// Create the ISensor. This is called by the Agent when it is initialized.
/// Create the ISensors. This is called by the Agent when it is initialized.
/// <returns>Created ISensor object.</returns>
public abstract ISensor CreateSensor();
/// <summary>
/// Returns the shape of the sensor observations that will be created.
/// </summary>
/// <returns>Shape of the sensor observation.</returns>
public abstract int[] GetObservationShape();
/// <returns>Created ISensor objects.</returns>
public abstract ISensor[] CreateSensors();
}
}

27
com.unity.ml-agents/Runtime/Sensors/StackingSensor.cs


/// Internally, a circular buffer of arrays is used. The m_CurrentIndex represents the most recent observation.
/// Currently, observations are stacked on the last dimension.
/// </summary>
public class StackingSensor : ISparseChannelSensor, IBuiltInSensor
public class StackingSensor : ISensor, IBuiltInSensor
{
/// <summary>
/// The wrapped sensor.

m_StackedObservations[i] = new float[m_UnstackedObservationSize];
}
if (m_WrappedSensor.GetCompressionType() != SensorCompressionType.None)
if (m_WrappedSensor.GetCompressionSpec().SensorCompressionType != SensorCompressionType.None)
{
m_StackedCompressedObservations = new byte[numStackedObservations][];
m_EmptyCompressedObservation = CreateEmptyPNG();

{
Array.Clear(m_StackedObservations[i], 0, m_StackedObservations[i].Length);
}
if (m_WrappedSensor.GetCompressionType() != SensorCompressionType.None)
if (m_WrappedSensor.GetCompressionSpec().SensorCompressionType != SensorCompressionType.None)
{
for (var i = 0; i < m_NumStackedObservations; i++)
{

return outputBytes;
}
/// <inheritdoc/>
public int[] GetCompressedChannelMapping()
public CompressionSpec GetCompressionSpec()
return m_CompressionMapping;
}
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
{
return m_WrappedSensor.GetCompressionType();
var wrappedSpec = m_WrappedSensor.GetCompressionSpec();
return new CompressionSpec(wrappedSpec.SensorCompressionType, m_CompressionMapping);
}
/// <summary>

}
/// <summary>
/// Constrct stacked CompressedChannelMapping.
/// Construct stacked CompressedChannelMapping.
/// </summary>
internal int[] ConstructStackedCompressedChannelMapping(ISensor wrappedSenesor)
{

int[] wrappedMapping = null;
int wrappedNumChannel = m_WrappedSpec.Shape[2];
var sparseChannelSensor = m_WrappedSensor as ISparseChannelSensor;
if (sparseChannelSensor != null)
{
wrappedMapping = sparseChannelSensor.GetCompressedChannelMapping();
}
wrappedMapping = wrappedSenesor.GetCompressionSpec().CompressedChannelMapping;
if (wrappedMapping == null)
{
if (wrappedNumChannel == 1)

6
com.unity.ml-agents/Runtime/Sensors/VectorSensor.cs


}
/// <inheritdoc/>
public virtual SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return SensorCompressionType.None;
return CompressionSpec.Default();
}
/// <inheritdoc/>

void AddFloatObs(float obs)
{
#if DEBUG
#endif
m_Observations.Add(obs);
}

10
com.unity.ml-agents/Runtime/Unity.ML-Agents.asmdef


"name": "com.unity.modules.unityanalytics",
"expression": "1.0.0",
"define": "MLA_UNITY_ANALYTICS_MODULE"
},
{
"name": "com.unity.modules.physics",
"expression": "1.0.0",
"define": "MLA_UNITY_PHYSICS_MODULE"
},
{
"name": "com.unity.modules.physics2d",
"expression": "1.0.0",
"define": "MLA_UNITY_PHYSICS2D_MODULE"
}
]
}

7
com.unity.ml-agents/Runtime/Utilities.cs


using System;
using System.Diagnostics;
/// <summary>
/// Calculates the cumulative sum of an integer array. The result array will be one element
/// larger than the input array since it has a padded 0 at the beginning.

return result;
}
#if DEBUG
[Conditional("DEBUG")]
if (float.IsNaN(value))
{
throw new ArgumentException($"NaN {valueCategory} passed to {caller}.");

throw new ArgumentException($"Inifinity {valueCategory} passed to {caller}.");
}
}
#endif
}

6
com.unity.ml-agents/Tests/Editor/AcademyTests.cs


using NUnit.Framework;
using Unity.MLAgents.Sensors;
using UnityEngine;
#if UNITY_2019_3_OR_NEWER
#endif
namespace Unity.MLAgents.Tests
{

[Test]
public void TestPackageVersion()
{
// Make sure that the version strings in the package and Academy don't get out of sync.
// Unfortunately, the PackageInfo methods don't exist in earlier versions of the editor.
#if UNITY_2019_3_OR_NEWER
#endif
}
class RecursiveAgent : Agent

12
com.unity.ml-agents/Tests/Editor/Analytics/TrainingAnalyticsTest.cs


using Unity.MLAgents.Actuators;
using Unity.MLAgents.Analytics;
using Unity.MLAgents.Policies;
using UnityEditor;
namespace Unity.MLAgents.Tests.Analytics
{

Assert.AreEqual(2, remotePolicyEvent.ActuatorInfos[0].NumContinuousActions);
Assert.AreEqual(0, remotePolicyEvent.ActuatorInfos[0].NumDiscreteActions);
}
[Test]

}
Academy.Instance.Dispose();
}
[Test]
public void TestEnableAnalytics()
{
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE
Assert.IsTrue(EditorAnalytics.enabled == TrainingAnalytics.EnableAnalytics());
#else
Assert.IsFalse(TrainingAnalytics.EnableAnalytics());
#endif
}
}
}

137
com.unity.ml-agents/Tests/Editor/Communicator/GrpcExtensionsTests.cs


using System;
using System.Text.RegularExpressions;
using Google.Protobuf;
using Google.Protobuf.Collections;
using NUnit.Framework;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Demonstrations;

using Unity.MLAgents.Analytics;
using Unity.MLAgents.CommunicatorObjects;
using UnityEngine;
using UnityEngine.TestTools;
namespace Unity.MLAgents.Tests
{

[SetUp]
public void SetUp()
{
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
}
[Test]
public void TestDefaultBrainParametersToProto()
{

Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
HybridActions = false
};
brain.ToProto("foo", false);
}
[Test]

var actionSpec = new ActionSpec();
actionSpec.ToBrainParametersProto("foo", false);
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
HybridActions = false
};
actionSpec.ToBrainParametersProto("foo", false);
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
HybridActions = false
};
actionSpec.ToBrainParametersProto("foo", false);
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
HybridActions = false
};
actionSpec.ToBrainParametersProto("foo", false);
}
[Test]
public void ToBrainParameters()
{
// Should be able to convert a default instance to proto.
var actionSpec = new ActionSpec();
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
HybridActions = false
};
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
// Continuous
actionSpec = ActionSpec.MakeContinuous(3);
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
HybridActions = false
};
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
// Discrete
actionSpec = ActionSpec.MakeDiscrete(1, 2, 3);
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
HybridActions = false
};
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
}
[Test]

var agentInfo = new AgentInfo();
agentInfo.ToInfoActionPairProto();
var pairProto = agentInfo.ToInfoActionPairProto();
pairProto.AgentInfo.Observations.Add(new ObservationProto
{
CompressedData = ByteString.Empty,
CompressionType = CompressionTypeProto.None,
FloatData = new ObservationProto.Types.FloatData(),
ObservationType = ObservationTypeProto.Default,
Name = "Sensor"
});
pairProto.AgentInfo.Observations[0].Shape.Add(0);
pairProto.GetObservationSummaries();
agentInfo.ToAgentInfoProto();
agentInfo.groupId = 1;
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
MultiAgentGroups = false
};
agentInfo.ToAgentInfoProto();
LogAssert.Expect(LogType.Warning, new Regex(".+"));
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
{
BaseRLCapabilities = true,
MultiAgentGroups = true
};
agentInfo.ToAgentInfoProto();
}

public void Reset() { }
public SensorCompressionType GetCompressionType()
public CompressionSpec GetCompressionSpec()
return CompressionType;
return new CompressionSpec(CompressionType);
}
}
class DummySparseChannelSensor : DummySensor, ISparseChannelSensor
{
public int[] Mapping;
internal DummySparseChannelSensor()
{
}
public int[] GetCompressedChannelMapping()
{
return Mapping;
}
}

Assert.AreEqual(obsProto.CompressedData.Length, 0);
}
}
[Test]
public void TestIsTrivialMapping()
{
Assert.AreEqual(GrpcExtensions.IsTrivialMapping(new DummySensor()), true);
var sparseChannelSensor = new DummySparseChannelSensor();
sparseChannelSensor.Mapping = null;
Assert.AreEqual(GrpcExtensions.IsTrivialMapping(sparseChannelSensor), true);
sparseChannelSensor.Mapping = new[] { 0, 0, 0 };
Assert.AreEqual(GrpcExtensions.IsTrivialMapping(sparseChannelSensor), true);
sparseChannelSensor.Mapping = new[] { 0, 1, 2, 3, 4 };
Assert.AreEqual(GrpcExtensions.IsTrivialMapping(sparseChannelSensor), true);
sparseChannelSensor.Mapping = new[] { 1, 2, 3, 4, -1, -1 };
Assert.AreEqual(GrpcExtensions.IsTrivialMapping(sparseChannelSensor), false);
sparseChannelSensor.Mapping = new[] { 0, 0, 0, 1, 1, 1 };
Assert.AreEqual(GrpcExtensions.IsTrivialMapping(sparseChannelSensor), false);
}
[Test]
public void TestDefaultTrainingEvents()
{

4
com.unity.ml-agents/Tests/Editor/Inference/ModelRunnerTest.cs


var modelRunner = new ModelRunner(discreteONNXModel, actionSpec, InferenceDevice.Burst);
var info1 = new AgentInfo();
info1.episodeId = 1;
modelRunner.PutObservations(info1, new[] { sensor_21_20_3.CreateSensor() }.ToList());
modelRunner.PutObservations(info1, new[] { sensor_21_20_3.CreateSensors()[0] }.ToList());
modelRunner.PutObservations(info2, new[] { sensor_21_20_3.CreateSensor() }.ToList());
modelRunner.PutObservations(info2, new[] { sensor_21_20_3.CreateSensors()[0] }.ToList());
modelRunner.DecideBatch();

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

正在加载...
取消
保存