diff --git a/.yamato/com.unity.ml-agents-test.yml b/.yamato/com.unity.ml-agents-test.yml
index 26a8a617bd..012aa1f8e9 100644
--- a/.yamato/com.unity.ml-agents-test.yml
+++ b/.yamato/com.unity.ml-agents-test.yml
@@ -2,15 +2,23 @@ test_editors:
- version: 2018.4
# 2018.4 doesn't support code-coverage
enableCodeCoverage: !!bool false
+ # We want some scene tests to run in the DevProject, but packages there only support 2019+
+ testProject: Project
- version: 2019.4
enableCodeCoverage: !!bool true
+ testProject: DevProject
- version: 2020.1
enableCodeCoverage: !!bool true
+ testProject: DevProject
- version: 2020.2
enableCodeCoverage: !!bool true
+ testProject: DevProject
+
trunk_editor:
- version: trunk
enableCodeCoverage: !!bool true
+ testProject: DevProject
+
test_platforms:
- name: win
type: Unity::VM
@@ -24,6 +32,7 @@ test_platforms:
type: Unity::VM
image: package-ci/ubuntu:stable
flavor: b1.medium
+
packages:
- name: com.unity.ml-agents
assembly: Unity.ML-Agents
@@ -70,7 +79,7 @@ test_{{ package.name }}_{{ platform.name }}_{{ editor.version }}:
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 Project --package-filter {{ package.name }} {{ coverageOptions }} --extra-utr-arg "reruncount=2"
+ - upm-ci project test -u {{ editor.version }} --project-path {{ editor.testProject }} --package-filter {{ package.name }} {{ coverageOptions }} --extra-utr-arg "reruncount=2"
{% if editor.enableCodeCoverage %}
- python3 ml-agents/tests/yamato/check_coverage_percent.py upm-ci~/test-results/ {{ package.minCoveragePct }}
{% endif %}
@@ -88,6 +97,7 @@ test_{{ package.name }}_{{ platform.name }}_{{ editor.version }}:
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 %}
@@ -116,7 +126,7 @@ test_{{ package.name }}_{{ platform.name }}_trunk:
- python -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 Project --package-filter {{ package.name }} {{ coverageOptions }} --extra-utr-arg "reruncount=2"
+ - upm-ci project test -u {{ editor.version }} --project-path {{ editor.testProject }} --package-filter {{ package.name }} {{ coverageOptions }} --extra-utr-arg "reruncount=2"
{% if editor.enableCodeCoverage %}
- python3 ml-agents/tests/yamato/check_coverage_percent.py upm-ci~/test-results/ {{ package.minCoveragePct }}
{% endif %}
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Editor.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Editor.meta
new file mode 100644
index 0000000000..5c4107a279
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: dc5370caac53244599df51d5c6d39876
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Performance.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Performance.meta
similarity index 100%
rename from DevProject/Assets/ML-Agents/Scripts/Tests/Performance.meta
rename to DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Performance.meta
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Performance/SensorPerformanceTests.cs b/DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Performance/SensorPerformanceTests.cs
similarity index 100%
rename from DevProject/Assets/ML-Agents/Scripts/Tests/Performance/SensorPerformanceTests.cs
rename to DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Performance/SensorPerformanceTests.cs
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Performance/SensorPerformanceTests.cs.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Performance/SensorPerformanceTests.cs.meta
similarity index 100%
rename from DevProject/Assets/ML-Agents/Scripts/Tests/Performance/SensorPerformanceTests.cs.meta
rename to DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Performance/SensorPerformanceTests.cs.meta
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Tests.asmdef b/DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Tests.asmdef
similarity index 100%
rename from DevProject/Assets/ML-Agents/Scripts/Tests/Tests.asmdef
rename to DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Tests.asmdef
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Tests.asmdef.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Tests.asmdef.meta
similarity index 100%
rename from DevProject/Assets/ML-Agents/Scripts/Tests/Tests.asmdef.meta
rename to DevProject/Assets/ML-Agents/Scripts/Tests/Editor/Tests.asmdef.meta
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime.meta
new file mode 100644
index 0000000000..5b7b31c463
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 216d926b40df54befbf2bed34587444d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest.meta
new file mode 100644
index 0000000000..e6d6569c66
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a36f098f1b304456cb2edcb3719fa416
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs
new file mode 100644
index 0000000000..169cb6d7db
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs
@@ -0,0 +1,36 @@
+using System.Collections;
+using NUnit.Framework;
+using UnityEngine.TestTools;
+using UnityEngine;
+using UnityEngine.SceneManagement;
+using Unity.MLAgents;
+#if UNITY_EDITOR
+using UnityEditor.SceneManagement;
+#endif
+
+namespace Tests
+{
+ public class AcademyStepperTest
+ {
+ [SetUp]
+ public void Setup()
+ {
+ SceneManager.LoadScene("ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene");
+ }
+
+ ///
+ /// Verify in each update, the Academy is only stepped once.
+ ///
+ [UnityTest]
+ public IEnumerator AcademyStepperCleanupPasses()
+ {
+ var academy = Academy.Instance;
+ int initStepCount = academy.TotalStepCount;
+ for (var i = 0; i < 5; i++)
+ {
+ yield return new WaitForFixedUpdate();
+ Assert.True(academy.TotalStepCount - initStepCount == i + 1);
+ }
+ }
+ }
+}
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs.meta
new file mode 100644
index 0000000000..53c36b14ac
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTest.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: acf0056574b054463a787f33ac6f4f59
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity
new file mode 100644
index 0000000000..1486ca4f31
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity
@@ -0,0 +1,385 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_OcclusionBakeSettings:
+ smallestOccluder: 5
+ smallestHole: 0.25
+ backfaceThreshold: 100
+ m_SceneGUID: 00000000000000000000000000000000
+ m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 9
+ m_Fog: 0
+ m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+ m_FogMode: 3
+ m_FogDensity: 0.01
+ m_LinearFogStart: 0
+ m_LinearFogEnd: 300
+ m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+ m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+ m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+ m_AmbientIntensity: 1
+ m_AmbientMode: 0
+ m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+ m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+ m_HaloStrength: 0.5
+ m_FlareStrength: 1
+ m_FlareFadeSpeed: 3
+ m_HaloTexture: {fileID: 0}
+ m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+ m_DefaultReflectionMode: 0
+ m_DefaultReflectionResolution: 128
+ m_ReflectionBounces: 1
+ m_ReflectionIntensity: 1
+ m_CustomReflection: {fileID: 0}
+ m_Sun: {fileID: 0}
+ m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
+ m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 11
+ m_GIWorkflowMode: 1
+ m_GISettings:
+ serializedVersion: 2
+ m_BounceScale: 1
+ m_IndirectOutputScale: 1
+ m_AlbedoBoost: 1
+ m_EnvironmentLightingMode: 0
+ m_EnableBakedLightmaps: 1
+ m_EnableRealtimeLightmaps: 0
+ m_LightmapEditorSettings:
+ serializedVersion: 12
+ m_Resolution: 2
+ m_BakeResolution: 40
+ m_AtlasSize: 1024
+ m_AO: 0
+ m_AOMaxDistance: 1
+ m_CompAOExponent: 1
+ m_CompAOExponentDirect: 0
+ m_ExtractAmbientOcclusion: 0
+ m_Padding: 2
+ m_LightmapParameters: {fileID: 0}
+ m_LightmapsBakeMode: 1
+ m_TextureCompression: 1
+ m_FinalGather: 0
+ m_FinalGatherFiltering: 1
+ m_FinalGatherRayCount: 256
+ m_ReflectionCompression: 2
+ m_MixedBakeMode: 2
+ m_BakeBackend: 1
+ m_PVRSampling: 1
+ m_PVRDirectSampleCount: 32
+ m_PVRSampleCount: 512
+ m_PVRBounces: 2
+ m_PVREnvironmentSampleCount: 256
+ m_PVREnvironmentReferencePointCount: 2048
+ m_PVRFilteringMode: 1
+ m_PVRDenoiserTypeDirect: 1
+ m_PVRDenoiserTypeIndirect: 1
+ m_PVRDenoiserTypeAO: 1
+ m_PVRFilterTypeDirect: 0
+ m_PVRFilterTypeIndirect: 0
+ m_PVRFilterTypeAO: 0
+ m_PVREnvironmentMIS: 1
+ m_PVRCulling: 1
+ m_PVRFilteringGaussRadiusDirect: 1
+ m_PVRFilteringGaussRadiusIndirect: 5
+ m_PVRFilteringGaussRadiusAO: 2
+ m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+ m_PVRFilteringAtrousPositionSigmaIndirect: 2
+ m_PVRFilteringAtrousPositionSigmaAO: 1
+ m_ExportTrainingData: 0
+ m_TrainingDataDestination: TrainingData
+ m_LightProbeSampleCountMultiplier: 4
+ m_LightingDataAsset: {fileID: 0}
+ m_UseShadowmask: 1
+--- !u!196 &4
+NavMeshSettings:
+ serializedVersion: 2
+ m_ObjectHideFlags: 0
+ m_BuildSettings:
+ serializedVersion: 2
+ agentTypeID: 0
+ agentRadius: 0.5
+ agentHeight: 2
+ agentSlope: 45
+ agentClimb: 0.4
+ ledgeDropHeight: 0
+ maxJumpAcrossDistance: 0
+ minRegionArea: 2
+ manualCellSize: 0
+ cellSize: 0.16666667
+ manualTileSize: 0
+ tileSize: 256
+ accuratePlacement: 0
+ debug:
+ m_Flags: 0
+ m_NavMeshData: {fileID: 0}
+--- !u!1 &187484343
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 187484345}
+ - component: {fileID: 187484344}
+ m_Layer: 0
+ m_Name: Directional Light
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!108 &187484344
+Light:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 187484343}
+ m_Enabled: 1
+ serializedVersion: 10
+ m_Type: 1
+ m_Shape: 0
+ m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+ m_Intensity: 1
+ m_Range: 10
+ m_SpotAngle: 30
+ m_InnerSpotAngle: 21.80208
+ m_CookieSize: 10
+ m_Shadows:
+ m_Type: 2
+ m_Resolution: -1
+ m_CustomResolution: -1
+ m_Strength: 1
+ m_Bias: 0.05
+ m_NormalBias: 0.4
+ m_NearPlane: 0.2
+ m_CullingMatrixOverride:
+ e00: 1
+ e01: 0
+ e02: 0
+ e03: 0
+ e10: 0
+ e11: 1
+ e12: 0
+ e13: 0
+ e20: 0
+ e21: 0
+ e22: 1
+ e23: 0
+ e30: 0
+ e31: 0
+ e32: 0
+ e33: 1
+ m_UseCullingMatrixOverride: 0
+ m_Cookie: {fileID: 0}
+ m_DrawHalo: 0
+ m_Flare: {fileID: 0}
+ m_RenderMode: 0
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingLayerMask: 1
+ m_Lightmapping: 4
+ m_LightShadowCasterMode: 0
+ m_AreaSize: {x: 1, y: 1}
+ m_BounceIntensity: 1
+ m_ColorTemperature: 6570
+ m_UseColorTemperature: 0
+ m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+ m_UseBoundingSphereOverride: 0
+ m_ShadowRadius: 0
+ m_ShadowAngle: 0
+--- !u!4 &187484345
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 187484343}
+ m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+ m_LocalPosition: {x: 0, y: 3, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
+--- !u!115 &539349017
+MonoScript:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name:
+ serializedVersion: 5
+ m_Script:
+ m_DefaultReferences: {}
+ m_Icon: {fileID: 0}
+ m_ExecutionOrder: 0
+ m_ClassName: AcademyFixedUpdateStepper
+ m_Namespace: Unity.MLAgents
+--- !u!1 &617287731
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 617287733}
+ - component: {fileID: 617287732}
+ m_Layer: 0
+ m_Name: AcademyFixedUpdateStepperLeaked
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &617287732
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 617287731}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 539349017}
+ m_Name:
+ m_EditorClassIdentifier:
+--- !u!4 &617287733
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 617287731}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 3
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1058198914
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1058198917}
+ - component: {fileID: 1058198916}
+ - component: {fileID: 1058198915}
+ m_Layer: 0
+ m_Name: Main Camera
+ m_TagString: MainCamera
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!81 &1058198915
+AudioListener:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1058198914}
+ m_Enabled: 1
+--- !u!20 &1058198916
+Camera:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1058198914}
+ m_Enabled: 1
+ serializedVersion: 2
+ m_ClearFlags: 1
+ m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+ m_projectionMatrixMode: 1
+ m_GateFitMode: 2
+ m_FOVAxisMode: 0
+ m_SensorSize: {x: 36, y: 24}
+ m_LensShift: {x: 0, y: 0}
+ m_FocalLength: 50
+ m_NormalizedViewPortRect:
+ serializedVersion: 2
+ x: 0
+ y: 0
+ width: 1
+ height: 1
+ near clip plane: 0.3
+ far clip plane: 1000
+ field of view: 60
+ orthographic: 0
+ orthographic size: 5
+ m_Depth: -1
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingPath: -1
+ m_TargetTexture: {fileID: 0}
+ m_TargetDisplay: 0
+ m_TargetEye: 3
+ m_HDR: 1
+ m_AllowMSAA: 1
+ m_AllowDynamicResolution: 0
+ m_ForceIntoRT: 0
+ m_OcclusionCulling: 1
+ m_StereoConvergence: 10
+ m_StereoSeparation: 0.022
+--- !u!4 &1058198917
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1058198914}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 1, z: -10}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1875138784
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1875138786}
+ m_Layer: 0
+ m_Name: GameObject
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1875138786
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1875138784}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 2
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity.meta
new file mode 100644
index 0000000000..5fdf5de344
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 9bafc50b1e55b43b2b1ae9620f1f8311
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef
new file mode 100644
index 0000000000..a70fee785a
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef
@@ -0,0 +1,21 @@
+{
+ "name": "Runtime",
+ "references": [
+ "Unity.ML-Agents"
+ ],
+ "optionalUnityReferences": [
+ "TestAssemblies"
+ ],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": true,
+ "precompiledReferences": [
+ "System.IO.Abstractions.dll",
+ "System.IO.Abstractions.TestingHelpers.dll",
+ "Google.Protobuf.dll"
+ ],
+ "autoReferenced": false,
+ "defineConstraints": [
+ "UNITY_INCLUDE_TESTS"
+ ]
+}
diff --git a/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef.meta b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef.meta
new file mode 100644
index 0000000000..6d864ffb9f
--- /dev/null
+++ b/DevProject/Assets/ML-Agents/Scripts/Tests/Runtime/Runtime.asmdef.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 3ce87dece2ef3488c983d27b05720aa2
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/DevProject/ProjectSettings/EditorBuildSettings.asset b/DevProject/ProjectSettings/EditorBuildSettings.asset
index 0147887ef4..8629f07f66 100644
--- a/DevProject/ProjectSettings/EditorBuildSettings.asset
+++ b/DevProject/ProjectSettings/EditorBuildSettings.asset
@@ -4,5 +4,8 @@
EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
- m_Scenes: []
+ m_Scenes:
+ - enabled: 1
+ path: Assets/ML-Agents/Scripts/Tests/Runtime/AcademyTest/AcademyStepperTestScene.unity
+ guid: 9bafc50b1e55b43b2b1ae9620f1f8311
m_configObjects: {}
diff --git a/com.unity.ml-agents/CHANGELOG.md b/com.unity.ml-agents/CHANGELOG.md
index cb4fb1986f..55c31ba883 100755
--- a/com.unity.ml-agents/CHANGELOG.md
+++ b/com.unity.ml-agents/CHANGELOG.md
@@ -31,6 +31,7 @@ and this project adheres to
camera frame. The scene is able to train with the provided default config file. (#4511)
### Bug Fixes
#### com.unity.ml-agents (C#)
+ - Fixed a bug where accessing the Academy outside of play mode would cause the Academy to get stepped multiple times when in play mode. (#4532)
#### ml-agents / ml-agents-envs / gym-unity (Python)
diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs
index 383526b2e8..b708953d75 100644
--- a/com.unity.ml-agents/Runtime/Academy.cs
+++ b/com.unity.ml-agents/Runtime/Academy.cs
@@ -32,7 +32,16 @@ internal class AcademyFixedUpdateStepper : MonoBehaviour
{
void FixedUpdate()
{
- Academy.Instance.EnvironmentStep();
+ // Check if the stepper belongs to the current Academy and destroy it if it's not.
+ // This is to prevent from having leaked stepper from previous runs.
+ if (!Academy.IsInitialized || !Academy.Instance.IsStepperOwner(this))
+ {
+ Destroy(this.gameObject);
+ }
+ else
+ {
+ Academy.Instance.EnvironmentStep();
+ }
}
}
@@ -226,7 +235,25 @@ public int InferenceSeed
Application.quitting += Dispose;
LazyInitialize();
+
+#if UNITY_EDITOR
+ EditorApplication.playModeStateChanged += HandleOnPlayModeChanged;
+#endif
+ }
+
+#if UNITY_EDITOR
+ ///
+ /// Clean up the Academy when switching from edit mode to play mode
+ ///
+ /// State.
+ void HandleOnPlayModeChanged(PlayModeStateChange state)
+ {
+ if (state == PlayModeStateChange.ExitingEditMode)
+ {
+ Dispose();
+ }
}
+#endif
///
/// Initialize the Academy if it hasn't already been initialized.
@@ -635,5 +662,13 @@ public void Dispose()
// Reset the Lazy instance
s_Lazy = new Lazy(() => new Academy());
}
+
+ ///
+ /// Check if the input AcademyFixedUpdateStepper belongs to this Academy.
+ ///
+ internal bool IsStepperOwner(AcademyFixedUpdateStepper stepper)
+ {
+ return GameObject.ReferenceEquals(stepper.gameObject, Academy.Instance.m_StepperObject);
+ }
}
}
diff --git a/com.unity.ml-agents/Tests/Runtime/RuntimeAPITest.cs b/com.unity.ml-agents/Tests/Runtime/RuntimeAPITest.cs
index 2656482b91..62041f71f5 100644
--- a/com.unity.ml-agents/Tests/Runtime/RuntimeAPITest.cs
+++ b/com.unity.ml-agents/Tests/Runtime/RuntimeAPITest.cs
@@ -55,6 +55,10 @@ public class RuntimeApiTest
[SetUp]
public static void Setup()
{
+ if (Academy.IsInitialized)
+ {
+ Academy.Instance.Dispose();
+ }
Academy.Instance.AutomaticSteppingEnabled = false;
}