浏览代码

Code Style - apply PascalCase (#3828)

* cleanup a few classes

* cleanup raycast code

* more capitalization

* more renames

* changelog and migration

* fix MaxStep in docs

* doc string
/develop/dockerfile
GitHub 5 年前
当前提交
0a7e53be
共有 41 个文件被更改,包括 397 次插入377 次删除
  1. 4
      Project/Assets/ML-Agents/Examples/Hallway/Scripts/HallwayAgent.cs
  2. 2
      Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs
  3. 2
      Project/Assets/ML-Agents/Examples/Pyramids/Scripts/PyramidAgent.cs
  4. 8
      Project/Assets/ML-Agents/Examples/SharedAssets/Scripts/ModelOverrider.cs
  5. 2
      Project/Assets/ML-Agents/Examples/Soccer/Scripts/AgentSoccer.cs
  6. 4
      com.unity.ml-agents/CHANGELOG.md
  7. 7
      com.unity.ml-agents/Editor/AgentEditor.cs
  8. 6
      com.unity.ml-agents/Editor/BehaviorParametersEditor.cs
  9. 10
      com.unity.ml-agents/Editor/BrainParametersDrawer.cs
  10. 4
      com.unity.ml-agents/Editor/DemonstrationDrawer.cs
  11. 2
      com.unity.ml-agents/Runtime/Academy.cs
  12. 63
      com.unity.ml-agents/Runtime/Agent.cs
  13. 12
      com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs
  14. 32
      com.unity.ml-agents/Runtime/Demonstrations/DemonstrationRecorder.cs
  15. 12
      com.unity.ml-agents/Runtime/DiscreteActionMasker.cs
  16. 18
      com.unity.ml-agents/Runtime/Inference/BarracudaModelParamLoader.cs
  17. 4
      com.unity.ml-agents/Runtime/Inference/TensorApplier.cs
  18. 33
      com.unity.ml-agents/Runtime/Policies/BehaviorParameters.cs
  19. 34
      com.unity.ml-agents/Runtime/Policies/BrainParameters.cs
  20. 4
      com.unity.ml-agents/Runtime/Sensors/CameraSensor.cs
  21. 20
      com.unity.ml-agents/Runtime/Sensors/CameraSensorComponent.cs
  22. 102
      com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensor.cs
  23. 2
      com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponent2D.cs
  24. 8
      com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponent3D.cs
  25. 54
      com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponentBase.cs
  26. 2
      com.unity.ml-agents/Runtime/Sensors/RenderTextureSensor.cs
  27. 22
      com.unity.ml-agents/Runtime/Sensors/RenderTextureSensorComponent.cs
  28. 2
      com.unity.ml-agents/Tests/Editor/BehaviorParameterTests.cs
  29. 34
      com.unity.ml-agents/Tests/Editor/DemonstrationTests.cs
  30. 26
      com.unity.ml-agents/Tests/Editor/EditModeTestActionMasker.cs
  31. 8
      com.unity.ml-agents/Tests/Editor/EditModeTestInternalBrainTensorGenerator.cs
  32. 8
      com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs
  33. 18
      com.unity.ml-agents/Tests/Editor/ModelRunnerTest.cs
  34. 30
      com.unity.ml-agents/Tests/Editor/ParameterLoaderTest.cs
  35. 42
      com.unity.ml-agents/Tests/Editor/PublicAPI/PublicApiValidation.cs
  36. 10
      com.unity.ml-agents/Tests/Editor/Sensor/CameraSensorComponentTest.cs
  37. 78
      com.unity.ml-agents/Tests/Editor/Sensor/RayPerceptionSensorTests.cs
  38. 6
      com.unity.ml-agents/Tests/Editor/Sensor/RenderTextureSensorComponentTests.cs
  39. 32
      com.unity.ml-agents/Tests/Runtime/RuntimeAPITest.cs
  40. 2
      docs/Learning-Environment-Examples.md
  41. 5
      docs/Migrating.md

4
Project/Assets/ML-Agents/Examples/Hallway/Scripts/HallwayAgent.cs


{
if (useVectorObs)
{
sensor.AddObservation(StepCount / (float)maxStep);
sensor.AddObservation(StepCount / (float)MaxStep);
}
}

public override void OnActionReceived(float[] vectorAction)
{
AddReward(-1f / maxStep);
AddReward(-1f / MaxStep);
MoveAgent(vectorAction);
}

2
Project/Assets/ML-Agents/Examples/PushBlock/Scripts/PushAgentBasic.cs


MoveAgent(vectorAction);
// Penalty given each step to encourage agent to finish task quickly.
AddReward(-1f / maxStep);
AddReward(-1f / MaxStep);
}
public override void Heuristic(float[] actionsOut)

2
Project/Assets/ML-Agents/Examples/Pyramids/Scripts/PyramidAgent.cs


public override void OnActionReceived(float[] vectorAction)
{
AddReward(-1f / maxStep);
AddReward(-1f / MaxStep);
MoveAgent(vectorAction);
}

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


if (m_MaxEpisodes > 0)
{
// For Agents without maxSteps, exit as soon as we've hit the target number of episodes.
// For Agents that specify maxStep, also make sure we've gone at least that many steps.
// For Agents that specify MaxStep, also make sure we've gone at least that many steps.
if (m_Agent.CompletedEpisodes >= m_MaxEpisodes && m_NumSteps > m_MaxEpisodes * m_Agent.maxStep)
if (m_Agent.CompletedEpisodes >= m_MaxEpisodes && m_NumSteps > m_MaxEpisodes * m_Agent.MaxStep)
{
Application.Quit(0);
}

if (!m_BehaviorNameOverrides.ContainsKey(behaviorName))
{
Debug.Log($"No override for behaviorName {behaviorName}");
Debug.Log($"No override for BehaviorName {behaviorName}");
return null;
}

{
m_Agent.LazyInitialize();
var bp = m_Agent.GetComponent<BehaviorParameters>();
var name = bp.behaviorName;
var name = bp.BehaviorName;
var nnModel = GetModelForBehaviorName(name);
Debug.Log($"Overriding behavior {name} for agent with model {nnModel?.name}");

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


public override void Initialize()
{
m_Existential = 1f / maxStep;
m_Existential = 1f / MaxStep;
m_BehaviorParameters = gameObject.GetComponent<BehaviorParameters>();
if (m_BehaviorParameters.TeamId == (int)Team.Blue)
{

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


`UnityToGymWrapper` and no longer creates the `UnityEnvironment`.
Instead, the `UnityEnvironment` must be passed as input to the
constructor of `UnityToGymWrapper`
- Public fields and properties on several classes were renamed to follow Unity's
C# style conventions. All public fields and properties now use "PascalCase"
instead of "camelCase"; for example, `Agent.maxStep` was renamed to
`Agent.MaxStep`. For a full list of changes, see the pull request. (#3828)
### Minor Changes

7
com.unity.ml-agents/Editor/AgentEditor.cs


var serializedAgent = serializedObject;
serializedAgent.Update();
var maxSteps = serializedAgent.FindProperty(
"maxStep");
var maxSteps = serializedAgent.FindProperty("MaxStep");
new GUIContent(
"Max Step", "The per-agent maximum number of steps."));
new GUIContent("Max Step", "The per-agent maximum number of steps.")
);
serializedAgent.ApplyModifiedProperties();

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


var model = (NNModel)serializedObject.FindProperty("m_Model").objectReferenceValue;
var behaviorParameters = (BehaviorParameters)target;
SensorComponent[] sensorComponents;
if (behaviorParameters.useChildSensors)
if (behaviorParameters.UseChildSensors)
{
sensorComponents = behaviorParameters.GetComponentsInChildren<SensorComponent>();
}

}
var brainParameters = behaviorParameters.brainParameters;
var brainParameters = behaviorParameters.BrainParameters;
if (model != null)
{
barracudaModel = ModelLoader.Load(model);

var failedChecks = Inference.BarracudaModelParamLoader.CheckModel(
barracudaModel, brainParameters, sensorComponents, behaviorParameters.behaviorType
barracudaModel, brainParameters, sensorComponents, behaviorParameters.BehaviorType
);
foreach (var check in failedChecks)
{

10
com.unity.ml-agents/Editor/BrainParametersDrawer.cs


// The height of a line in the Unity Inspectors
const float k_LineHeight = 17f;
const int k_VecObsNumLine = 3;
const string k_ActionSizePropName = "vectorActionSize";
const string k_ActionTypePropName = "vectorActionSpaceType";
const string k_ActionDescriptionPropName = "vectorActionDescriptions";
const string k_VecObsPropName = "vectorObservationSize";
const string k_NumVecObsPropName = "numStackedVectorObservations";
const string k_ActionSizePropName = "VectorActionSize";
const string k_ActionTypePropName = "VectorActionSpaceType";
const string k_ActionDescriptionPropName = "VectorActionDescriptions";
const string k_VecObsPropName = "VectorObservationSize";
const string k_NumVecObsPropName = "NumStackedVectorObservations";
/// <inheritdoc />
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)

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


/// </summary>
void MakeActionsProperty(SerializedProperty property)
{
var actSizeProperty = property.FindPropertyRelative("vectorActionSize");
var actSpaceTypeProp = property.FindPropertyRelative("vectorActionSpaceType");
var actSizeProperty = property.FindPropertyRelative("VectorActionSize");
var actSpaceTypeProp = property.FindPropertyRelative("VectorActionSpaceType");
var vecActSizeLabel =
actSizeProperty.displayName + ": " + BuildIntArrayLabel(actSizeProperty);

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


/// NNModel and the InferenceDevice as provided.
/// </summary>
/// <param name="model">The NNModel the ModelRunner must use.</param>
/// <param name="brainParameters">The brainParameters used to create the ModelRunner.</param>
/// <param name="brainParameters">The BrainParameters used to create the ModelRunner.</param>
/// <param name="inferenceDevice">
/// The inference device (CPU or GPU) the ModelRunner will use.
/// </param>

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


using MLAgents.Sensors;
using MLAgents.Demonstrations;
using MLAgents.Policies;
using UnityEngine.Serialization;
namespace MLAgents
{

IPolicy m_Brain;
BehaviorParameters m_PolicyFactory;
/// This code is here to make the upgrade path for users using maxStep
/// This code is here to make the upgrade path for users using MaxStep
/// easier. We will hook into the Serialization code and make sure that
/// agentParameters.maxStep and this.maxStep are in sync.
[Serializable]

/// {
/// if (!Academy.Instance.IsCommunicatorOn)
/// {
/// this.maxStep = 0;
/// this.MaxStep = 0;
/// }
/// }
/// }

/// </example>
[HideInInspector] public int maxStep;
[FormerlySerializedAs("maxStep")]
[HideInInspector] public int MaxStep;
/// Current Agent information (message sent to Brain).
AgentInfo m_Info;

/// </example>
public void OnBeforeSerialize()
{
// Manages a serialization upgrade issue from v0.13 to v0.14 where maxStep moved
// Manages a serialization upgrade issue from v0.13 to v0.14 where MaxStep moved
if (maxStep == 0 && maxStep != agentParameters.maxStep && !hasUpgradedFromAgentParameters)
if (MaxStep == 0 && MaxStep != agentParameters.maxStep && !hasUpgradedFromAgentParameters)
maxStep = agentParameters.maxStep;
MaxStep = agentParameters.maxStep;
}
hasUpgradedFromAgentParameters = true;
}

/// </example>
public void OnAfterDeserialize()
{
// Manages a serialization upgrade issue from v0.13 to v0.14 where maxStep moved
// Manages a serialization upgrade issue from v0.13 to v0.14 where MaxStep moved
if (maxStep == 0 && maxStep != agentParameters.maxStep && !hasUpgradedFromAgentParameters)
if (MaxStep == 0 && MaxStep != agentParameters.maxStep && !hasUpgradedFromAgentParameters)
maxStep = agentParameters.maxStep;
MaxStep = agentParameters.maxStep;
}
hasUpgradedFromAgentParameters = true;
}

NNModel model,
InferenceDevice inferenceDevice = InferenceDevice.CPU)
{
if (behaviorName == m_PolicyFactory.behaviorName &&
model == m_PolicyFactory.model &&
inferenceDevice == m_PolicyFactory.inferenceDevice)
if (behaviorName == m_PolicyFactory.BehaviorName &&
model == m_PolicyFactory.Model &&
inferenceDevice == m_PolicyFactory.InferenceDevice)
m_PolicyFactory.model = model;
m_PolicyFactory.inferenceDevice = inferenceDevice;
m_PolicyFactory.behaviorName = behaviorName;
m_PolicyFactory.Model = model;
m_PolicyFactory.InferenceDevice = inferenceDevice;
m_PolicyFactory.BehaviorName = behaviorName;
ReloadPolicy();
}

void UpdateRewardStats()
{
var gaugeName = $"{m_PolicyFactory.behaviorName}.CumulativeReward";
var gaugeName = $"{m_PolicyFactory.BehaviorName}.CumulativeReward";
TimerStack.Instance.SetGauge(gaugeName, GetCumulativeReward());
}

/// at the end of an episode.
void ResetData()
{
var param = m_PolicyFactory.brainParameters;
var param = m_PolicyFactory.BrainParameters;
m_ActionMasker = new DiscreteActionMasker(param);
// If we haven't initialized vectorActions, initialize to 0. This should only
// happen during the creation of the Agent. In subsequent episodes, vectorAction

m_Action.vectorActions = new float[param.numActions];
m_Info.storedVectorActions = new float[param.numActions];
m_Action.vectorActions = new float[param.NumActions];
m_Info.storedVectorActions = new float[param.NumActions];
}
}

///
/// [GameObject]: https://docs.unity3d.com/Manual/GameObjects.html
/// </remarks>
public virtual void Initialize(){}
public virtual void Initialize() {}
/// <summary>
/// Implement `Heuristic()` to choose an action for this agent using a custom heuristic.

/// [Input Manager]: https://docs.unity3d.com/Manual/class-InputManager.html
/// [Input System package]: https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/index.html
/// </example>
/// <param name="actionsOut">Array for the output actions.</param>
/// <seealso cref="OnActionReceived(float[])"/>
public virtual void Heuristic(float[] actionsOut)
{

{
// Get all attached sensor components
SensorComponent[] attachedSensorComponents;
if (m_PolicyFactory.useChildSensors)
if (m_PolicyFactory.UseChildSensors)
{
attachedSensorComponents = GetComponentsInChildren<SensorComponent>();
}

}
// Support legacy CollectObservations
var param = m_PolicyFactory.brainParameters;
if (param.vectorObservationSize > 0)
var param = m_PolicyFactory.BrainParameters;
if (param.VectorObservationSize > 0)
collectObservationsSensor = new VectorSensor(param.vectorObservationSize);
if (param.numStackedVectorObservations > 1)
collectObservationsSensor = new VectorSensor(param.VectorObservationSize);
if (param.NumStackedVectorObservations > 1)
collectObservationsSensor, param.numStackedVectorObservations);
collectObservationsSensor, param.NumStackedVectorObservations);
sensors.Add(stackingSensor);
}
else

}
using (TimerStack.Instance.Scoped("CollectDiscreteActionMasks"))
{
if (m_PolicyFactory.brainParameters.vectorActionSpaceType == SpaceType.Discrete)
if (m_PolicyFactory.BrainParameters.VectorActionSpaceType == SpaceType.Discrete)
{
CollectDiscreteActionMasks(m_ActionMasker);
}

/// vector of observations. You must build the vector in the same order
/// each time `CollectObservations()` is called and the length of the vector
/// must always be the same. In addition, the length of the observation must
/// match the <see cref="BrainParameters.vectorObservationSize"/>
/// match the <see cref="BrainParameters.VectorObservationSize"/>
/// attribute of the linked Brain, which is set in the Editor on the
/// **Behavior Parameters** component attached to the agent's [GameObject].
///

/// by the <see cref="BrainParameters"/> of the agent's associated
/// <see cref="BehaviorParameters"/> component.
/// </param>
public virtual void OnActionReceived(float[] vectorAction){}
public virtual void OnActionReceived(float[] vectorAction) {}
/// <summary>
/// Implement `OnEpisodeBegin()` to set up an Agent instance at the beginning

OnActionReceived(m_Action.vectorActions);
}
if ((m_StepCount >= maxStep) && (maxStep > 0))
if ((m_StepCount >= MaxStep) && (MaxStep > 0))
{
NotifyAgentDone(DoneReason.MaxStepReached);
_AgentReset();

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


{
var brainParametersProto = new BrainParametersProto
{
VectorActionSize = { bp.vectorActionSize },
VectorActionSize = { bp.VectorActionSize },
(SpaceTypeProto)bp.vectorActionSpaceType,
(SpaceTypeProto)bp.VectorActionSpaceType,
brainParametersProto.VectorActionDescriptions.AddRange(bp.vectorActionDescriptions);
brainParametersProto.VectorActionDescriptions.AddRange(bp.VectorActionDescriptions);
return brainParametersProto;
}

{
var bp = new BrainParameters
{
vectorActionSize = bpp.VectorActionSize.ToArray(),
vectorActionDescriptions = bpp.VectorActionDescriptions.ToArray(),
vectorActionSpaceType = (SpaceType)bpp.VectorActionSpaceType
VectorActionSize = bpp.VectorActionSize.ToArray(),
VectorActionDescriptions = bpp.VectorActionDescriptions.ToArray(),
VectorActionSpaceType = (SpaceType)bpp.VectorActionSpaceType
};
return bp;
}

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


using UnityEngine;
using System.IO;
using MLAgents.Policies;
using UnityEngine.Serialization;
namespace MLAgents.Demonstrations
{

/// <summary>
/// Whether or not to record demonstrations.
/// </summary>
[FormerlySerializedAs("record")]
public bool record;
public bool Record;
[FormerlySerializedAs("demonstrationName")]
public string demonstrationName;
public string DemonstrationName;
[FormerlySerializedAs("demonstrationDirectory")]
public string demonstrationDirectory;
public string DemonstrationDirectory;
DemonstrationWriter m_DemoWriter;
internal const int MaxNameLength = 16;

void Update()
{
if (record)
if (Record)
{
LazyInitialize();
}

m_FileSystem = fileSystem ?? new FileSystem();
var behaviorParams = GetComponent<BehaviorParameters>();
if (string.IsNullOrEmpty(demonstrationName))
if (string.IsNullOrEmpty(DemonstrationName))
demonstrationName = behaviorParams.behaviorName;
DemonstrationName = behaviorParams.BehaviorName;
if (string.IsNullOrEmpty(demonstrationDirectory))
if (string.IsNullOrEmpty(DemonstrationDirectory))
demonstrationDirectory = Path.Combine(Application.dataPath, k_DefaultDirectoryName);
DemonstrationDirectory = Path.Combine(Application.dataPath, k_DefaultDirectoryName);
demonstrationName = SanitizeName(demonstrationName, MaxNameLength);
var filePath = MakeDemonstrationFilePath(m_FileSystem, demonstrationDirectory, demonstrationName);
DemonstrationName = SanitizeName(DemonstrationName, MaxNameLength);
var filePath = MakeDemonstrationFilePath(m_FileSystem, DemonstrationDirectory, DemonstrationName);
var stream = m_FileSystem.File.Create(filePath);
m_DemoWriter = new DemonstrationWriter(stream);

}
/// <summary>
/// Gets a unique path for the demonstrationName in the demonstrationDirectory.
/// Gets a unique path for the DemonstrationName in the DemonstrationDirectory.
/// </summary>
/// <param name="fileSystem"></param>
/// <param name="demonstrationDirectory"></param>

{
var behaviorParams = GetComponent<BehaviorParameters>();
demoWriter.Initialize(
demonstrationName,
behaviorParams.brainParameters,
behaviorParams.fullyQualifiedBehaviorName
DemonstrationName,
behaviorParams.BrainParameters,
behaviorParams.FullyQualifiedBehaviorName
);
m_Agent.DemonstrationWriters.Add(demoWriter);
}

12
com.unity.ml-agents/Runtime/DiscreteActionMasker.cs


public void SetMask(int branch, IEnumerable<int> actionIndices)
{
// If the branch does not exist, raise an error
if (branch >= m_BrainParameters.vectorActionSize.Length)
if (branch >= m_BrainParameters.VectorActionSize.Length)
var totalNumberActions = m_BrainParameters.vectorActionSize.Sum();
var totalNumberActions = m_BrainParameters.VectorActionSize.Sum();
// By default, the masks are null. If we want to specify a new mask, we initialize
// the actionMasks with trues.

// indices for each branch.
if (m_StartingActionIndices == null)
{
m_StartingActionIndices = Utilities.CumSum(m_BrainParameters.vectorActionSize);
m_StartingActionIndices = Utilities.CumSum(m_BrainParameters.VectorActionSize);
if (actionIndex >= m_BrainParameters.vectorActionSize[branch])
if (actionIndex >= m_BrainParameters.VectorActionSize[branch])
{
throw new UnityAgentsException(
"Invalid Action Masking: Action Mask is too large for specified branch.");

void AssertMask()
{
// Action Masks can only be used in Discrete Control.
if (m_BrainParameters.vectorActionSpaceType != SpaceType.Discrete)
if (m_BrainParameters.VectorActionSpaceType != SpaceType.Discrete)
var numBranches = m_BrainParameters.vectorActionSize.Length;
var numBranches = m_BrainParameters.VectorActionSize.Length;
for (var branchIndex = 0; branchIndex < numBranches; branchIndex++)
{
if (AreAllActionsMasked(branchIndex))

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


var tensorsNames = GetInputTensors(model).Select(x => x.name).ToList();
// If there is no Vector Observation Input but the Brain Parameters expect one.
if ((brainParameters.vectorObservationSize != 0) &&
if ((brainParameters.VectorObservationSize != 0) &&
(!tensorsNames.Contains(TensorNames.VectorObservationPlaceholder)))
{
failedModelChecks.Add(

static string CheckVectorObsShape(
BrainParameters brainParameters, TensorProxy tensorProxy, SensorComponent[] sensorComponents)
{
var vecObsSizeBp = brainParameters.vectorObservationSize;
var numStackedVector = brainParameters.numStackedVectorObservations;
var vecObsSizeBp = brainParameters.VectorObservationSize;
var numStackedVector = brainParameters.NumStackedVectorObservations;
var totalVecObsSizeT = tensorProxy.shape[tensorProxy.shape.Length - 1];
var totalVectorSensorSize = 0;

static string CheckPreviousActionShape(
BrainParameters brainParameters, TensorProxy tensorProxy, SensorComponent[] sensorComponents)
{
var numberActionsBp = brainParameters.vectorActionSize.Length;
var numberActionsBp = brainParameters.VectorActionSize.Length;
var numberActionsT = tensorProxy.shape[tensorProxy.shape.Length - 1];
if (numberActionsBp != numberActionsT)
{

return failedModelChecks;
}
if (isContinuous == ModelActionType.Continuous &&
brainParameters.vectorActionSpaceType != SpaceType.Continuous)
brainParameters.VectorActionSpaceType != SpaceType.Continuous)
{
failedModelChecks.Add(
"Model has been trained using Continuous Control but the Brain Parameters " +

if (isContinuous == ModelActionType.Discrete &&
brainParameters.vectorActionSpaceType != SpaceType.Discrete)
brainParameters.VectorActionSpaceType != SpaceType.Discrete)
{
failedModelChecks.Add(
"Model has been trained using Discrete Control but the Brain Parameters " +

var tensorTester = new Dictionary<string, Func<BrainParameters, TensorShape, int, string>>();
if (brainParameters.vectorActionSpaceType == SpaceType.Continuous)
if (brainParameters.VectorActionSpaceType == SpaceType.Continuous)
{
tensorTester[TensorNames.ActionOutput] = CheckContinuousActionOutputShape;
}

static string CheckDiscreteActionOutputShape(
BrainParameters brainParameters, TensorShape shape, int modelActionSize)
{
var bpActionSize = brainParameters.vectorActionSize.Sum();
var bpActionSize = brainParameters.VectorActionSize.Sum();
if (modelActionSize != bpActionSize)
{
return "Action Size of the model does not match. The BrainParameters expect " +

static string CheckContinuousActionOutputShape(
BrainParameters brainParameters, TensorShape shape, int modelActionSize)
{
var bpActionSize = brainParameters.vectorActionSize[0];
var bpActionSize = brainParameters.VectorActionSize[0];
if (modelActionSize != bpActionSize)
{
return "Action Size of the model does not match. The BrainParameters expect " +

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


Dictionary<int, List<float>> memories,
object barracudaModel = null)
{
if (bp.vectorActionSpaceType == SpaceType.Continuous)
if (bp.VectorActionSpaceType == SpaceType.Continuous)
{
m_Dict[TensorNames.ActionOutput] = new ContinuousActionOutputApplier();
}

new DiscreteActionOutputApplier(bp.vectorActionSize, seed, allocator);
new DiscreteActionOutputApplier(bp.VectorActionSize, seed, allocator);
}
m_Dict[TensorNames.RecurrentOutput] = new MemoryOutputApplier(memories);

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


InferenceOnly
}
/// <summary>
/// A component for setting an <seealso cref="Agent"/> instance's behavior and
/// brain properties.

BrainParameters m_BrainParameters = new BrainParameters();
/// <summary>
/// The associated <see cref="BrainParameters"/> for this behavior.
/// The associated <see cref="Policies.BrainParameters"/> for this behavior.
public BrainParameters brainParameters
public BrainParameters BrainParameters
{
get { return m_BrainParameters; }
internal set { m_BrainParameters = value; }

/// <summary>
/// The neural network model used when in inference mode.
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,InferenceDevice)"/>
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,Policies.InferenceDevice)"/>
public NNModel model
public NNModel Model
{
get { return m_Model; }
set { m_Model = value; UpdateAgentPolicy(); }

/// <summary>
/// How inference is performed for this Agent's model.
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,InferenceDevice)"/>
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,Policies.InferenceDevice)"/>
public InferenceDevice inferenceDevice
public InferenceDevice InferenceDevice
{
get { return m_InferenceDevice; }
set { m_InferenceDevice = value; UpdateAgentPolicy();}

/// <summary>
/// The BehaviorType for the Agent.
/// </summary>
public BehaviorType behaviorType
public BehaviorType BehaviorType
{
get { return m_BehaviorType; }
set { m_BehaviorType = value; UpdateAgentPolicy(); }

/// <summary>
/// The name of this behavior, which is used as a base name. See
/// <see cref="fullyQualifiedBehaviorName"/> for the full name.
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,InferenceDevice)"/>
/// <see cref="FullyQualifiedBehaviorName"/> for the full name.
/// This should not be set at runtime; use <see cref="Agent.SetModel(string,NNModel,Policies.InferenceDevice)"/>
public string behaviorName
public string BehaviorName
{
get { return m_BehaviorName; }
set { m_BehaviorName = value; UpdateAgentPolicy(); }

/// Whether or not to use all the sensor components attached to child GameObjects of the agent.
/// Note that changing this after the Agent has been initialized will not have any effect.
/// </summary>
public bool useChildSensors
public bool UseChildSensors
{
get { return m_UseChildSensors; }
set { m_UseChildSensors = value; }

/// Returns the behavior name, concatenated with any other metadata (i.e. team id).
/// </summary>
public string fullyQualifiedBehaviorName
public string FullyQualifiedBehaviorName
{
get { return m_BehaviorName + "?team=" + TeamId; }
}

switch (m_BehaviorType)
{
case BehaviorType.HeuristicOnly:
return new HeuristicPolicy(heuristic, m_BrainParameters.numActions);
return new HeuristicPolicy(heuristic, m_BrainParameters.NumActions);
case BehaviorType.InferenceOnly:
{
if (m_Model == null)

case BehaviorType.Default:
if (Academy.Instance.IsCommunicatorOn)
{
return new RemotePolicy(m_BrainParameters, fullyQualifiedBehaviorName);
return new RemotePolicy(m_BrainParameters, FullyQualifiedBehaviorName);
}
if (m_Model != null)
{

{
return new HeuristicPolicy(heuristic, m_BrainParameters.numActions);
return new HeuristicPolicy(heuristic, m_BrainParameters.NumActions);
return new HeuristicPolicy(heuristic, m_BrainParameters.numActions);
return new HeuristicPolicy(heuristic, m_BrainParameters.NumActions);
}
}

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


using System;
using UnityEngine;
using UnityEngine.Serialization;
namespace MLAgents.Policies
{

/// <value>
/// The length of the vector containing observation values.
/// </value>
public int vectorObservationSize = 1;
[FormerlySerializedAs("vectorObservationSize")]
public int VectorObservationSize = 1;
[Range(1, 50)] public int numStackedVectorObservations = 1;
[FormerlySerializedAs("numStackedVectorObservations")]
[Range(1, 50)] public int NumStackedVectorObservations = 1;
/// <summary>
/// The size of the action space.

/// the action.
/// For the discrete action space: the number of branches in the action space.
/// </value>
public int[] vectorActionSize = new[] {1};
[FormerlySerializedAs("vectorActionSize")]
public int[] VectorActionSize = new[] {1};
public string[] vectorActionDescriptions;
[FormerlySerializedAs("vectorActionDescriptions")]
public string[] VectorActionDescriptions;
public SpaceType vectorActionSpaceType = SpaceType.Discrete;
[FormerlySerializedAs("vectorActionSpaceType")]
public SpaceType VectorActionSpaceType = SpaceType.Discrete;
public int numActions
public int NumActions
switch (vectorActionSpaceType)
switch (VectorActionSpaceType)
return vectorActionSize.Length;
return VectorActionSize.Length;
return vectorActionSize[0];
return VectorActionSize[0];
default:
return 0;
}

{
return new BrainParameters
{
vectorObservationSize = vectorObservationSize,
numStackedVectorObservations = numStackedVectorObservations,
vectorActionSize = (int[])vectorActionSize.Clone(),
vectorActionDescriptions = (string[])vectorActionDescriptions.Clone(),
vectorActionSpaceType = vectorActionSpaceType
VectorObservationSize = VectorObservationSize,
NumStackedVectorObservations = NumStackedVectorObservations,
VectorActionSize = (int[])VectorActionSize.Clone(),
VectorActionDescriptions = (string[])VectorActionDescriptions.Clone(),
VectorActionSpaceType = VectorActionSpaceType
};
}
}

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


/// <summary>
/// The Camera used for rendering the sensor observations.
/// </summary>
public Camera camera
public Camera Camera
{
get { return m_Camera; }
set { m_Camera = value; }

/// The compression type used by the sensor.
/// </summary>
public SensorCompressionType compressionType
public SensorCompressionType CompressionType
{
get { return m_CompressionType; }
set { m_CompressionType = value; }

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


/// <summary>
/// Camera object that provides the data to the sensor.
/// </summary>
public new Camera camera
public Camera Camera
{
get { return m_Camera; }
set { m_Camera = value; UpdateSensor(); }

/// Name of the generated <see cref="CameraSensor"/> object.
/// Note that changing this at runtime does not affect how the Agent sorts the sensors.
/// </summary>
public string sensorName
public string SensorName
{
get { return m_SensorName; }
set { m_SensorName = value; }

/// Width of the generated observation.
/// Note that changing this after the sensor is created has no effect.
/// </summary>
public int width
public int Width
{
get { return m_Width; }
set { m_Width = value; }

/// Height of the generated observation.
/// Note that changing this after the sensor is created has no effect.
/// </summary>
public int height
public int Height
{
get { return m_Height; }
set { m_Height = value; }

/// Whether to generate grayscale images or color.
/// Note that changing this after the sensor is created has no effect.
/// </summary>
public bool grayscale
public bool Grayscale
{
get { return m_Grayscale; }
set { m_Grayscale = value; }

/// <summary>
/// The compression type to use for the sensor.
/// </summary>
public SensorCompressionType compression
public SensorCompressionType CompressionType
{
get { return m_Compression; }
set { m_Compression = value; UpdateSensor(); }

/// <returns>The created <see cref="CameraSensor"/> object for this component.</returns>
public override ISensor CreateSensor()
{
m_Sensor = new CameraSensor(m_Camera, m_Width, m_Height, grayscale, m_SensorName, compression);
m_Sensor = new CameraSensor(m_Camera, m_Width, m_Height, Grayscale, m_SensorName, m_Compression);
return m_Sensor;
}

/// <returns>The observation shape of the associated <see cref="CameraSensor"/> object.</returns>
public override int[] GetObservationShape()
{
return CameraSensor.GenerateShape(m_Width, m_Height, grayscale);
return CameraSensor.GenerateShape(m_Width, m_Height, Grayscale);
}
/// <summary>

{
if (m_Sensor != null)
{
m_Sensor.camera = m_Camera;
m_Sensor.compressionType = m_Compression;
m_Sensor.Camera = m_Camera;
m_Sensor.CompressionType = m_Compression;
}
}
}

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


/// <summary>
/// Length of the rays to cast. This will be scaled up or down based on the scale of the transform.
/// </summary>
public float rayLength;
public float RayLength;
public IReadOnlyList<string> detectableTags;
public IReadOnlyList<string> DetectableTags;
public IReadOnlyList<float> angles;
public IReadOnlyList<float> Angles;
public float startOffset;
public float StartOffset;
public float endOffset;
public float EndOffset;
public float castRadius;
public float CastRadius;
public Transform transform;
public Transform Transform;
public RayPerceptionCastType castType;
public RayPerceptionCastType CastType;
public int layerMask;
public int LayerMask;
/// <summary>
/// Returns the expected number of floats in the output.

{
return (detectableTags.Count + 2) * angles.Count;
return (DetectableTags.Count + 2) * Angles.Count;
}
/// <summary>

/// <returns>A tuple of the start and end positions in world space.</returns>
public (Vector3 StartPositionWorld, Vector3 EndPositionWorld) RayExtents(int rayIndex)
{
var angle = angles[rayIndex];
var angle = Angles[rayIndex];
if (castType == RayPerceptionCastType.Cast3D)
if (CastType == RayPerceptionCastType.Cast3D)
startPositionLocal = new Vector3(0, startOffset, 0);
endPositionLocal = PolarToCartesian3D(rayLength, angle);
endPositionLocal.y += endOffset;
startPositionLocal = new Vector3(0, StartOffset, 0);
endPositionLocal = PolarToCartesian3D(RayLength, angle);
endPositionLocal.y += EndOffset;
endPositionLocal = PolarToCartesian2D(rayLength, angle);
endPositionLocal = PolarToCartesian2D(RayLength, angle);
var startPositionWorld = transform.TransformPoint(startPositionLocal);
var endPositionWorld = transform.TransformPoint(endPositionLocal);
var startPositionWorld = Transform.TransformPoint(startPositionLocal);
var endPositionWorld = Transform.TransformPoint(endPositionLocal);
return (StartPositionWorld : startPositionWorld, EndPositionWorld : endPositionWorld);
}

/// <summary>
/// Whether or not the ray hit anything.
/// </summary>
public bool hasHit;
public bool HasHit;
/// Whether or not the ray hit an object whose tag is in the input's detectableTags list.
/// Whether or not the ray hit an object whose tag is in the input's DetectableTags list.
public bool hitTaggedObject;
public bool HitTaggedObject;
/// The index of the hit object's tag in the detectableTags list, or -1 if there was no hit, or the
/// The index of the hit object's tag in the DetectableTags list, or -1 if there was no hit, or the
public int hitTagIndex;
public int HitTagIndex;
public float hitFraction;
public float HitFraction;
/// 1. A one-hot encoding for detectable tags. For example, if detectableTags.Length = n, the
/// 1. A one-hot encoding for detectable tags. For example, if DetectableTags.Length = n, the
/// first n elements of the sublist will be a one-hot encoding of the detectableTag that was hit, or
/// all zeroes otherwise.
/// 2. The 'numDetectableTags' element of the sublist will be 1 if the ray missed everything, or 0 if it hit

/// </summary>
/// <param name="numDetectableTags"></param>
/// <param name="rayIndex"></param>
/// <param name="buffer">Output buffer. The size must be equal to (numDetectableTags+2) * rayOutputs.Length</param>
/// <param name="buffer">Output buffer. The size must be equal to (numDetectableTags+2) * RayOutputs.Length</param>
if (hitTaggedObject)
if (HitTaggedObject)
buffer[bufferOffset + hitTagIndex] = 1f;
buffer[bufferOffset + HitTagIndex] = 1f;
buffer[bufferOffset + numDetectableTags] = hasHit ? 0f : 1f;
buffer[bufferOffset + numDetectableTags + 1] = hitFraction;
buffer[bufferOffset + numDetectableTags] = HasHit ? 0f : 1f;
buffer[bufferOffset + numDetectableTags + 1] = HitFraction;
}
}

public RayOutput[] rayOutputs;
public RayOutput[] RayOutputs;
}
/// <summary>

{
Array.Clear(m_Observations, 0, m_Observations.Length);
var numRays = m_RayPerceptionInput.angles.Count;
var numDetectableTags = m_RayPerceptionInput.detectableTags.Count;
var numRays = m_RayPerceptionInput.Angles.Count;
var numDetectableTags = m_RayPerceptionInput.DetectableTags.Count;
if (m_DebugDisplayInfo != null)
{

public static RayPerceptionOutput Perceive(RayPerceptionInput input)
{
RayPerceptionOutput output = new RayPerceptionOutput();
output.rayOutputs = new RayPerceptionOutput.RayOutput[input.angles.Count];
output.RayOutputs = new RayPerceptionOutput.RayOutput[input.Angles.Count];
for (var rayIndex = 0; rayIndex < input.angles.Count; rayIndex++)
for (var rayIndex = 0; rayIndex < input.Angles.Count; rayIndex++)
output.rayOutputs[rayIndex] = PerceiveSingleRay(input, rayIndex, out debugRay);
output.RayOutputs[rayIndex] = PerceiveSingleRay(input, rayIndex, out debugRay);
}
return output;

out DebugDisplayInfo.RayInfo debugRayOut
)
{
var unscaledRayLength = input.rayLength;
var unscaledCastRadius = input.castRadius;
var unscaledRayLength = input.RayLength;
var unscaledCastRadius = input.CastRadius;
var extents = input.RayExtents(rayIndex);
var startPositionWorld = extents.StartPositionWorld;

float hitFraction;
GameObject hitObject;
if (input.castType == RayPerceptionCastType.Cast3D)
if (input.CastType == RayPerceptionCastType.Cast3D)
scaledRayLength, input.layerMask);
scaledRayLength, input.LayerMask);
scaledRayLength, input.layerMask);
scaledRayLength, input.LayerMask);
}
// If scaledRayLength is 0, we still could have a hit with sphere casts (maybe?).

if (scaledCastRadius > 0f)
{
rayHit = Physics2D.CircleCast(startPositionWorld, scaledCastRadius, rayDirection,
scaledRayLength, input.layerMask);
scaledRayLength, input.LayerMask);
rayHit = Physics2D.Raycast(startPositionWorld, rayDirection, scaledRayLength, input.layerMask);
rayHit = Physics2D.Raycast(startPositionWorld, rayDirection, scaledRayLength, input.LayerMask);
}
castHit = rayHit;

var rayOutput = new RayPerceptionOutput.RayOutput
{
hasHit = castHit,
hitFraction = hitFraction,
hitTaggedObject = false,
hitTagIndex = -1
HasHit = castHit,
HitFraction = hitFraction,
HitTaggedObject = false,
HitTagIndex = -1
for (var i = 0; i < input.detectableTags.Count; i++)
for (var i = 0; i < input.DetectableTags.Count; i++)
if (hitObject.CompareTag(input.detectableTags[i]))
if (hitObject.CompareTag(input.DetectableTags[i]))
rayOutput.hitTaggedObject = true;
rayOutput.hitTagIndex = i;
rayOutput.HitTaggedObject = true;
rayOutput.HitTagIndex = i;
break;
}
}

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


public RayPerceptionSensorComponent2D()
{
// Set to the 2D defaults (just in case they ever diverge).
rayLayerMask = Physics2D.DefaultRaycastLayers;
RayLayerMask = Physics2D.DefaultRaycastLayers;
}
/// <inheritdoc/>

8
com.unity.ml-agents/Runtime/Sensors/RayPerceptionSensorComponent3D.cs


/// <summary>
/// Ray start is offset up or down by this amount.
/// </summary>
public float startVerticalOffset
public float StartVerticalOffset
{
get => m_StartVerticalOffset;
set { m_StartVerticalOffset = value; UpdateSensor(); }

/// <summary>
/// Ray end is offset up or down by this amount.
/// </summary>
public float endVerticalOffset
public float EndVerticalOffset
{
get => m_EndVerticalOffset;
set { m_EndVerticalOffset = value; UpdateSensor(); }

/// <inheritdoc/>
public override float GetStartVerticalOffset()
{
return startVerticalOffset;
return StartVerticalOffset;
return endVerticalOffset;
return EndVerticalOffset;
}
}
}

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


/// The name of the Sensor that this component wraps.
/// Note that changing this at runtime does not affect how the Agent sorts the sensors.
/// </summary>
public string sensorName
public string SensorName
{
get { return m_SensorName; }
set { m_SensorName = value; }

/// List of tags in the scene to compare against.
/// Note that this should not be changed at runtime.
/// </summary>
public List<string> detectableTags
public List<string> DetectableTags
{
get { return m_DetectableTags; }
set { m_DetectableTags = value; }

/// Number of rays to the left and right of center.
/// Note that this should not be changed at runtime.
/// </summary>
public int raysPerDirection
public int RaysPerDirection
{
get { return m_RaysPerDirection; }
// Note: can't change at runtime

/// Cone size for rays. Using 90 degrees will cast rays to the left and right.
/// Greater than 90 degrees will go backwards.
/// </summary>
public float maxRayDegrees
public float MaxRayDegrees
{
get => m_MaxRayDegrees;
set { m_MaxRayDegrees = value; UpdateSensor(); }

/// <summary>
/// Radius of sphere to cast. Set to zero for raycasts.
/// </summary>
public float sphereCastRadius
public float SphereCastRadius
{
get => m_SphereCastRadius;
set { m_SphereCastRadius = value; UpdateSensor(); }

/// <summary>
/// Length of the rays to cast.
/// </summary>
public float rayLength
public float RayLength
{
get => m_RayLength;
set { m_RayLength = value; UpdateSensor(); }

/// <summary>
/// Controls which layers the rays can hit.
/// </summary>
public LayerMask rayLayerMask
public LayerMask RayLayerMask
{
get => m_RayLayerMask;
set { m_RayLayerMask = value; UpdateSensor(); }

/// Whether to stack previous observations. Using 1 means no previous observations.
/// Note that changing this after the sensor is created has no effect.
/// </summary>
public int observationStacks
public int ObservationStacks
{
get { return m_ObservationStacks; }
set { m_ObservationStacks = value; }

/// <summary>
/// Get the RayPerceptionSensor that was created.
/// </summary>
public RayPerceptionSensor raySensor
public RayPerceptionSensor RaySensor
{
get => m_RaySensor;
}

m_RaySensor = new RayPerceptionSensor(m_SensorName, rayPerceptionInput);
if (observationStacks != 1)
if (ObservationStacks != 1)
var stackingSensor = new StackingSensor(m_RaySensor, observationStacks);
var stackingSensor = new StackingSensor(m_RaySensor, ObservationStacks);
return stackingSensor;
}

/// <returns></returns>
public override int[] GetObservationShape()
{
var numRays = 2 * raysPerDirection + 1;
var numRays = 2 * RaysPerDirection + 1;
var stacks = observationStacks > 1 ? observationStacks : 1;
var stacks = ObservationStacks > 1 ? ObservationStacks : 1;
return new[] { obsSize * stacks };
}

/// <returns></returns>
public RayPerceptionInput GetRayPerceptionInput()
{
var rayAngles = GetRayAngles(raysPerDirection, maxRayDegrees);
var rayAngles = GetRayAngles(RaysPerDirection, MaxRayDegrees);
rayPerceptionInput.rayLength = rayLength;
rayPerceptionInput.detectableTags = detectableTags;
rayPerceptionInput.angles = rayAngles;
rayPerceptionInput.startOffset = GetStartVerticalOffset();
rayPerceptionInput.endOffset = GetEndVerticalOffset();
rayPerceptionInput.castRadius = sphereCastRadius;
rayPerceptionInput.transform = transform;
rayPerceptionInput.castType = GetCastType();
rayPerceptionInput.layerMask = rayLayerMask;
rayPerceptionInput.RayLength = RayLength;
rayPerceptionInput.DetectableTags = DetectableTags;
rayPerceptionInput.Angles = rayAngles;
rayPerceptionInput.StartOffset = GetStartVerticalOffset();
rayPerceptionInput.EndOffset = GetEndVerticalOffset();
rayPerceptionInput.CastRadius = SphereCastRadius;
rayPerceptionInput.Transform = transform;
rayPerceptionInput.CastType = GetCastType();
rayPerceptionInput.LayerMask = RayLayerMask;
return rayPerceptionInput;
}

else
{
var rayInput = GetRayPerceptionInput();
for (var rayIndex = 0; rayIndex < rayInput.angles.Count; rayIndex++)
for (var rayIndex = 0; rayIndex < rayInput.Angles.Count; rayIndex++)
{
DebugDisplayInfo.RayInfo debugRay;
RayPerceptionSensor.PerceiveSingleRay(rayInput, rayIndex, out debugRay);

var startPositionWorld = rayInfo.worldStart;
var endPositionWorld = rayInfo.worldEnd;
var rayDirection = endPositionWorld - startPositionWorld;
rayDirection *= rayInfo.rayOutput.hitFraction;
rayDirection *= rayInfo.rayOutput.HitFraction;
var lerpT = rayInfo.rayOutput.hitFraction * rayInfo.rayOutput.hitFraction;
var lerpT = rayInfo.rayOutput.HitFraction * rayInfo.rayOutput.HitFraction;
var color = Color.Lerp(rayHitColor, rayMissColor, lerpT);
color.a *= alpha;
Gizmos.color = color;

if (rayInfo.rayOutput.hasHit)
if (rayInfo.rayOutput.HasHit)
{
var hitRadius = Mathf.Max(rayInfo.castRadius, .05f);
Gizmos.DrawWireSphere(startPositionWorld + rayDirection, hitRadius);

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


/// <summary>
/// The compression type used by the sensor.
/// </summary>
public SensorCompressionType compressionType
public SensorCompressionType CompressionType
{
get { return m_CompressionType; }
set { m_CompressionType = value; }

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


RenderTextureSensor m_Sensor;
/// <summary>
/// The <see cref="RenderTexture"/> instance that the associated
/// The <see cref="UnityEngine.RenderTexture"/> instance that the associated
/// <see cref="RenderTextureSensor"/> wraps.
/// </summary>
[HideInInspector, SerializeField, FormerlySerializedAs("renderTexture")]

/// Stores the <see cref="RenderTexture"/> associated with this sensor.
/// Stores the <see cref="UnityEngine.RenderTexture"/> associated with this sensor.
public RenderTexture renderTexture
public RenderTexture RenderTexture
{
get { return m_RenderTexture; }
set { m_RenderTexture = value; }

/// Name of the generated <see cref="RenderTextureSensor"/>.
/// Note that changing this at runtime does not affect how the Agent sorts the sensors.
/// </summary>
public string sensorName
public string SensorName
{
get { return m_SensorName; }
set { m_SensorName = value; }

/// Whether the RenderTexture observation should be converted to grayscale or not.
/// Note that changing this after the sensor is created has no effect.
/// </summary>
public bool grayscale
public bool Grayscale
{
get { return m_Grayscale; }
set { m_Grayscale = value; }

/// <summary>
/// Compression type for the render texture observation.
/// </summary>
public SensorCompressionType compression
public SensorCompressionType CompressionType
{
get { return m_Compression; }
set { m_Compression = value; UpdateSensor(); }

public override ISensor CreateSensor()
{
m_Sensor = new RenderTextureSensor(renderTexture, grayscale, sensorName, compression);
m_Sensor = new RenderTextureSensor(RenderTexture, Grayscale, SensorName, m_Compression);
return m_Sensor;
}

var width = renderTexture != null ? renderTexture.width : 0;
var height = renderTexture != null ? renderTexture.height : 0;
var width = RenderTexture != null ? RenderTexture.width : 0;
var height = RenderTexture != null ? RenderTexture.height : 0;
return new[] { height, width, grayscale ? 1 : 3 };
return new[] { height, width, Grayscale ? 1 : 3 };
}
/// <summary>

{
if (m_Sensor != null)
{
m_Sensor.compressionType = m_Compression;
m_Sensor.CompressionType = m_Compression;
}
}
}

2
com.unity.ml-agents/Tests/Editor/BehaviorParameterTests.cs


{
var gameObj = new GameObject();
var bp = gameObj.AddComponent<BehaviorParameters>();
bp.behaviorType = BehaviorType.InferenceOnly;
bp.BehaviorType = BehaviorType.InferenceOnly;
Assert.Throws<UnityAgentsException>(() =>
{

34
com.unity.ml-agents/Tests/Editor/DemonstrationTests.cs


var gameobj = new GameObject("gameObj");
var bp = gameobj.AddComponent<BehaviorParameters>();
bp.brainParameters.vectorObservationSize = 3;
bp.brainParameters.numStackedVectorObservations = 2;
bp.brainParameters.vectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
bp.brainParameters.vectorActionSize = new[] { 2, 2 };
bp.brainParameters.vectorActionSpaceType = SpaceType.Discrete;
bp.BrainParameters.VectorObservationSize = 3;
bp.BrainParameters.NumStackedVectorObservations = 2;
bp.BrainParameters.VectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
bp.BrainParameters.VectorActionSize = new[] { 2, 2 };
bp.BrainParameters.VectorActionSpaceType = SpaceType.Discrete;
var agent = gameobj.AddComponent<TestAgent>();

demoRec.record = true;
demoRec.demonstrationName = k_DemoName;
demoRec.demonstrationDirectory = k_DemoDirectory;
demoRec.Record = true;
demoRec.DemonstrationName = k_DemoName;
demoRec.DemonstrationDirectory = k_DemoDirectory;
var demoWriter = demoRec.LazyInitialize(fileSystem);
Assert.IsTrue(fileSystem.Directory.Exists(k_DemoDirectory));

{
var agentGo1 = new GameObject("TestAgent");
var bpA = agentGo1.AddComponent<BehaviorParameters>();
bpA.brainParameters.vectorObservationSize = 3;
bpA.brainParameters.numStackedVectorObservations = 1;
bpA.brainParameters.vectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
bpA.brainParameters.vectorActionSize = new[] { 2, 2 };
bpA.brainParameters.vectorActionSpaceType = SpaceType.Discrete;
bpA.BrainParameters.VectorObservationSize = 3;
bpA.BrainParameters.NumStackedVectorObservations = 1;
bpA.BrainParameters.VectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
bpA.BrainParameters.VectorActionSize = new[] { 2, 2 };
bpA.BrainParameters.VectorActionSpaceType = SpaceType.Discrete;
agentGo1.AddComponent<ObservationAgent>();
var agent1 = agentGo1.GetComponent<ObservationAgent>();

var fileSystem = new MockFileSystem();
demoRecorder.demonstrationDirectory = k_DemoDirectory;
demoRecorder.demonstrationName = "TestBrain";
demoRecorder.record = true;
demoRecorder.DemonstrationDirectory = k_DemoDirectory;
demoRecorder.DemonstrationName = "TestBrain";
demoRecorder.Record = true;
demoRecorder.LazyInitialize(fileSystem);
var agentEnableMethod = typeof(Agent).GetMethod("OnEnable",

var obs = agentInfoProto.Observations[2]; // skip dummy sensors
{
var vecObs = obs.FloatData.Data;
Assert.AreEqual(bpA.brainParameters.vectorObservationSize, vecObs.Count);
Assert.AreEqual(bpA.BrainParameters.VectorObservationSize, vecObs.Count);
for (var i = 0; i < vecObs.Count; i++)
{
Assert.AreEqual((float)i + 1, vecObs[i]);

26
com.unity.ml-agents/Tests/Editor/EditModeTestActionMasker.cs


public void FailsWithContinuous()
{
var bp = new BrainParameters();
bp.vectorActionSpaceType = SpaceType.Continuous;
bp.vectorActionSize = new[] {4};
bp.VectorActionSpaceType = SpaceType.Continuous;
bp.VectorActionSize = new[] {4};
var masker = new DiscreteActionMasker(bp);
masker.SetMask(0, new[] {0});
Assert.Catch<UnityAgentsException>(() => masker.GetMask());

public void NullMask()
{
var bp = new BrainParameters();
bp.vectorActionSpaceType = SpaceType.Discrete;
bp.VectorActionSpaceType = SpaceType.Discrete;
var masker = new DiscreteActionMasker(bp);
var mask = masker.GetMask();
Assert.IsNull(mask);

public void FirstBranchMask()
{
var bp = new BrainParameters();
bp.vectorActionSpaceType = SpaceType.Discrete;
bp.vectorActionSize = new[] {4, 5, 6};
bp.VectorActionSpaceType = SpaceType.Discrete;
bp.VectorActionSize = new[] {4, 5, 6};
var masker = new DiscreteActionMasker(bp);
var mask = masker.GetMask();
Assert.IsNull(mask);

{
var bp = new BrainParameters
{
vectorActionSpaceType = SpaceType.Discrete,
vectorActionSize = new[] { 4, 5, 6 }
VectorActionSpaceType = SpaceType.Discrete,
VectorActionSize = new[] { 4, 5, 6 }
};
var masker = new DiscreteActionMasker(bp);
masker.SetMask(1, new[] {1, 2, 3});

{
var bp = new BrainParameters
{
vectorActionSpaceType = SpaceType.Discrete,
vectorActionSize = new[] { 4, 5, 6 }
VectorActionSpaceType = SpaceType.Discrete,
VectorActionSize = new[] { 4, 5, 6 }
};
var masker = new DiscreteActionMasker(bp);
masker.SetMask(1, new[] {1, 2, 3});

{
var bp = new BrainParameters
{
vectorActionSpaceType = SpaceType.Discrete,
vectorActionSize = new[] { 4, 5, 6 }
VectorActionSpaceType = SpaceType.Discrete,
VectorActionSize = new[] { 4, 5, 6 }
};
var masker = new DiscreteActionMasker(bp);

public void MultipleMaskEdit()
{
var bp = new BrainParameters();
bp.vectorActionSpaceType = SpaceType.Discrete;
bp.vectorActionSize = new[] {4, 5, 6};
bp.VectorActionSpaceType = SpaceType.Discrete;
bp.VectorActionSize = new[] {4, 5, 6};
var masker = new DiscreteActionMasker(bp);
masker.SetMask(0, new[] {0, 1});
masker.SetMask(0, new[] {3});

8
com.unity.ml-agents/Tests/Editor/EditModeTestInternalBrainTensorGenerator.cs


{
var goA = new GameObject("goA");
var bpA = goA.AddComponent<BehaviorParameters>();
bpA.brainParameters.vectorObservationSize = 3;
bpA.brainParameters.numStackedVectorObservations = 1;
bpA.BrainParameters.VectorObservationSize = 3;
bpA.BrainParameters.NumStackedVectorObservations = 1;
bpB.brainParameters.vectorObservationSize = 3;
bpB.brainParameters.numStackedVectorObservations = 1;
bpB.BrainParameters.VectorObservationSize = 3;
bpB.BrainParameters.NumStackedVectorObservations = 1;
var agentB = goB.AddComponent<TestAgent>();
var agents = new List<TestAgent> { agentA, agentB };

8
com.unity.ml-agents/Tests/Editor/MLAgentsEditModeTest.cs


var agentGo1 = new GameObject("TestAgent");
agentGo1.AddComponent<TestAgent>();
var behaviorParameters = agentGo1.GetComponent<BehaviorParameters>();
behaviorParameters.brainParameters.numStackedVectorObservations = 3;
behaviorParameters.BrainParameters.NumStackedVectorObservations = 3;
var agent1 = agentGo1.GetComponent<TestAgent>();
var aca = Academy.Instance;
agent1.LazyInitialize();

decisionRequester.Awake();
agent1.maxStep = 20;
agent1.MaxStep = 20;
agent2.LazyInitialize();
agent1.LazyInitialize();

for (var i = 0; i < 50; i++)
{
expectedAgent1ActionForEpisode += 1;
if (expectedAgent1ActionForEpisode == agent1.maxStep || i == 0)
if (expectedAgent1ActionForEpisode == agent1.MaxStep || i == 0)
{
expectedAgent1ActionForEpisode = 0;
}

decisionRequester.Awake();
const int maxStep = 6;
agent1.maxStep = maxStep;
agent1.MaxStep = maxStep;
agent1.LazyInitialize();
var expectedAgentStepCount = 0;

18
com.unity.ml-agents/Tests/Editor/ModelRunnerTest.cs


private BrainParameters GetContinuous2vis8vec2actionBrainParameters()
{
var validBrainParameters = new BrainParameters();
validBrainParameters.vectorObservationSize = 8;
validBrainParameters.vectorActionSize = new int[] { 2 };
validBrainParameters.numStackedVectorObservations = 1;
validBrainParameters.vectorActionSpaceType = SpaceType.Continuous;
validBrainParameters.VectorObservationSize = 8;
validBrainParameters.VectorActionSize = new int[] { 2 };
validBrainParameters.NumStackedVectorObservations = 1;
validBrainParameters.VectorActionSpaceType = SpaceType.Continuous;
return validBrainParameters;
}

validBrainParameters.vectorObservationSize = 0;
validBrainParameters.vectorActionSize = new int[] { 2, 3 };
validBrainParameters.numStackedVectorObservations = 1;
validBrainParameters.vectorActionSpaceType = SpaceType.Discrete;
validBrainParameters.VectorObservationSize = 0;
validBrainParameters.VectorActionSize = new int[] { 2, 3 };
validBrainParameters.NumStackedVectorObservations = 1;
validBrainParameters.VectorActionSpaceType = SpaceType.Discrete;
return validBrainParameters;
}

Assert.IsNotNull(modelRunner.GetAction(1));
Assert.IsNotNull(modelRunner.GetAction(2));
Assert.IsNull(modelRunner.GetAction(3));
Assert.AreEqual(brainParameters.vectorActionSize.Count(), modelRunner.GetAction(1).Count());
Assert.AreEqual(brainParameters.VectorActionSize.Count(), modelRunner.GetAction(1).Count());
modelRunner.Dispose();
}
}

30
com.unity.ml-agents/Tests/Editor/ParameterLoaderTest.cs


private BrainParameters GetContinuous2vis8vec2actionBrainParameters()
{
var validBrainParameters = new BrainParameters();
validBrainParameters.vectorObservationSize = 8;
validBrainParameters.vectorActionSize = new int[] { 2 };
validBrainParameters.numStackedVectorObservations = 1;
validBrainParameters.vectorActionSpaceType = SpaceType.Continuous;
validBrainParameters.VectorObservationSize = 8;
validBrainParameters.VectorActionSize = new int[] { 2 };
validBrainParameters.NumStackedVectorObservations = 1;
validBrainParameters.VectorActionSpaceType = SpaceType.Continuous;
return validBrainParameters;
}

validBrainParameters.vectorObservationSize = 0;
validBrainParameters.vectorActionSize = new int[] { 2, 3 };
validBrainParameters.numStackedVectorObservations = 1;
validBrainParameters.vectorActionSpaceType = SpaceType.Discrete;
validBrainParameters.VectorObservationSize = 0;
validBrainParameters.VectorActionSize = new int[] { 2, 3 };
validBrainParameters.NumStackedVectorObservations = 1;
validBrainParameters.VectorActionSpaceType = SpaceType.Discrete;
return validBrainParameters;
}

var model = ModelLoader.Load(continuous2vis8vec2actionModel);
var brainParameters = GetContinuous2vis8vec2actionBrainParameters();
brainParameters.vectorObservationSize = 9; // Invalid observation
brainParameters.VectorObservationSize = 9; // Invalid observation
brainParameters.numStackedVectorObservations = 2;// Invalid stacking
brainParameters.NumStackedVectorObservations = 2;// Invalid stacking
errors = BarracudaModelParamLoader.CheckModel(model, brainParameters, new SensorComponent[] { sensor_21_20_3, sensor_20_22_3 });
Assert.Greater(errors.Count(), 0);
}

var model = ModelLoader.Load(discrete1vis0vec_2_3action_recurrModel);
var brainParameters = GetDiscrete1vis0vec_2_3action_recurrModelBrainParameters();
brainParameters.vectorObservationSize = 1; // Invalid observation
brainParameters.VectorObservationSize = 1; // Invalid observation
var errors = BarracudaModelParamLoader.CheckModel(model, brainParameters, new SensorComponent[] { sensor_21_20_3 });
Assert.Greater(errors.Count(), 0);
}

var model = ModelLoader.Load(continuous2vis8vec2actionModel);
var brainParameters = GetContinuous2vis8vec2actionBrainParameters();
brainParameters.vectorActionSize = new int[] { 3 }; // Invalid action
brainParameters.VectorActionSize = new int[] { 3 }; // Invalid action
brainParameters.vectorActionSpaceType = SpaceType.Discrete;// Invalid SpaceType
brainParameters.VectorActionSpaceType = SpaceType.Discrete;// Invalid SpaceType
errors = BarracudaModelParamLoader.CheckModel(model, brainParameters, new SensorComponent[] { sensor_21_20_3, sensor_20_22_3 });
Assert.Greater(errors.Count(), 0);
}

var model = ModelLoader.Load(discrete1vis0vec_2_3action_recurrModel);
var brainParameters = GetDiscrete1vis0vec_2_3action_recurrModelBrainParameters();
brainParameters.vectorActionSize = new int[] { 3, 3 }; // Invalid action
brainParameters.VectorActionSize = new int[] { 3, 3 }; // Invalid action
brainParameters.vectorActionSpaceType = SpaceType.Continuous;// Invalid SpaceType
brainParameters.VectorActionSpaceType = SpaceType.Continuous;// Invalid SpaceType
errors = BarracudaModelParamLoader.CheckModel(model, brainParameters, new SensorComponent[] { sensor_21_20_3 });
Assert.Greater(errors.Count(), 0);
}

42
com.unity.ml-agents/Tests/Editor/PublicAPI/PublicApiValidation.cs


var height = 16;
var sensorComponent = gameObject.AddComponent<CameraSensorComponent>();
sensorComponent.camera = Camera.main;
sensorComponent.sensorName = "camera1";
sensorComponent.width = width;
sensorComponent.height = height;
sensorComponent.grayscale = true;
sensorComponent.Camera = Camera.main;
sensorComponent.SensorName = "camera1";
sensorComponent.Width = width;
sensorComponent.Height = height;
sensorComponent.Grayscale = true;
Assert.AreEqual("camera1", sensorComponent.sensorName);
Assert.AreEqual(width, sensorComponent.width);
Assert.AreEqual(height, sensorComponent.height);
Assert.IsTrue(sensorComponent.grayscale);
Assert.AreEqual("camera1", sensorComponent.SensorName);
Assert.AreEqual(width, sensorComponent.Width);
Assert.AreEqual(height, sensorComponent.Height);
Assert.IsTrue(sensorComponent.Grayscale);
}
[Test]

var width = 24;
var height = 16;
var texture = new RenderTexture(width, height, 0);
sensorComponent.renderTexture = texture;
sensorComponent.sensorName = "rtx1";
sensorComponent.grayscale = true;
sensorComponent.RenderTexture = texture;
sensorComponent.SensorName = "rtx1";
sensorComponent.Grayscale = true;
Assert.AreEqual("rtx1", sensorComponent.sensorName);
Assert.IsTrue(sensorComponent.grayscale);
Assert.AreEqual("rtx1", sensorComponent.SensorName);
Assert.IsTrue(sensorComponent.Grayscale);
}
[Test]

var sensorComponent = gameObject.AddComponent<RayPerceptionSensorComponent3D>();
sensorComponent.sensorName = "ray3d";
sensorComponent.detectableTags = new List<string> { "Player", "Respawn" };
sensorComponent.raysPerDirection = 3;
sensorComponent.maxRayDegrees = 30;
sensorComponent.sphereCastRadius = .1f;
sensorComponent.rayLayerMask = 0;
sensorComponent.observationStacks = 2;
sensorComponent.SensorName = "ray3d";
sensorComponent.DetectableTags = new List<string> { "Player", "Respawn" };
sensorComponent.RaysPerDirection = 3;
sensorComponent.MaxRayDegrees = 30;
sensorComponent.SphereCastRadius = .1f;
sensorComponent.RayLayerMask = 0;
sensorComponent.ObservationStacks = 2;
sensorComponent.CreateSensor();
}

10
com.unity.ml-agents/Tests/Editor/Sensor/CameraSensorComponentTest.cs


var agentGameObj = new GameObject("agent");
var cameraComponent = agentGameObj.AddComponent<CameraSensorComponent>();
cameraComponent.camera = camera;
cameraComponent.height = height;
cameraComponent.width = width;
cameraComponent.grayscale = grayscale;
cameraComponent.compression = compression;
cameraComponent.Camera = camera;
cameraComponent.Height = height;
cameraComponent.Width = width;
cameraComponent.Grayscale = grayscale;
cameraComponent.CompressionType = compression;
var expectedShape = new[] { height, width, grayscale ? 1 : 3 };
Assert.AreEqual(expectedShape, cameraComponent.GetObservationShape());

78
com.unity.ml-agents/Tests/Editor/Sensor/RayPerceptionSensorTests.cs


var obj = new GameObject("agent");
var perception = obj.AddComponent<RayPerceptionSensorComponent3D>();
perception.raysPerDirection = 1;
perception.maxRayDegrees = 45;
perception.rayLength = 20;
perception.detectableTags = new List<string>();
perception.detectableTags.Add(k_CubeTag);
perception.detectableTags.Add(k_SphereTag);
perception.RaysPerDirection = 1;
perception.MaxRayDegrees = 45;
perception.RayLength = 20;
perception.DetectableTags = new List<string>();
perception.DetectableTags.Add(k_CubeTag);
perception.DetectableTags.Add(k_SphereTag);
perception.sphereCastRadius = castRadius;
perception.SphereCastRadius = castRadius;
var expectedObs = (2 * perception.raysPerDirection + 1) * (perception.detectableTags.Count + 2);
var expectedObs = (2 * perception.RaysPerDirection + 1) * (perception.DetectableTags.Count + 2);
Assert.AreEqual(sensor.GetObservationShape()[0], expectedObs);
var outputBuffer = new float[expectedObs];

// Hit is at z=9.0 in world space, ray length is 20
Assert.That(
outputBuffer[3], Is.EqualTo((9.5f - castRadius) / perception.rayLength).Within(.0005f)
outputBuffer[3], Is.EqualTo((9.5f - castRadius) / perception.RayLength).Within(.0005f)
);
// Spheres are at 5,0,5 and 5,0,-5, so 5*sqrt(2) units from origin

Assert.AreEqual(0.0f, outputBuffer[5]); // missed sphere
Assert.AreEqual(0.0f, outputBuffer[6]); // hit unknown tag -> all 0
Assert.That(
outputBuffer[7], Is.EqualTo(expectedHitLengthWorldSpace / perception.rayLength).Within(.0005f)
outputBuffer[7], Is.EqualTo(expectedHitLengthWorldSpace / perception.RayLength).Within(.0005f)
);
Assert.AreEqual(0.0f, outputBuffer[8]); // missed cube

outputBuffer[11], Is.EqualTo(expectedHitLengthWorldSpace / perception.rayLength).Within(.0005f)
outputBuffer[11], Is.EqualTo(expectedHitLengthWorldSpace / perception.RayLength).Within(.0005f)
);
}
}

var obj = new GameObject("agent");
var perception = obj.AddComponent<RayPerceptionSensorComponent3D>();
perception.raysPerDirection = 0;
perception.maxRayDegrees = 45;
perception.rayLength = 20;
perception.detectableTags = new List<string>();
perception.detectableTags.Add(k_CubeTag);
perception.detectableTags.Add(k_SphereTag);
perception.RaysPerDirection = 0;
perception.MaxRayDegrees = 45;
perception.RayLength = 20;
perception.DetectableTags = new List<string>();
perception.DetectableTags.Add(k_CubeTag);
perception.DetectableTags.Add(k_SphereTag);
var expectedObs = (2 * perception.raysPerDirection + 1) * (perception.detectableTags.Count + 2);
var expectedObs = (2 * perception.RaysPerDirection + 1) * (perception.DetectableTags.Count + 2);
Assert.AreEqual(sensor.GetObservationShape()[0], expectedObs);
var outputBuffer = new float[expectedObs];

var obj = new GameObject("agent");
var perception = obj.AddComponent<RayPerceptionSensorComponent3D>();
perception.raysPerDirection = 0;
perception.rayLength = 20;
perception.detectableTags = new List<string>();
perception.RaysPerDirection = 0;
perception.RayLength = 20;
perception.DetectableTags = new List<string>();
var filterCubeLayers = new[] { false, true };
foreach (var filterCubeLayer in filterCubeLayers)

{
layerMask &= ~(1 << cubeFiltered.layer);
}
perception.rayLayerMask = layerMask;
perception.RayLayerMask = layerMask;
var expectedObs = (2 * perception.raysPerDirection + 1) * (perception.detectableTags.Count + 2);
var expectedObs = (2 * perception.RaysPerDirection + 1) * (perception.DetectableTags.Count + 2);
Assert.AreEqual(sensor.GetObservationShape()[0], expectedObs);
var outputBuffer = new float[expectedObs];

{
// Hit the far cube because close was filtered.
Assert.That(outputBuffer[outputBuffer.Length - 1],
Is.EqualTo((9.5f - perception.sphereCastRadius) / perception.rayLength).Within(.0005f)
Is.EqualTo((9.5f - perception.SphereCastRadius) / perception.RayLength).Within(.0005f)
);
}
else

Is.EqualTo((4.5f - perception.sphereCastRadius) / perception.rayLength).Within(.0005f)
Is.EqualTo((4.5f - perception.SphereCastRadius) / perception.RayLength).Within(.0005f)
);
}
}

var perception = obj.AddComponent<RayPerceptionSensorComponent3D>();
obj.transform.localScale = new Vector3(2, 2, 2);
perception.raysPerDirection = 0;
perception.maxRayDegrees = 45;
perception.rayLength = 20;
perception.detectableTags = new List<string>();
perception.detectableTags.Add(k_CubeTag);
perception.RaysPerDirection = 0;
perception.MaxRayDegrees = 45;
perception.RayLength = 20;
perception.DetectableTags = new List<string>();
perception.DetectableTags.Add(k_CubeTag);
perception.sphereCastRadius = castRadius;
perception.SphereCastRadius = castRadius;
var expectedObs = (2 * perception.raysPerDirection + 1) * (perception.detectableTags.Count + 2);
var expectedObs = (2 * perception.RaysPerDirection + 1) * (perception.DetectableTags.Count + 2);
Assert.AreEqual(sensor.GetObservationShape()[0], expectedObs);
var outputBuffer = new float[expectedObs];

// Hit is at z=9.0 in world space, ray length was 20
// But scale increases the cast size and the ray length
var scaledRayLength = 2 * perception.rayLength;
var scaledRayLength = 2 * perception.RayLength;
var scaledCastRadius = 2 * castRadius;
Assert.That(
outputBuffer[2], Is.EqualTo((9.5f - scaledCastRadius) / scaledRayLength).Within(.0005f)

var obj = new GameObject("agent");
var perception = obj.AddComponent<RayPerceptionSensorComponent3D>();
perception.raysPerDirection = 0;
perception.rayLength = 0.0f;
perception.sphereCastRadius = .5f;
perception.detectableTags = new List<string>();
perception.detectableTags.Add(k_CubeTag);
perception.RaysPerDirection = 0;
perception.RayLength = 0.0f;
perception.SphereCastRadius = .5f;
perception.DetectableTags = new List<string>();
perception.DetectableTags.Add(k_CubeTag);
var expectedObs = (2 * perception.raysPerDirection + 1) * (perception.detectableTags.Count + 2);
var expectedObs = (2 * perception.RaysPerDirection + 1) * (perception.DetectableTags.Count + 2);
Assert.AreEqual(sensor.GetObservationShape()[0], expectedObs);
var outputBuffer = new float[expectedObs];

6
com.unity.ml-agents/Tests/Editor/Sensor/RenderTextureSensorComponentTests.cs


var agentGameObj = new GameObject("agent");
var renderTexComponent = agentGameObj.AddComponent<RenderTextureSensorComponent>();
renderTexComponent.renderTexture = texture;
renderTexComponent.grayscale = grayscale;
renderTexComponent.compression = compression;
renderTexComponent.RenderTexture = texture;
renderTexComponent.Grayscale = grayscale;
renderTexComponent.CompressionType = compression;
var expectedShape = new[] { height, width, grayscale ? 1 : 3 };
Assert.AreEqual(expectedShape, renderTexComponent.GetObservationShape());

32
com.unity.ml-agents/Tests/Runtime/RuntimeAPITest.cs


var gameObject = new GameObject();
var behaviorParams = gameObject.AddComponent<BehaviorParameters>();
behaviorParams.brainParameters.vectorObservationSize = 3;
behaviorParams.brainParameters.numStackedVectorObservations = 2;
behaviorParams.brainParameters.vectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
behaviorParams.brainParameters.vectorActionSize = new[] { 2, 2 };
behaviorParams.brainParameters.vectorActionSpaceType = SpaceType.Discrete;
behaviorParams.behaviorName = "TestBehavior";
behaviorParams.BrainParameters.VectorObservationSize = 3;
behaviorParams.BrainParameters.NumStackedVectorObservations = 2;
behaviorParams.BrainParameters.VectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
behaviorParams.BrainParameters.VectorActionSize = new[] { 2, 2 };
behaviorParams.BrainParameters.VectorActionSpaceType = SpaceType.Discrete;
behaviorParams.BehaviorName = "TestBehavior";
behaviorParams.useChildSensors = true;
behaviorParams.UseChildSensors = true;
behaviorParams.behaviorType = BehaviorType.Default;
behaviorParams.BehaviorType = BehaviorType.Default;
sensorComponent.sensorName = "ray3d";
sensorComponent.detectableTags = new List<string> { "Player", "Respawn" };
sensorComponent.raysPerDirection = 3;
sensorComponent.SensorName = "ray3d";
sensorComponent.DetectableTags = new List<string> { "Player", "Respawn" };
sensorComponent.RaysPerDirection = 3;
// Make a StackingSensor that wraps the RayPerceptionSensorComponent3D
// This isn't necessarily practical, just to ensure that it can be done

// ISensor isn't set up yet.
Assert.IsNull(sensorComponent.raySensor);
Assert.IsNull(sensorComponent.RaySensor);
behaviorParams.behaviorType = BehaviorType.HeuristicOnly;
behaviorParams.BehaviorType = BehaviorType.HeuristicOnly;
// Agent needs to be added after everything else is setup.
var agent = gameObject.AddComponent<PublicApiAgent>();

// Initialization should set up the sensors
Assert.IsNotNull(sensorComponent.raySensor);
Assert.IsNotNull(sensorComponent.RaySensor);
var otherDevice = behaviorParams.inferenceDevice == InferenceDevice.CPU ? InferenceDevice.GPU : InferenceDevice.CPU;
agent.SetModel(behaviorParams.behaviorName, behaviorParams.model, otherDevice);
var otherDevice = behaviorParams.InferenceDevice == InferenceDevice.CPU ? InferenceDevice.GPU : InferenceDevice.CPU;
agent.SetModel(behaviorParams.BehaviorName, behaviorParams.Model, otherDevice);
agent.AddReward(1.0f);

2
docs/Learning-Environment-Examples.md


Behavior Parameters : SoccerTwos.
- Agent Reward Function (dependent):
- (1 - `accumulated time penalty`) When ball enters opponent's goal `accumulated time penalty` is incremented by
(1 / `maxStep`) every fixed update and is reset to 0 at the beginning of an episode.
(1 / `MaxStep`) every fixed update and is reset to 0 at the beginning of an episode.
- -1 When ball enters team's goal.
- Behavior Parameters:
- Vector Observation space: 336 corresponding to 11 ray-casts forward distributed over 120 degrees

5
docs/Migrating.md


`UnityToGymWrapper` and no longer creates the `UnityEnvironment`. Instead,
the `UnityEnvironment` must be passed as input to the
constructor of `UnityToGymWrapper`
- Public fields and properties on several classes were renamed to follow Unity's
C# style conventions. All public fields and properties now use "PascalCase"
instead of "camelCase"; for example, `Agent.maxStep` was renamed to
`Agent.MaxStep`. For a full list of changes, see the pull request. (#3828)
### Steps to Migrate

- Replace `UnityEnv` with `UnityToGymWrapper` in your code. The constructor
no longer takes a file name as input but a fully constructed
`UnityEnvironment` instead.
- Update uses of "camelCase" fields and properties to "PascalCase".
## Migrating from 0.14 to 0.15

正在加载...
取消
保存