浏览代码

Merge branch 'master' into soccer-fives

/soccer-fives
Andrew Cohen 4 年前
当前提交
de73baa9
共有 74 个文件被更改,包括 1404 次插入374 次删除
  1. 50
      .circleci/config.yml
  2. 8
      .github/PULL_REQUEST_TEMPLATE.md
  3. 4
      .pre-commit-config.yaml
  4. 1
      .yamato/com.unity.ml-agents-test.yml
  5. 9
      Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs
  6. 3
      com.unity.ml-agents/CHANGELOG.md
  7. 4
      com.unity.ml-agents/Editor/BrainParametersDrawer.cs
  8. 10
      com.unity.ml-agents/Editor/Unity.ML-Agents.Editor.asmdef
  9. 12
      com.unity.ml-agents/Runtime/Academy.cs
  10. 13
      com.unity.ml-agents/Runtime/ActionMasker.cs
  11. 29
      com.unity.ml-agents/Runtime/DecisionRequester.cs
  12. 20
      com.unity.ml-agents/Runtime/Demonstrations/DemonstrationRecorder.cs
  13. 16
      com.unity.ml-agents/Runtime/Demonstrations/DemonstrationWriter.cs
  14. 4
      com.unity.ml-agents/Runtime/InferenceBrain/BarracudaModelParamLoader.cs
  15. 12
      com.unity.ml-agents/Runtime/InferenceBrain/TensorGenerator.cs
  16. 4
      com.unity.ml-agents/Runtime/InferenceBrain/Utils/RandomNormal.cs
  17. 12
      com.unity.ml-agents/Runtime/Policy/BarracudaPolicy.cs
  18. 21
      com.unity.ml-agents/Runtime/Policy/BehaviorParameters.cs
  19. 34
      com.unity.ml-agents/Runtime/Policy/BrainParameters.cs
  20. 54
      com.unity.ml-agents/Runtime/Sensor/CameraSensor.cs
  21. 37
      com.unity.ml-agents/Runtime/Sensor/CameraSensorComponent.cs
  22. 63
      com.unity.ml-agents/Runtime/Sensor/ISensor.cs
  23. 2
      com.unity.ml-agents/Runtime/Sensor/Observation.cs
  24. 44
      com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensor.cs
  25. 7
      com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensorComponent2D.cs
  26. 37
      com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensorComponent3D.cs
  27. 279
      com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensorComponentBase.cs
  28. 21
      com.unity.ml-agents/Runtime/Sensor/RenderTextureSensor.cs
  29. 22
      com.unity.ml-agents/Runtime/Sensor/RenderTextureSensorComponent.cs
  30. 19
      com.unity.ml-agents/Runtime/Sensor/SensorBase.cs
  31. 17
      com.unity.ml-agents/Runtime/Sensor/SensorComponent.cs
  32. 4
      com.unity.ml-agents/Runtime/Sensor/StackingSensor.cs
  33. 23
      com.unity.ml-agents/Runtime/Sensor/VectorSensor.cs
  34. 8
      com.unity.ml-agents/Runtime/Sensor/WriteAdapter.cs
  35. 8
      com.unity.ml-agents/Runtime/SideChannel/EngineConfigurationChannel.cs
  36. 16
      com.unity.ml-agents/Runtime/SideChannel/FloatPropertiesChannel.cs
  37. 5
      com.unity.ml-agents/Runtime/SideChannel/RawBytesChannel.cs
  38. 7
      com.unity.ml-agents/Runtime/SideChannel/SideChannel.cs
  39. 18
      com.unity.ml-agents/Runtime/Timer.cs
  40. 5
      com.unity.ml-agents/Runtime/Unity.ML-Agents.asmdef
  41. 9
      com.unity.ml-agents/Runtime/UnityAgentsException.cs
  42. 82
      com.unity.ml-agents/Runtime/Utilities.cs
  43. 4
      com.unity.ml-agents/Tests/Editor/DemonstrationTests.cs
  44. 5
      com.unity.ml-agents/Tests/Editor/Unity.ML-Agents.Editor.Tests.asmdef
  45. 15
      gym-unity/gym_unity/envs/__init__.py
  46. 9
      ml-agents/mlagents/trainers/common/nn_policy.py
  47. 4
      ml-agents/mlagents/trainers/components/reward_signals/curiosity/signal.py
  48. 4
      ml-agents/mlagents/trainers/components/reward_signals/gail/signal.py
  49. 6
      ml-agents/mlagents/trainers/ppo/optimizer.py
  50. 8
      ml-agents/mlagents/trainers/sac/network.py
  51. 7
      ml-agents/mlagents/trainers/sac/optimizer.py
  52. 4
      ml-agents/mlagents/trainers/tests/test_meta_curriculum.py
  53. 9
      ml-agents/mlagents/trainers/tests/test_simple_rl.py
  54. 1
      ml-agents/mlagents/trainers/tf_policy.py
  55. 34
      notebooks/getting-started-gym.ipynb
  56. 27
      notebooks/getting-started.ipynb
  57. 8
      com.unity.ml-agents/Runtime/Communicator/ICommunicator.cs
  58. 40
      .yamato/protobuf-generation-test.yml
  59. 94
      com.unity.ml-agents/Editor/RayPerceptionSensorComponentBaseEditor.cs
  60. 11
      com.unity.ml-agents/Editor/RayPerceptionSensorComponentBaseEditor.cs.meta
  61. 8
      com.unity.ml-agents/Runtime/Communicator.meta
  62. 5
      com.unity.ml-agents/Runtime/Grpc/AssemblyInfo.cs
  63. 11
      com.unity.ml-agents/Runtime/Grpc/AssemblyInfo.cs.meta
  64. 16
      com.unity.ml-agents/Runtime/Grpc/Unity.ML-Agents.CommunicatorObjects.asmdef
  65. 7
      com.unity.ml-agents/Runtime/Grpc/Unity.ML-Agents.CommunicatorObjects.asmdef.meta
  66. 381
      com.unity.ml-agents/Third Party Notices.md
  67. 7
      com.unity.ml-agents/Third Party Notices.md.meta
  68. 0
      /com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs.meta
  69. 0
      /com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs.meta
  70. 0
      /com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs
  71. 0
      /com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
  72. 0
      /com.unity.ml-agents/Runtime/Communicator/ICommunicator.cs.meta
  73. 0
      /com.unity.ml-agents/Runtime/Communicator/ICommunicator.cs

50
.circleci/config.yml


. venv/bin/activate
pre-commit run --hook-stage manual << parameters.precommit_command >> --all-files
protobuf_generation_check:
docker:
- image: circleci/python:3.7.3
working_directory: ~/repo/
steps:
- checkout
- run:
name: Combine proto files for caching
command: cat protobuf-definitions/proto/mlagents_envs/communicator_objects/*.proto > /tmp/proto_deps.txt
- restore_cache:
keys:
- v1-protobuf-gen-dependencies-{{ checksum "/tmp/proto_deps.txt" }}
- v1-protobuf-gen-dependencies-
- run:
name: Install Dependencies
command: |
sudo apt-get install nuget
nuget install Grpc.Tools -Version 1.14.1 -OutputDirectory protobuf-definitions/
python3 -m venv venv
. venv/bin/activate
pip install --upgrade pip
pip install grpcio-tools==1.13.0 --progress-bar=off
pip install mypy-protobuf==1.16.0 --progress-bar=off
- save_cache:
paths:
- ./venv
key: v1-protobuf-gen-dependencies-{{ checksum "/tmp/proto_deps.txt" }}
- run:
name: Generate protobufs
command: |
. venv/bin/activate
cd protobuf-definitions
chmod +x Grpc.Tools.1.14.1/tools/linux_x64/protoc
chmod +x Grpc.Tools.1.14.1/tools/linux_x64/grpc_csharp_plugin
COMPILER=Grpc.Tools.1.14.1/tools/linux_x64 ./make.sh
CS_PROTO_PATH=com.unity.ml-agents/Runtime/Grpc/CommunicatorObjects
git diff --exit-code --quiet -- :/ ":(exclude,top)$CS_PROTO_PATH/*.meta" \
|| { GIT_ERR=$?; echo "protobufs need to be regenerated, apply the patch uploaded to artifacts."; \
echo "Apply the patch with the command: git apply proto.patch"; \
git diff -- :/ ":(exclude,top)$CS_PROTO_PATH/*.meta" > /tmp/proto.patch; \
exit $GIT_ERR; }
- store_artifacts:
path: /tmp/proto.patch
destination: proto.patch
deploy:
parameters:
directory:

# Test python 3.7 with the newest supported versions
pip_constraints: test_constraints_max_tf2_version.txt
- markdown_link_check
- protobuf_generation_check
- pre-commit
- deploy:
name: deploy ml-agents-envs

8
.github/PULL_REQUEST_TEMPLATE.md


- [ ] Other (please describe)
### Checklist
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] I have added updated the changelog (if applicable)
- [ ] I have added necessary documentation (if applicable)
- [ ] I have updated the migration guide (if applicable)
- [ ] Added tests that prove my fix is effective or that my feature works
- [ ] Updated the [changelog](https://github.com/Unity-Technologies/ml-agents/blob/master/com.unity.ml-agents/CHANGELOG.md) (if applicable)
- [ ] Updated the [documentation](https://github.com/Unity-Technologies/ml-agents/tree/master/docs) (if applicable)
- [ ] Updated the [migration guide](https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Migrating.md) (if applicable)
### Other comments

4
.pre-commit-config.yaml


# markdown-link-check doesn't support multiple files on the commandline, so this hacks around that.
# Note that you must install the package separately via npm. For example:
# brew install npm; npm install -g markdown-link-check
entry: bash -xc 'echo "$@" | xargs -n1 -t markdown-link-check -c markdown-link-check.fast.json' --
entry: bash -c 'for i in "$@"; do markdown-link-check -c markdown-link-check.fast.json "$i"; done' --
language: system
types: [markdown]
# Don't check localized files since their target might not be localized.

- id: markdown-link-check-full
name: markdown-link-check-full
entry: bash -xc 'echo "$@" | xargs -n1 -t markdown-link-check -c markdown-link-check.full.json' --
entry: bash -c 'for i in "$@"; do markdown-link-check -c markdown-link-check.full.json "$i"; done' --
language: system
types: [markdown]
exclude: ".*localized.*"

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


test_editors:
- version: 2018.4
- version: 2019.3
- version: 2020.1
test_platforms:
- name: win
type: Unity::VM

9
Project/Assets/ML-Agents/Examples/WallJump/Scripts/WallJumpAgent.cs


}
/// <summary>
/// Chenges the color of the ground for a moment
/// Changes the color of the ground for a moment.
/// <returns>The Enumerator to be used in a Coroutine</returns>
/// <param name="mat">The material to be swaped.</param>
/// <returns>The Enumerator to be used in a Coroutine.</returns>
/// <param name="mat">The material to be swapped.</param>
/// <param name="time">The time the material will remain.</param>
IEnumerator GoalScoredSwapGroundMaterial(Material mat, float time)
{

/// <param name="config">Config.
/// If 0 : No wall and noWallBrain.
/// If 1: Small wall and smallWallBrain.
/// Other : Tall wall and BigWallBrain. </param>
/// Other : Tall wall and BigWallBrain.
/// </param>
void ConfigureAgent(int config)
{
var localScale = wall.transform.localScale;

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


- `DemonstrationRecorder` now has an optional path for the demonstrations. This will default to `Application.dataPath` if not set.
- `DemonstrationStore` was changed to accept a `Stream` for its constructor, and was renamed to `DemonstrationWriter`
- The method `GetStepCount()` on the Agent class has been replaced with the property getter `StepCount`
- `RayPerceptionSensorComponent` and related classes now display the debug gizmos whenever the Agent is selected (not just Play mode).
- Most fields on `RayPerceptionSensorComponent` can now be changed while the editor is in Play mode. The exceptions to this are fields that affect the number of observations.
- Unused static methods from the `Utilities` class (ShiftLeft, ReplaceRange, AddRangeNoAlloc, and GetSensorFloatObservationSize) were removed.
### Bugfixes
- Fixed an issue which caused self-play training sessions to consume a lot of memory. (#3451)

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


}
/// <summary>
/// The Height required to draw the Vector Action parameters
/// The Height required to draw the Vector Action parameters.
/// <returns>The height of the drawer of the Vector Action </returns>
/// <returns>The height of the drawer of the Vector Action.</returns>
static float GetHeightDrawVectorAction(SerializedProperty property)
{
var actionSize = 2 + property.FindPropertyRelative(k_ActionSizePropName).arraySize;

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


"name": "Unity.ML-Agents.Editor",
"references": [
"Unity.ML-Agents",
"Barracuda"
"Barracuda",
"Unity.ML-Agents.CommunicatorObjects"
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],

"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
"defineConstraints": []
}

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


/// Creates or retrieves an existing ModelRunner that uses the same
/// 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="inferenceDevice"> The inference device (CPU or GPU)
/// the ModelRunner will use </param>
/// <returns> The ModelRunner compatible with the input settings</returns>
/// <param name="model">The NNModel the ModelRunner must use.</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>
/// <returns> The ModelRunner compatible with the input settings.</returns>
internal ModelRunner GetOrCreateModelRunner(
NNModel model, BrainParameters brainParameters, InferenceDevice inferenceDevice)
{

13
com.unity.ml-agents/Runtime/ActionMasker.cs


namespace MLAgents
{
/// <summary>
/// Agents that take discrete actions can explicitly indicate that specific actions
/// are not allowed at a point in time. This enables the agent to indicate that some actions
/// may be illegal (e.g. the King in Chess taking a move to the left if it is already in the
/// left side of the board). This class represents the set of masked actions and provides
/// the utilities for setting and retrieving them.
/// </summary>
public class ActionMasker
{
/// When using discrete control, is the starting indices of the actions

/// The actionIndices correspond to the actions the agent will be unable to perform
/// on the branch 0.
/// </summary>
/// <param name="actionIndices">The indices of the masked actions on branch 0</param>
/// <param name="actionIndices">The indices of the masked actions on branch 0.</param>
public void SetActionMask(IEnumerable<int> actionIndices)
{
SetActionMask(0, actionIndices);

/// action branch. The actionIndex correspond to the action the agent will be unable
/// to perform.
/// </summary>
/// <param name="branch">The branch for which the actions will be masked</param>
/// <param name="actionIndex">The index of the masked action</param>
/// <param name="branch">The branch for which the actions will be masked.</param>
/// <param name="actionIndex">The index of the masked action.</param>
public void SetActionMask(int branch, int actionIndex)
{
SetActionMask(branch, new[] { actionIndex });

29
com.unity.ml-agents/Runtime/DecisionRequester.cs


using System;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace MLAgents

[AddComponentMenu("ML Agents/Decision Requester", (int)MenuGroup.Default)]
public class DecisionRequester : MonoBehaviour
{
/// <summary>
/// The frequency with which the agent requests a decision. A DecisionPeriod of 5 means
/// that the Agent will request a decision every 5 Academy steps.
/// </summary>
[Tooltip("The agent will automatically request a decision every X Academy steps.")]
[Tooltip("The frequency with which the agent requests a decision. A DecisionPeriod " +
"of 5 means that the Agent will request a decision every 5 Academy steps.")]
[Tooltip("Whether or not AgentAction will be called on Academy steps that decisions aren't requested. Has no effect if DecisionPeriod is 1.")]
/// <summary>
/// Indicates whether or not the agent will take an action during the Academy steps where
/// it does not request a decision. Has no effect when DecisionPeriod is set to 1.
/// </summary>
[Tooltip("Indicates whether or not the agent will take an action during the Academy " +
"steps where it does not request a decision. Has no effect when DecisionPeriod " +
"is set to 1.")]
[Tooltip("Whether or not Agent decisions should start at a random offset.")]
/// <summary>
/// Whether or not the Agent decisions should start at an offset (different for each agent).
/// This does not affect <see cref="DecisionPeriod"/>. Turning this on will distribute
/// the decision-making computations for all the agents across multiple Academy steps.
/// This can be valuable in scenarios where you have many agents in the scene, particularly
/// during the inference phase.
/// </summary>
[Tooltip("Whether or not Agent decisions should start at an offset.")]
public void Awake()
internal void Awake()
{
m_Offset = offsetStep ? gameObject.GetInstanceID() : 0;
m_Agent = gameObject.GetComponent<Agent>();

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


[AddComponentMenu("ML Agents/Demonstration Recorder", (int)MenuGroup.Default)]
public class DemonstrationRecorder : MonoBehaviour
{
/// <summary>
/// Whether or not to record demonstrations.
/// </summary>
[Tooltip("Base demonstration file name. Will have numbers appended to make unique.")]
/// <summary>
/// Base demonstration file name. If multiple files are saved, the additional filenames
/// will have a sequence of unique numbers appended.
/// </summary>
[Tooltip("Base demonstration file name. If multiple files are saved, the additional " +
"filenames will have a unique number appended.")]
[Tooltip("Base directory to write the demo files. If null, will use {Application.dataPath}/Demonstrations.")]
/// <summary>
/// Directory to save the demo files. Will default to a "Demonstrations/" folder in the
/// Application data path if not specified.
/// </summary>
[Tooltip("Directory to save the demo files. Will default to " +
"{Application.dataPath}/Demonstrations if not specified.")]
public string demonstrationDirectory;
DemonstrationWriter m_DemoWriter;

const string k_DefaultDirectoryName = "Demonstrations";
IFileSystem m_FileSystem;
Agent m_Agent;

}
if (string.IsNullOrEmpty(demonstrationDirectory))
{
demonstrationDirectory = Path.Combine(Application.dataPath, "Demonstrations");
demonstrationDirectory = Path.Combine(Application.dataPath, k_DefaultDirectoryName);
}
demonstrationName = SanitizeName(demonstrationName, MaxNameLength);

16
com.unity.ml-agents/Runtime/Demonstrations/DemonstrationWriter.cs


namespace MLAgents
{
/// <summary>
/// Responsible for writing demonstration data to stream (usually a file stream).
/// Responsible for writing demonstration data to stream (typically a file stream).
public const int MetaDataBytes = 32; // Number of bytes allocated to metadata in demo file.
/// <summary>
/// Number of bytes reserved for the Demonstration metadata at the start of the demo file.
/// </summary>
internal const int MetaDataBytes = 32;
DemonstrationMetaData m_MetaData;
Stream m_Writer;

/// <summary>
/// Writes the initial data to the stream.
/// </summary>
/// <param name="demonstrationName">Base name of the demonstration file(s).</param>
/// <param name="brainName">The name of the Brain the agent is attached to.</param>
/// <param name="brainParameters">The parameters of the Brain the agent is attached to.</param>
public void Initialize(
string demonstrationName, BrainParameters brainParameters, string brainName)
{

/// <summary>
/// Writes brain parameters to file.
/// </summary>
/// <param name="brainName">The name of the Brain the agent is attached to.</param>
/// <param name="brainParameters">The parameters of the Brain the agent is attached to.</param>
void WriteBrainParameters(string brainName, BrainParameters brainParameters)
{
if (m_Writer == null)

/// <summary>
/// Write AgentInfo experience to file.
/// </summary>
/// <param name="info"> <see cref="AgentInfo"/> for the agent being recorded.</param>
/// <param name="sensors">List of sensors to record for the agent.</param>
internal void Record(AgentInfo info, List<ISensor> sensors)
{
if (m_Writer == null)

/// <summary>
/// Performs all clean-up necessary
/// Performs all clean-up necessary.
/// </summary>
public void Close()
{

4
com.unity.ml-agents/Runtime/InferenceBrain/BarracudaModelParamLoader.cs


/// Generates the Tensor inputs that are expected to be present in the Model.
/// </summary>
/// <param name="model">
/// The Barracuda engine model for loading static parameters
/// The Barracuda engine model for loading static parameters.
/// <returns>TensorProxy IEnumerable with the expected Tensor inputs</returns>
/// <returns>TensorProxy IEnumerable with the expected Tensor inputs.</returns>
public static IReadOnlyList<TensorProxy> GetInputTensors(Model model)
{
var tensors = new List<TensorProxy>();

12
com.unity.ml-agents/Runtime/InferenceBrain/TensorGenerator.cs


/// Modifies the data inside a Tensor according to the information contained in the
/// AgentInfos contained in the current batch.
/// </summary>
/// <param name="tensorProxy"> The tensor the data and shape will be modified</param>
/// <param name="batchSize"> The number of agents present in the current batch</param>
/// <param name="infos"> List of AgentInfos containing the
/// information that will be used to populate the tensor's data</param>
/// <param name="tensorProxy"> The tensor the data and shape will be modified.</param>
/// <param name="batchSize"> The number of agents present in the current batch.</param>
/// <param name="infos">
/// List of AgentInfos containing the information that will be used to populate
/// the tensor's data.
/// </param>
void Generate(
TensorProxy tensorProxy, int batchSize, IEnumerable<AgentInfoSensorsPair> infos);
}

/// Returns a new TensorGenerators object.
/// </summary>
/// <param name="seed"> The seed the Generators will be initialized with.</param>
/// <param name="allocator"> Tensor allocator</param>
/// <param name="allocator"> Tensor allocator.</param>
/// <param name="memories">Dictionary of AgentInfo.id to memory for use in the inference model.</param>
/// <param name="barracudaModel"></param>
public TensorGenerator(

4
com.unity.ml-agents/Runtime/InferenceBrain/Utils/RandomNormal.cs


double m_SpareUnscaled;
/// <summary>
/// Return the next random double number
/// Return the next random double number.
/// <returns>Next random double number</returns>
/// <returns>Next random double number.</returns>
public double NextDouble()
{
if (m_HasSpare)

12
com.unity.ml-agents/Runtime/Policy/BarracudaPolicy.cs


namespace MLAgents
{
/// <summary>
/// Where to perform inference.
/// </summary>
/// <summary>
/// CPU inference
/// </summary>
/// <summary>
/// GPU inference
/// </summary>
/// every step. It uses a ModelRunner that is shared accross all
/// every step. It uses a ModelRunner that is shared across all
/// Barracuda Policies that use the same model and inference devices.
/// </summary>
internal class BarracudaPolicy : IPolicy

21
com.unity.ml-agents/Runtime/Policy/BehaviorParameters.cs


/// <summary>
/// The Factory to generate policies.
/// </summary>
///
[AddComponentMenu("ML Agents/Behavior Parameters", (int)MenuGroup.Default)]
public class BehaviorParameters : MonoBehaviour
{

[HideInInspector]
[SerializeField]
string m_BehaviorName = "My Behavior";
/// <summary>
/// The team ID for this behavior.
/// </summary>
[HideInInspector]
[SerializeField]
public int m_TeamID;

[Tooltip("Use all Sensor components attached to child GameObjects of this Agent.")]
bool m_UseChildSensors = true;
/// <summary>
/// The associated <see cref="BrainParameters"/> for this behavior.
/// </summary>
/// <summary>
/// Whether or not to use all the sensor components attached to child GameObjects of the agent.
/// </summary>
/// <summary>
/// The name of this behavior, which is used as a base name. See
/// <see cref="fullyQualifiedBehaviorName"/> for the full name.
/// </summary>
public string behaviorName
{
get { return m_BehaviorName; }

}
}
/// <summary>
/// Updates the model and related details for this behavior.
/// </summary>
/// <param name="newBehaviorName">New name for the behavior.</param>
/// <param name="model">New neural network model for this behavior.</param>
/// <param name="inferenceDevice">New inference device for this behavior.</param>
public void GiveModel(
string newBehaviorName,
NNModel model,

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


namespace MLAgents
{
/// <summary>
/// Whether the action space is discrete or continuous.
/// </summary>
/// <summary>
/// Discrete action space: a fixed number of options are available.
/// </summary>
/// <summary>
/// Continuous action space: each action can take on a float value.
/// </summary>
Continuous
}

public class BrainParameters
{
/// <summary>
/// If continuous : The length of the float vector that represents
/// the state
/// If discrete : The number of possible values the state can take
/// If continuous : The length of the float vector that represents the state.
/// If discrete : The number of possible values the state can take.
/// <summary>
/// Stacking refers to concatenating the observations across multiple frames. This field
/// indicates the number of frames to concatenate across.
/// </summary>
/// If continuous : The length of the float vector that represents
/// the action
/// If discrete : The number of possible values the action can take*/
/// If continuous : The length of the float vector that represents the action.
/// If discrete : The number of possible values the action can take.
/// <summary></summary>The list of strings describing what the actions correpond to */
/// <summary>
/// The list of strings describing what the actions correspond to.
/// </summary>
/// <summary>Defines if the action is discrete or continuous</summary>
/// <summary>
/// Defines if the action is discrete or continuous.
/// </summary>
/// Deep clones the BrainParameter object
/// Deep clones the BrainParameter object.
/// </summary>
/// <returns> A new BrainParameter object with the same values as the original.</returns>
public BrainParameters Clone()

54
com.unity.ml-agents/Runtime/Sensor/CameraSensor.cs


using System;
/// <summary>
/// A sensor that wraps a Camera object to generate visual observations for an agent.
/// </summary>
public class CameraSensor : ISensor
{
Camera m_Camera;

int[] m_Shape;
SensorCompressionType m_CompressionType;
public CameraSensor(Camera camera, int width, int height, bool grayscale, string name,
SensorCompressionType compression)
/// <summary>
/// Creates and returns the camera sensor.
/// </summary>
/// <param name="camera">Camera object to capture images from.</param>
/// <param name="width">The width of the generated visual observation.</param>
/// <param name="height">The height of the generated visual observation.</param>
/// <param name="grayscale">Whether to convert the generated image to grayscale or keep color.</param>
/// <param name="name">The name of the camera sensor.</param>
/// <param name="compression">The compression to apply to the generated image.</param>
public CameraSensor(
Camera camera, int width, int height, bool grayscale, string name, SensorCompressionType compression)
{
m_Camera = camera;
m_Width = width;

m_Shape = new[] { height, width, grayscale ? 1 : 3 };
m_Shape = GenerateShape(width, height, grayscale);
/// <summary>
/// Accessor for the name of the sensor.
/// </summary>
/// <returns>Sensor name.</returns>
/// <summary>
/// Accessor for the size of the sensor data. Will be h x w x 1 for grayscale and
/// h x w x 3 for color.
/// </summary>
/// <returns>Size of each of the three dimensions.</returns>
/// <summary>
/// Generates a compressed image. This can be valuable in speeding-up training.
/// </summary>
/// <returns>Compressed image.</returns>
public byte[] GetCompressedObservation()
{
using (TimerStack.Instance.Scoped("CameraSensor.GetCompressedObservation"))

}
}
/// <summary>
/// Writes out the generated, uncompressed image to the provided <see cref="WriteAdapter"/>.
/// </summary>
/// <param name="adapter">Where the observation is written to.</param>
/// <returns></returns>
public int Write(WriteAdapter adapter)
{
using (TimerStack.Instance.Scoped("CameraSensor.WriteToTensor"))

}
}
/// <inheritdoc/>
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
{
return m_CompressionType;

/// Converts a m_Camera and corresponding resolution to a 2D texture.
/// Renders a Camera instance to a 2D texture at the corresponding resolution.
/// </summary>
/// <returns>The 2D texture.</returns>
/// <param name="obsCamera">Camera.</param>

RenderTexture.active = prevActiveRt;
RenderTexture.ReleaseTemporary(tempRt);
return texture2D;
}
/// <summary>
/// Computes the observation shape for a camera sensor based on the height, width
/// and grayscale flag.
/// </summary>
/// <param name="width">Width of the image captures from the camera.</param>
/// <param name="height">Height of the image captures from the camera.</param>
/// <param name="grayscale">Whether or not to convert the image to grayscale.</param>
/// <returns>The observation shape.</returns>
internal static int[] GenerateShape(int width, int height, bool grayscale)
{
return new[] { height, width, grayscale ? 1 : 3 };
}
}
}

37
com.unity.ml-agents/Runtime/Sensor/CameraSensorComponent.cs


using System;
/// <summary>
/// A SensorComponent that creates a <see cref="CameraSensor"/>.
/// </summary>
/// <summary>
/// Camera object that provides the data to the sensor.
/// </summary>
/// <summary>
/// Name of the generated <see cref="CameraSensor"/> object.
/// </summary>
/// <summary>
/// Width of the generated image.
/// </summary>
/// <summary>
/// Height of the generated image.
/// </summary>
/// <summary>
/// Whether to generate grayscale images or color.
/// </summary>
/// <summary>
/// The compression type to use for the sensor.
/// </summary>
/// <summary>
/// Creates the <see cref="CameraSensor"/>
/// </summary>
/// <returns>The created <see cref="CameraSensor"/> object for this component.</returns>
/// <summary>
/// Computes the observation shape of the sensor.
/// </summary>
/// <returns>The observation shape of the associated <see cref="CameraSensor"/> object.</returns>
return new[] { height, width, grayscale ? 1 : 3 };
return CameraSensor.GenerateShape(width, height, grayscale);
}
}
}

63
com.unity.ml-agents/Runtime/Sensor/ISensor.cs


namespace MLAgents
{
/// <summary>
/// The compression setting for visual/camera observations.
/// </summary>
/// <summary>
/// No compression. Data is preserved as float arrays.
/// </summary>
/// <summary>
/// PNG format. Data will be stored in binary format.
/// </summary>
/// For custom implementations, it is recommended to SensorBase instead.
/// For custom implementations, it is recommended to <see cref="SensorBase"/> instead.
/// For example, a sensor that observes the velocity of a rigid body (in 3D) would return new {3}.
/// A sensor that returns an RGB image would return new [] {Width, Height, 3}
/// For example, a sensor that observes the velocity of a rigid body (in 3D) would return
/// new {3}. A sensor that returns an RGB image would return new [] {Height, Width, 3}
/// <returns></returns>
/// <returns>Size of the observations that will be generated.</returns>
/// Write the observation data directly to the WriteAdapter.
/// This is considered an advanced interface; for a simpler approach, use SensorBase and override WriteFloats instead.
/// Note that this (and GetCompressedObservation) may be called multiple times per agent step, so should not
/// mutate any internal state.
/// Write the observation data directly to the <see cref="WriteAdapter"/>.
/// This is considered an advanced interface; for a simpler approach, use
/// <see cref="SensorBase"/> and override <see cref="SensorBase.WriteObservation"/> instead.
/// Note that this (and <see cref="GetCompressedObservation"/>) may
/// be called multiple times per agent step, so should not mutate any internal state.
/// <param name="adapter"></param>
/// <returns>The number of elements written</returns>
/// <param name="adapter">Where the observations will be written to.</param>
/// <returns>The number of elements written.</returns>
/// Return a compressed representation of the observation. For small observations, this should generally not be
/// implemented. However, compressing large observations (such as visual results) can significantly improve
/// model training time.
/// Return a compressed representation of the observation. For small observations,
/// this should generally not be implemented. However, compressing large observations
/// (such as visual results) can significantly improve model training time.
/// <returns></returns>
/// <returns>Compressed observation.</returns>
byte[] GetCompressedObservation();
/// <summary>

/// <summary>
/// Return the compression type being used. If no compression is used, return SensorCompressionType.None
/// Return the compression type being used. If no compression is used, return
/// <see cref="SensorCompressionType.None"/>.
/// <returns></returns>
/// <returns>Compression type used by the sensor.</returns>
/// Get the name of the sensor. This is used to ensure deterministic sorting of the sensors on an Agent,
/// so the naming must be consistent across all sensors and agents.
/// Get the name of the sensor. This is used to ensure deterministic sorting of the sensors
/// on an Agent, so the naming must be consistent across all sensors and agents.
/// <returns>The name of the sensor</returns>
/// <returns>The name of the sensor.</returns>
/// <summary>
/// Helper methods to be shared by all classes that implement <see cref="ISensor"/>.
/// </summary>
/// Get the total number of elements in the ISensor's observation (i.e. the product of the shape elements).
/// Get the total number of elements in the ISensor's observation (i.e. the product of the
/// shape elements).
/// </summary>
/// <param name="sensor"></param>
/// <returns></returns>

int count = 1;
for (var i = 0; i < shape.Length; i++)
var count = 1;
foreach (var dim in shape)
count *= shape[i];
count *= dim;
}
return count;

2
com.unity.ml-agents/Runtime/Sensor/Observation.cs


/// <summary>
/// The uncompressed dimensions of the data.
/// E.g. for RGB visual observations, this will be {Width, Height, 3}
/// E.g. for RGB visual observations, this will be {Height, Width, 3}
/// </summary>
public int[] Shape;
}

44
com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensor.cs


/// </summary>
public enum RayPerceptionCastType
{
/// <summary>
/// </summary>
/// <summary>
/// </summary>
/// <summary>
/// Contains the elements that define a ray perception sensor.
/// </summary>
public struct RayPerceptionInput
{
/// <summary>

}
}
/// <summary>
/// Contains the data generated/produced from a ray perception sensor.
/// </summary>
/// <summary>
/// Contains the data generated from a single ray of a ray perception sensor.
/// </summary>
public struct RayOutput
{
/// <summary>

int m_Frame;
}
/// <summary>
/// A sensor implementation that supports ray cast-based observations.
/// </summary>
public class RayPerceptionSensor : ISensor
{
float[] m_Observations;

get { return m_DebugDisplayInfo; }
}
/// <summary>
/// Creates the RayPerceptionSensor.
/// </summary>
/// <param name="name">The name of the sensor.</param>
/// <param name="rayInput">The inputs for the sensor.</param>
public RayPerceptionSensor(string name, RayPerceptionInput rayInput)
{
var numObservations = rayInput.OutputSize();

}
}
internal void SetRayPerceptionInput(RayPerceptionInput input)
{
// TODO make sure that number of rays and tags don't change
m_RayPerceptionInput = input;
}
/// <summary>
/// Computes the ray perception observations and saves them to the provided
/// <see cref="WriteAdapter"/>.
/// </summary>
/// <param name="adapter">Where the ray perception observations are written to.</param>
/// <returns></returns>
public int Write(WriteAdapter adapter)
{
using (TimerStack.Instance.Scoped("RayPerceptionSensor.Perceive"))

return m_Observations.Length;
}
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
public virtual SensorCompressionType GetCompressionType()
{
return SensorCompressionType.None;

/// Evaluates the raycasts to be used as part of an observation of an agent.
/// </summary>
/// <param name="input">Input defining the rays that will be cast.</param>
/// <param name="output">Output class that will be written to with raycast results.</param>
///
/// <returns>Output struct containing the raycast results.</returns>
public static RayPerceptionOutput PerceiveStatic(RayPerceptionInput input)
{
RayPerceptionOutput output = new RayPerceptionOutput();

/// <param name="rayIndex"></param>
/// <param name="debugRayOut"></param>
/// <returns></returns>
static RayPerceptionOutput.RayOutput PerceiveSingleRay(
internal static RayPerceptionOutput.RayOutput PerceiveSingleRay(
RayPerceptionInput input,
int rayIndex,
out DebugDisplayInfo.RayInfo debugRayOut

debugRayOut.castRadius = scaledCastRadius;
return rayOutput;
}
}
}

7
com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensorComponent2D.cs


namespace MLAgents
{
/// <summary>
/// A component for 2D Ray Perception.
/// </summary>
/// <summary>
/// Initializes the raycast sensor component.
/// </summary>
public RayPerceptionSensorComponent2D()
{
// Set to the 2D defaults (just in case they ever diverge).

/// <inheritdoc/>
public override RayPerceptionCastType GetCastType()
{
return RayPerceptionCastType.Cast2D;

37
com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensorComponent3D.cs


using System;
using UnityEngine.Serialization;
/// <summary>
/// A component for 3D Ray Perception.
/// </summary>
[Header("3D Properties", order = 100)]
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("startVerticalOffset")]
public float startVerticalOffset;
float m_StartVerticalOffset;
/// <summary>
/// Ray start is offset up or down by this amount.
/// </summary>
public float startVerticalOffset
{
get => m_StartVerticalOffset;
set { m_StartVerticalOffset = value; UpdateSensor(); }
}
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("endVerticalOffset")]
public float endVerticalOffset;
float m_EndVerticalOffset;
/// <summary>
/// Ray end is offset up or down by this amount.
/// </summary>
public float endVerticalOffset
{
get => m_EndVerticalOffset;
set { m_EndVerticalOffset = value; UpdateSensor(); }
}
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
public override float GetEndVerticalOffset()
{
return endVerticalOffset;

279
com.unity.ml-agents/Runtime/Sensor/RayPerceptionSensorComponentBase.cs


using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
/// <summary>
/// A base class to support sensor components for raycast-based sensors.
/// </summary>
public string sensorName = "RayPerceptionSensor";
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("sensorName")]
string m_SensorName = "RayPerceptionSensor";
/// <summary>
/// The name of the Sensor that this component wraps.
/// </summary>
public string sensorName
{
get => m_SensorName;
// Restrict the access on the name, since changing it a runtime doesn't re-sort the Agent sensors.
internal set => m_SensorName = value;
}
[SerializeField]
[FormerlySerializedAs("detectableTags")]
public List<string> detectableTags;
List<string> m_DetectableTags;
/// <summary>
/// List of tags in the scene to compare against.
/// </summary>
public List<string> detectableTags
{
get => m_DetectableTags;
// Note: can't change at runtime
internal set => m_DetectableTags = value;
}
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("raysPerDirection")]
public int raysPerDirection = 3;
int m_RaysPerDirection = 3;
/// <summary>
/// Number of rays to the left and right of center.
/// </summary>
public int raysPerDirection
{
get => m_RaysPerDirection;
// Note: can't change at runtime
internal set => m_RaysPerDirection = value;
}
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("maxRayDegrees")]
[Tooltip("Cone size for rays. Using 90 degrees will cast rays to the left and right. Greater than 90 degrees will go backwards.")]
public float maxRayDegrees = 70;
[Tooltip("Cone size for rays. Using 90 degrees will cast rays to the left and right. " +
"Greater than 90 degrees will go backwards.")]
float m_MaxRayDegrees = 70;
/// <summary>
/// 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
{
get => m_MaxRayDegrees;
set { m_MaxRayDegrees = value; UpdateSensor(); }
}
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("sphereCastRadius")]
public float sphereCastRadius = 0.5f;
float m_SphereCastRadius = 0.5f;
/// <summary>
/// Radius of sphere to cast. Set to zero for raycasts.
/// </summary>
public float sphereCastRadius
{
get => m_SphereCastRadius;
set { m_SphereCastRadius = value; UpdateSensor(); }
}
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("rayLength")]
public float rayLength = 20f;
float m_RayLength = 20f;
/// <summary>
/// Length of the rays to cast.
/// </summary>
public float rayLength
{
get => m_RayLength;
set { m_RayLength = value; UpdateSensor(); }
}
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("rayLayerMask")]
public LayerMask rayLayerMask = Physics.DefaultRaycastLayers;
LayerMask m_RayLayerMask = Physics.DefaultRaycastLayers;
/// <summary>
/// Controls which layers the rays can hit.
/// </summary>
public LayerMask rayLayerMask
{
get => m_RayLayerMask;
set { m_RayLayerMask = value; UpdateSensor();}
}
[HideInInspector]
[SerializeField]
[FormerlySerializedAs("observationStacks")]
public int observationStacks = 1;
int m_ObservationStacks = 1;
/// <summary>
/// Whether to stack previous observations. Using 1 means no previous observations.
/// </summary>
internal int observationStacks
{
get => m_ObservationStacks;
set => m_ObservationStacks = value; // Note: can't change at runtime
}
/// <summary>
/// Color to code a ray that hits another object.
/// </summary>
[HideInInspector]
[SerializeField]
public Color rayHitColor = Color.red;
public Color rayMissColor = Color.white;
internal Color rayHitColor = Color.red;
/// <summary>
/// Color to code a ray that avoid or misses all other objects.
/// </summary>
[HideInInspector]
[SerializeField]
internal Color rayMissColor = Color.white;
/// <summary>
/// Returns the <see cref="RayPerceptionCastType"/> for the associated raycast sensor.
/// </summary>
/// <returns></returns>
/// <summary>
/// Returns the amount that the ray start is offset up or down by.
/// </summary>
/// <returns></returns>
/// <summary>
/// Returns the amount that the ray end is offset up or down by.
/// </summary>
/// <returns></returns>
/// <summary>
/// Returns an initialized raycast sensor.
/// </summary>
/// <returns></returns>
var rayAngles = GetRayAngles(raysPerDirection, maxRayDegrees);
var rayPerceptionInput = GetRayPerceptionInput();
var rayPerceptionInput = new RayPerceptionInput();
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;
m_RaySensor = new RayPerceptionSensor(sensorName, rayPerceptionInput);
m_RaySensor = new RayPerceptionSensor(m_SensorName, rayPerceptionInput);
if (observationStacks != 1)
{

return m_RaySensor;
}
/// <summary>
/// Returns the specific ray angles given the number of rays per direction and the
/// cone size for the rays.
/// </summary>
/// <param name="raysPerDirection">Number of rays to the left and right of center.</param>
/// <param name="maxRayDegrees">
/// Cone size for rays. Using 90 degrees will cast rays to the left and right.
/// Greater than 90 degrees will go backwards.
/// </param>
/// <returns></returns>
public static float[] GetRayAngles(int raysPerDirection, float maxRayDegrees)
{
// Example:

return anglesOut;
}
/// <summary>
/// Returns the observation shape for this raycast sensor which depends on the number
/// of tags for detected objects and the number of rays.
/// </summary>
/// <returns></returns>
var numTags = detectableTags?.Count ?? 0;
var numTags = m_DetectableTags?.Count ?? 0;
/// <summary>
/// Draw the debug information from the sensor (if available).
/// </summary>
public void OnDrawGizmos()
RayPerceptionInput GetRayPerceptionInput()
{
var rayAngles = GetRayAngles(raysPerDirection, maxRayDegrees);
var rayPerceptionInput = new RayPerceptionInput();
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;
}
internal void UpdateSensor()
if (m_RaySensor?.debugDisplayInfo?.rayInfos == null)
if (m_RaySensor != null)
return;
var rayInput = GetRayPerceptionInput();
m_RaySensor.SetRayPerceptionInput(rayInput);
var debugInfo = m_RaySensor.debugDisplayInfo;
}
// Draw "old" observations in a lighter color.
// Since the agent may not step every frame, this helps de-emphasize "stale" hit information.
var alpha = Mathf.Pow(.5f, debugInfo.age);
void OnDrawGizmosSelected()
{
if (m_RaySensor?.debugDisplayInfo?.rayInfos != null)
{
// If we have cached debug info from the sensor, draw that.
// Draw "old" observations in a lighter color.
// Since the agent may not step every frame, this helps de-emphasize "stale" hit information.
var alpha = Mathf.Pow(.5f, m_RaySensor.debugDisplayInfo.age);
foreach (var rayInfo in debugInfo.rayInfos)
foreach (var rayInfo in m_RaySensor.debugDisplayInfo.rayInfos)
{
DrawRaycastGizmos(rayInfo, alpha);
}
}
else
var startPositionWorld = rayInfo.worldStart;
var endPositionWorld = rayInfo.worldEnd;
var rayDirection = endPositionWorld - startPositionWorld;
rayDirection *= rayInfo.rayOutput.hitFraction;
var rayInput = GetRayPerceptionInput();
for (var rayIndex = 0; rayIndex < rayInput.angles.Count; rayIndex++)
{
DebugDisplayInfo.RayInfo debugRay;
RayPerceptionSensor.PerceiveSingleRay(rayInput, rayIndex, out debugRay);
DrawRaycastGizmos(debugRay);
}
}
}
/// <summary>
/// Draw the debug information from the sensor (if available).
/// </summary>
void DrawRaycastGizmos(DebugDisplayInfo.RayInfo rayInfo, float alpha=1.0f)
{
var startPositionWorld = rayInfo.worldStart;
var endPositionWorld = rayInfo.worldEnd;
var rayDirection = endPositionWorld - startPositionWorld;
rayDirection *= rayInfo.rayOutput.hitFraction;
// hit fraction ^2 will shift "far" hits closer to the hit color
var lerpT = rayInfo.rayOutput.hitFraction * rayInfo.rayOutput.hitFraction;
var color = Color.Lerp(rayHitColor, rayMissColor, lerpT);
color.a *= alpha;
Gizmos.color = color;
Gizmos.DrawRay(startPositionWorld, rayDirection);
// hit fraction ^2 will shift "far" hits closer to the hit color
var lerpT = rayInfo.rayOutput.hitFraction * rayInfo.rayOutput.hitFraction;
var color = Color.Lerp(rayHitColor, rayMissColor, lerpT);
color.a *= alpha;
Gizmos.color = color;
Gizmos.DrawRay(startPositionWorld, rayDirection);
// Draw the hit point as a sphere. If using rays to cast (0 radius), use a small sphere.
if (rayInfo.rayOutput.hasHit)
{
var hitRadius = Mathf.Max(rayInfo.castRadius, .05f);
Gizmos.DrawWireSphere(startPositionWorld + rayDirection, hitRadius);
}
// Draw the hit point as a sphere. If using rays to cast (0 radius), use a small sphere.
if (rayInfo.rayOutput.hasHit)
{
var hitRadius = Mathf.Max(rayInfo.castRadius, .05f);
Gizmos.DrawWireSphere(startPositionWorld + rayDirection, hitRadius);
}
}
}

21
com.unity.ml-agents/Runtime/Sensor/RenderTextureSensor.cs


using System;
/// <summary>
/// Sensor class that wraps a <see cref="RenderTexture"/> instance.
/// </summary>
public class RenderTextureSensor : ISensor
{
RenderTexture m_RenderTexture;

SensorCompressionType m_CompressionType;
public RenderTextureSensor(RenderTexture renderTexture, bool grayscale, string name,
SensorCompressionType compressionType)
/// <summary>
/// Initializes the sensor.
/// </summary>
/// <param name="renderTexture">The <see cref="RenderTexture"/> instance to wrap.</param>
/// <param name="grayscale">Whether to convert it to grayscale or not.</param>
/// <param name="name">Name of the sensor.</param>
/// <param name="compressionType">Compression method for the render texture.</param>
public RenderTextureSensor(
RenderTexture renderTexture, bool grayscale, string name, SensorCompressionType compressionType)
{
m_RenderTexture = renderTexture;
var width = renderTexture != null ? renderTexture.width : 0;

m_CompressionType = compressionType;
}
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
public byte[] GetCompressedObservation()
{
using (TimerStack.Instance.Scoped("RenderTexSensor.GetCompressedObservation"))

}
}
/// <inheritdoc/>
public int Write(WriteAdapter adapter)
{
using (TimerStack.Instance.Scoped("RenderTexSensor.GetCompressedObservation"))

}
}
/// <inheritdoc/>
/// <inheritdoc/>
public SensorCompressionType GetCompressionType()
{
return m_CompressionType;

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


using System;
/// <summary>
/// Component that wraps a <see cref="RenderTextureSensor"/>.
/// </summary>
/// <summary>
/// The <see cref="RenderTexture"/> instance that the associated
/// <see cref="RenderTextureSensor"/> wraps.
/// </summary>
/// <summary>
/// Name of the sensor.
/// </summary>
/// <summary>
/// Whether the RenderTexture observation should be converted to grayscale or not.
/// </summary>
/// <summary>
/// Compression type for the render texture observation.
/// </summary>
/// <inheritdoc/>
/// <inheritdoc/>
public override int[] GetObservationShape()
{
var width = renderTexture != null ? renderTexture.width : 0;

19
com.unity.ml-agents/Runtime/Sensor/SensorBase.cs


using UnityEngine;
/// <summary>
/// A base sensor that provides a number default implementations.
/// </summary>
/// Write the observations to the output buffer. This size of the buffer will be product of the sizes returned
/// by GetObservationShape().
/// Write the observations to the output buffer. This size of the buffer will be product
/// of the sizes returned by <see cref="GetObservationShape"/>.
/// <inheritdoc/>
/// <inheritdoc/>
/// Default implementation of Write interface. This creates a temporary array, calls WriteObservation,
/// and then writes the results to the WriteAdapter.
/// Default implementation of Write interface. This creates a temporary array,
/// calls WriteObservation, and then writes the results to the WriteAdapter.
/// <returns>The number of elements written.</returns>
public virtual int Write(WriteAdapter adapter)
{
// TODO reuse buffer for similar agents, don't call GetObservationShape()

return numFloats;
}
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
public virtual SensorCompressionType GetCompressionType()
{
return SensorCompressionType.None;

17
com.unity.ml-agents/Runtime/Sensor/SensorComponent.cs


using System;
/// Editor components for creating Sensors. Generally an ISensor implementation should have a corresponding
/// SensorComponent to create it.
/// Editor components for creating Sensors. Generally an ISensor implementation should have a
/// corresponding SensorComponent to create it.
/// </summary>
public abstract class SensorComponent : MonoBehaviour
{

/// <returns></returns>
/// <returns>Created ISensor object.</returns>
/// <returns></returns>
/// <returns>Shape of the sensor observation.</returns>
/// <summary>
/// Whether the observation is visual or not.
/// </summary>
/// <returns>True if the observation is visual, false otherwise.</returns>
public virtual bool IsVisual()
{
var shape = GetObservationShape();

/// <summary>
/// Whether the observation is vector or not.
/// </summary>
/// <returns>True if the observation is vector, false otherwise.</returns>
public virtual bool IsVector()
{
var shape = GetObservationShape();

4
com.unity.ml-agents/Runtime/Sensor/StackingSensor.cs


/// <summary>
///
/// </summary>
/// <param name="wrapped">The wrapped sensor</param>
/// <param name="numStackedObservations">Number of stacked observations to keep</param>
/// <param name="wrapped">The wrapped sensor.</param>
/// <param name="numStackedObservations">Number of stacked observations to keep.</param>
public StackingSensor(ISensor wrapped, int numStackedObservations)
{
// TODO ensure numStackedObservations > 1

23
com.unity.ml-agents/Runtime/Sensor/VectorSensor.cs


namespace MLAgents
{
/// <summary>
/// A sensor implementation for vector observations.
/// </summary>
// TOOD allow setting float[]
// TODO allow setting float[]
/// <summary>
/// Initializes the sensor.
/// </summary>
/// <param name="observationSize">Number of vector observations.</param>
/// <param name="name">Name of the sensor.</param>
public VectorSensor(int observationSize, string name = null)
{
if (name == null)

m_Shape = new[] { observationSize };
}
/// <inheritdoc/>
public int Write(WriteAdapter adapter)
{
var expectedObservations = m_Shape[0];

return expectedObservations;
}
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
/// <inheritdoc/>
public virtual SensorCompressionType GetCompressionType()
{
return SensorCompressionType.None;

/// <summary>
/// Adds a boolean observation to the vector observation of the agent.
/// </summary>
/// <param name="observation"></param>
/// <param name="observation">Observation.</param>
/// <summary>
/// Adds a one-hot encoding observation.
/// </summary>
/// <param name="observation">The index of this observation.</param>
/// <param name="range">The max index for any observation.</param>
public void AddOneHotObservation(int observation, int range)
{
for (var i = 0; i < range; i++)

8
com.unity.ml-agents/Runtime/Sensor/WriteAdapter.cs


/// <summary>
/// Set the adapter to write to a TensorProxy at the given batch and channel offset.
/// </summary>
/// <param name="tensorProxy">Tensor proxy that will be writtent to.</param>
/// <param name="batchIndex">Batch index in the tensor proxy (i.e. the index of the Agent)</param>
/// <param name="tensorProxy">Tensor proxy that will be written to.</param>
/// <param name="batchIndex">Batch index in the tensor proxy (i.e. the index of the Agent).</param>
/// <param name="channelOffset">Offset from the start of the channel to write to.</param>
internal void SetTarget(TensorProxy tensorProxy, int batchIndex, int channelOffset)
{

/// <summary>
/// 1D write access at a specified index. Use AddRange if possible instead.
/// </summary>
/// <param name="index">Index to write to</param>
/// <param name="index">Index to write to.</param>
public float this[int index]
{
set

/// Write the range of floats
/// </summary>
/// <param name="data"></param>
/// <param name="writeOffset">Optional write offset</param>
/// <param name="writeOffset">Optional write offset.</param>
public void AddRange(IEnumerable<float> data, int writeOffset = 0)
{
if (m_Data != null)

8
com.unity.ml-agents/Runtime/SideChannel/EngineConfigurationChannel.cs


namespace MLAgents
{
/// <summary>
/// Side channel that supports modifying attributes specific to the Unity Engine.
/// </summary>
/// <summary>
/// Initializes the side channel.
/// </summary>
/// <inheritdoc/>
public override void OnMessageReceived(byte[] data)
{
using (var memStream = new MemoryStream(data))

16
com.unity.ml-agents/Runtime/SideChannel/FloatPropertiesChannel.cs


namespace MLAgents
{
/// <summary>
/// Interface for managing a collection of float properties keyed by a string variable.
/// </summary>
public interface IFloatProperties
{
/// <summary>

IList<string> ListProperties();
}
/// <summary>
/// Side channel that is comprised of a collection of float variables, represented by
/// <see cref="IFloatProperties"/>
/// </summary>
public class FloatPropertiesChannel : SideChannel, IFloatProperties
{
Dictionary<string, float> m_FloatProperties = new Dictionary<string, float>();

/// <summary>
/// Initializes the side channel with the provided channel ID.
/// </summary>
/// <param name="channelId">ID for the side channel.</param>
public FloatPropertiesChannel(Guid channelId = default(Guid))
{
if (channelId == default(Guid))

}
}
/// <inheritdoc/>
public override void OnMessageReceived(byte[] data)
{
var kv = DeserializeMessage(data);

}
}
/// <inheritdoc/>
public void SetProperty(string key, float value)
{
m_FloatProperties[key] = value;

}
}
/// <inheritdoc/>
public float GetPropertyWithDefault(string key, float defaultValue)
{
if (m_FloatProperties.ContainsKey(key))

}
}
/// <inheritdoc/>
/// <inheritdoc/>
public IList<string> ListProperties()
{
return new List<string>(m_FloatProperties.Keys);

5
com.unity.ml-agents/Runtime/SideChannel/RawBytesChannel.cs


namespace MLAgents
{
/// <summary>
/// Side channel for managing raw bytes of data. It is up to the clients of this side channel
/// to interpret the messages.
/// </summary>
public class RawBytesChannel : SideChannel
{
List<byte[]> m_MessagesReceived = new List<byte[]>();

ChannelId = channelId;
}
/// <inheritdoc/>
public override void OnMessageReceived(byte[] data)
{
m_MessagesReceived.Add(data);

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


namespace MLAgents
{
/// <summary>
/// Side channels provide an alternative mechanism of sending/receiving data from Unity
/// to Python that is outside of the traditional machine learning loop. ML-Agents provides
/// some specific implementations of side channels, but users can create their own.
/// </summary>
public abstract class SideChannel
{
// The list of messages (byte arrays) that need to be sent to Python via the communicator.

/// An int identifier for the SideChannel. Ensures that there is only ever one side channel
/// of each type. Ensure the Unity side channels will be linked to their Python equivalent.
/// </summary>
/// <returns> The integer identifier of the SideChannel</returns>
/// <returns> The integer identifier of the SideChannel.</returns>
public Guid ChannelId{
get;
protected set;

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


static double s_TicksToSeconds = 1e-7; // 100 ns per tick
/// <summary>
/// Full name of the node. This is the node's parents full name concatenated with this node's name
/// Full name of the node. This is the node's parents full name concatenated with this
/// node's name.
/// </summary>
string m_FullName;

Reset();
}
/// <summary>
/// Resets the timer stack and the root node.
/// </summary>
/// <param name="name">Name of the root node.</param>
public void Reset(string name = "root")
{
m_Stack = new Stack<TimerNode>();

/// <summary>
/// The singleton <see cref="TimerStack"/> instance.
/// </summary>
public static TimerStack Instance
{
get { return k_Instance; }

get { return m_RootNode; }
}
/// <summary>
/// Whether or not new timers and gauges can be added.
/// </summary>
public bool Recording
{
get { return m_Recording; }

/// <summary>
/// Updates the referenced gauge in the root node with the provided value.
/// </summary>
/// <param name="name">The name of the Gauge to modify.</param>
/// <param name="value">The value to update the Gauge with.</param>
public void SetGauge(string name, float value)
{
if (!Recording)

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


{
"name": "Unity.ML-Agents",
"references": [
"Barracuda"
"Barracuda",
"Unity.ML-Agents.CommunicatorObjects"
],
"optionalUnityReferences": [],
"includePlatforms": [],

],
"autoReferenced": true,
"defineConstraints": []
}
}

9
com.unity.ml-agents/Runtime/UnityAgentsException.cs


namespace MLAgents
{
/// <summary>
/// </summary>
/// <summary>
/// </summary>
/// <param name="message">The exception message</param>
/// <summary>
/// </summary>
/// <param name="info">Data for serializing/de-serializing</param>
/// <param name="context">Describes the source and destination of the serialized stream</param>
protected UnityAgentsException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)

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


using System;
using UnityEngine;
using System.Collections.Generic;
namespace MLAgents
{

/// being stored in the tensor.
/// </param>
/// <returns>The number of floats written</returns>
public static int TextureToTensorProxy(
internal static int TextureToTensorProxy(
Texture2D texture,
WriteAdapter adapter,
bool grayScale)

/// Input array whose elements will be cumulatively added
/// </param>
/// <returns> The cumulative sum of the input array.</returns>
public static int[] CumSum(int[] input)
internal static int[] CumSum(int[] input)
{
var runningSum = 0;
var result = new int[input.Length + 1];

result[actionIndex + 1] = runningSum;
}
return result;
}
/// <summary>
/// Shifts list elements to the left by the specified amount (in-place).
/// <param name="list">
/// List whose elements will be shifted
/// </param>
/// <param name="shiftAmount">
/// Amount to shift the elements to the left by
/// </param>
/// </summary>
public static void ShiftLeft<T>(List<T> list, int shiftAmount)
{
for (var i = shiftAmount; i < list.Count; i++)
{
list[i - shiftAmount] = list[i];
}
}
/// <summary>
/// Replaces target list elements with source list elements starting at specified position
/// in target list.
/// <param name="dst">
/// Target list, where the elements are added to
/// </param>
/// <param name="src">
/// Source array, where the elements are copied from
/// </param>
/// <param name="start">
/// Starting position in target list to copy elements to
/// </param>
/// </summary>
public static void ReplaceRange<T>(List<T> dst, List<T> src, int start)
{
for (var i = 0; i < src.Count; i++)
{
dst[i + start] = src[i];
}
}
/// <summary>
/// Adds elements to list without extra temp allocations (assuming it fits pre-allocated
/// capacity of the list). The built-in List/<T/>.AddRange() unfortunately allocates
/// a temporary list to add items (even if the original array has sufficient capacity):
/// https://stackoverflow.com/questions/2123161/listt-addrange-implementation-suboptimal
/// Note: this implementation might be slow with a large source array.
/// <param name="dst">
/// Target list, where the elements are added to
/// </param>
/// <param name="src">
/// Source array, where the elements are copied from
/// </param>
/// </summary>
// ReSharper disable once ParameterTypeCanBeEnumerable.Global
public static void AddRangeNoAlloc<T>(List<T> dst, T[] src)
{
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var item in src)
{
dst.Add(item);
}
}
/// <summary>
/// Calculates the number of uncompressed floats in a list of ISensor
/// </summary>
public static int GetSensorFloatObservationSize(this List<ISensor> sensors)
{
int numFloatObservations = 0;
for (var i = 0; i < sensors.Count; i++)
{
if (sensors[i].GetCompressionType() == SensorCompressionType.None)
{
numFloatObservations += sensors[i].ObservationSize();
}
}
return numFloatObservations;
}
#if DEBUG

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


namespace MLAgents.Tests
{
[TestFixture]
public class DemonstrationTests : MonoBehaviour
public class DemonstrationTests
{
const string k_DemoDirectory = "Assets/Demonstrations/";
const string k_ExtensionType = ".demo";

}
[Test]
public void TestStoreInitalize()
public void TestStoreInitialize()
{
var fileSystem = new MockFileSystem();

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


"references": [
"Unity.ML-Agents.Editor",
"Unity.ML-Agents",
"Barracuda"
"Barracuda",
"Unity.ML-Agents.CommunicatorObjects"
],
"optionalUnityReferences": [
"TestAssemblies"

"defineConstraints": [
"UNITY_INCLUDE_TESTS"
]
}
}

15
gym-unity/gym_unity/envs/__init__.py


"""Resets the state of the environment and returns an initial observation.
In the case of multi-agent environments, this is a list.
Returns: observation (object/list): the initial observation of the
space.
space.
"""
step_result = self._step(True)
n_agents = step_result.n_agents()

default_observation = self._get_vector_obs(info)[0, :]
else:
raise UnityGymException(
"The Agent does not have vector observations and the environment was not setup"
"The Agent does not have vector observations and the environment was not setup "
+ "to use visual observations."
)

def _check_agents(self, n_agents: int) -> None:
if not self._multiagent and n_agents > 1:
raise UnityGymException(
"The environment was launched as a single-agent environment, however"
"The environment was launched as a single-agent environment, however "
"The environment was launched as a mutli-agent environment, however"
"The environment was launched as a mutli-agent environment, however "
"there is only one agent in the scene."
)
if self._n_agents == -1:

while info.n_agents() - sum(info.done) < self._n_agents:
if not info.done.all():
raise UnityGymException(
"The environment does not have the expected amount of agents."
"The environment does not have the expected amount of agents. "
+ "Some agents did not request decisions at the same time."
)
for agent_id, reward in zip(info.agent_id, info.reward):

def get_id_permutation(self, agent_ids: List[int]) -> List[int]:
"""
Get the permutation from new agent ids to the order that preserves the positions of previous agents.
The result is a list with each integer from 0 to len(agent_ids)-1 appearing exactly once.
The result is a list with each integer from 0 to len(_agent_id_to_gym_index)-1
appearing exactly once.
"""
# Map the new agent ids to the their index
new_agent_ids_to_index = {

# Make the output list. We don't write to it sequentially, so start with dummy values.
new_permutation = [-1] * len(agent_ids)
new_permutation = [-1] * len(self._agent_id_to_gym_index)
# For each agent ID, find the new index of the agent, and write it in the original index.
for agent_id, original_index in self._agent_id_to_gym_index.items():

9
ml-agents/mlagents/trainers/common/nn_policy.py


(tf.identity(self.all_log_probs)), axis=1, keepdims=True
)
self.action_holder = tf.placeholder(
shape=[None, self.act_size[0]], dtype=tf.float32, name="action_holder"
)
def _create_dc_actor(self, encoded: tf.Tensor) -> None:
"""
Creates Discrete control actor-critic model.

self.output = tf.identity(output)
self.all_log_probs = tf.identity(normalized_logits, name="action")
self.action_holder = tf.placeholder(
shape=[None, len(policy_branches)], dtype=tf.int32, name="action_holder"
)
tf.one_hot(self.action_holder[:, i], self.act_size[i])
tf.one_hot(self.output[:, i], self.act_size[i])
for i in range(len(self.act_size))
],
axis=1,

4
ml-agents/mlagents/trainers/components/reward_signals/curiosity/signal.py


if self.policy.use_continuous_act:
feed_dict[self.policy.selected_actions] = mini_batch["actions"]
else:
feed_dict[self.policy.action_holder] = mini_batch["actions"]
feed_dict[self.policy.output] = mini_batch["actions"]
unscaled_reward = self.policy.sess.run(
self.model.intrinsic_reward, feed_dict=feed_dict
)

if self.policy.use_continuous_act:
feed_dict[policy.selected_actions] = mini_batch["actions"]
else:
feed_dict[policy.action_holder] = mini_batch["actions"]
feed_dict[policy.output] = mini_batch["actions"]
if self.policy.use_vec_obs:
feed_dict[policy.vector_in] = mini_batch["vector_obs"]
feed_dict[self.model.next_vector_in] = mini_batch["next_vector_in"]

4
ml-agents/mlagents/trainers/components/reward_signals/gail/signal.py


if self.policy.use_continuous_act:
feed_dict[self.policy.selected_actions] = mini_batch["actions"]
else:
feed_dict[self.policy.action_holder] = mini_batch["actions"]
feed_dict[self.policy.output] = mini_batch["actions"]
feed_dict[self.model.done_policy_holder] = np.array(
mini_batch["done"]
).flatten()

if self.policy.use_continuous_act:
feed_dict[policy.selected_actions] = mini_batch["actions"]
else:
feed_dict[policy.action_holder] = mini_batch["actions"]
feed_dict[policy.output] = mini_batch["actions"]
if self.policy.use_vis_obs > 0:
for i in range(len(policy.visual_in)):

6
ml-agents/mlagents/trainers/ppo/optimizer.py


self, h_size: int, num_layers: int, vis_encode_type: EncoderType
) -> None:
"""
Creates Continuous control actor-critic model.
Creates Continuous control critic (value) network.
:param h_size: Size of hidden linear layers.
:param num_layers: Number of hidden linear layers.
:param vis_encode_type: The type of visual encoder to use.

self, h_size: int, num_layers: int, vis_encode_type: EncoderType
) -> None:
"""
Creates Discrete control actor-critic model.
Creates Discrete control critic (value) network.
:param h_size: Size of hidden linear layers.
:param num_layers: Number of hidden linear layers.
:param vis_encode_type: The type of visual encoder to use.

if self.policy.output_pre is not None and "actions_pre" in mini_batch:
feed_dict[self.policy.output_pre] = mini_batch["actions_pre"]
else:
feed_dict[self.policy.action_holder] = mini_batch["actions"]
feed_dict[self.policy.output] = mini_batch["actions"]
if self.policy.use_recurrent:
feed_dict[self.policy.prev_action] = mini_batch["prev_action"]
feed_dict[self.policy.action_masks] = mini_batch["action_mask"]

8
ml-agents/mlagents/trainers/sac/network.py


self.h_size,
self.join_scopes(scope, "value"),
)
self.external_action_in = tf.placeholder(
shape=[None, self.policy.act_size[0]],
dtype=tf.float32,
name="external_action_in",
)
hidden_q = tf.concat([hidden_value, self.policy.action_holder], axis=-1)
hidden_q = tf.concat([hidden_value, self.external_action_in], axis=-1)
hidden_qp = tf.concat([hidden_value, self.policy.output], axis=-1)
self.q1_heads, self.q2_heads, self.q1, self.q2 = self.create_q_heads(
self.stream_names,

7
ml-agents/mlagents/trainers/sac/optimizer.py


self.visual_in = self.policy.visual_in
self.next_vector_in = self.target_network.vector_in
self.next_visual_in = self.target_network.visual_in
self.action_holder = self.policy.action_holder
self.sequence_length_ph = self.policy.sequence_length_ph
self.next_sequence_length_ph = self.target_network.sequence_length_ph
if not self.policy.use_continuous_act:

# Don't use value estimate during inference. TODO: Check why PPO uses value_estimate in inference.
# Don't use value estimate during inference.
self.value = tf.identity(
self.policy_network.value, name="value_estimate_unused"
)

feed_dict[self.rewards_holders[name]] = batch["{}_rewards".format(name)]
if self.policy.use_continuous_act:
feed_dict[policy.action_holder] = batch["actions"]
feed_dict[self.policy_network.external_action_in] = batch["actions"]
feed_dict[policy.action_holder] = batch["actions"]
feed_dict[policy.output] = batch["actions"]
if self.policy.use_recurrent:
feed_dict[policy.prev_action] = batch["prev_action"]
feed_dict[policy.action_masks] = batch["action_mask"]

4
ml-agents/mlagents/trainers/tests/test_meta_curriculum.py


hidden_units: 128
lambd: 0.95
learning_rate: 5.0e-3
max_steps: 300
max_steps: 100
memory_size: 256
normalize: false
num_epoch: 3

env = Simple1DEnvironment(use_discrete=False)
curriculum_config = json.loads(dummy_curriculum_json_str)
mc = MetaCurriculum({curriculum_brain_name: curriculum_config})
_check_environment_trains(env, TRAINER_CONFIG, mc, -100.0)
_check_environment_trains(env, TRAINER_CONFIG, mc, None)

9
ml-agents/mlagents/trainers/tests/test_simple_rl.py


# Begin training
tc.start_learning(env_manager)
print(tc._get_measure_vals())
for mean_reward in tc._get_measure_vals().values():
assert not math.isnan(mean_reward)
assert mean_reward > success_threshold
if (
success_threshold is not None
): # For tests where we are just checking setup and not reward
for mean_reward in tc._get_measure_vals().values():
assert not math.isnan(mean_reward)
assert mean_reward > success_threshold
@pytest.mark.parametrize("use_discrete", [True, False])

1
ml-agents/mlagents/trainers/tf_policy.py


self.output_pre: Optional[tf.Tensor] = None
self.output: Optional[tf.Tensor] = None
self.selected_actions: Optional[tf.Tensor] = None
self.action_holder: Optional[tf.Tensor] = None
self.action_masks: Optional[tf.Tensor] = None
self.prev_action: Optional[tf.Tensor] = None
self.memory_in: Optional[tf.Tensor] = None

34
notebooks/getting-started-gym.ipynb


"source": [
"## Single-Agent Environments\n",
"\n",
"The first five steps show how to use the `UnityEnv` wrapper with single-agent environments. See below step five for how to use with multi-agent environments."
"These steps show how to use the `UnityEnv` wrapper with single-agent environments. See section below for how to use with multi-agent environments."
]
},
{

"### 1. Load dependencies\n",
"### 1.Set environment parameters\n",
"Be sure to set `env_name` to the name of the Unity environment file you want to launch.\n",
"\n",
"__Note__ : All the example environments have multiple agents by default. You can disable the duplicates in the inspector before building the executable."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"env_name = \"../envs/GridWorldSingle\" # Name of the Unity environment binary to launch"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2. Load dependencies\n",
"\n",
"The following loads the necessary dependencies and checks the Python version (at runtime). ML-Agents Toolkit (v0.3 onwards) requires Python 3."
]

"cell_type": "markdown",
"metadata": {},
"source": [
"### 2. Start the environment\n",
"`UnityEnv` launches and begins communication with the environment when instantiated. We will be using the `GridWorld` environment. You will need to create an `envs` directory within the `/python` subfolder of the repository, and build the GridWorld environment to that directory. For more information on building Unity environments, see [here](../docs/Learning-Environment-Executable.md)."
"### 3. Start the environment\n",
"`UnityEnv` launches and begins communication with the environment when instantiated. We will be using the `GridWorld` environment. You will need to create an `envs` directory in the root directory of the repository, and build the GridWorld environment to that directory. For more information on building Unity environments, see [here](https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Learning-Environment-Executable.md)."
]
},
{

"outputs": [],
"source": [
"env_name = \"../envs/GridWorld\" # Name of the Unity environment binary to launch\n",
"env = UnityEnv(env_name, worker_id=0, use_visual=True)\n",
"\n",
"# Examine environment parameters\n",

"cell_type": "markdown",
"metadata": {},
"source": [
"### 3. Examine the observation and state spaces\n",
"### 4. Examine the observation and state spaces\n",
"We can reset the environment to be provided with an initial observation of the environment."
]
},

"cell_type": "markdown",
"metadata": {},
"source": [
"### 4. Take random actions in the environment\n",
"### 5. Take random actions in the environment\n",
"Once we restart an environment, we can step the environment forward and provide actions to all of the agents within the environment. Here we simply choose random actions using the `env.action_space.sample()` function.\n",
"\n",
"Once this cell is executed, 10 messages will be printed that detail how much reward will be accumulated for the next 10 episodes. The Unity environment will then pause, waiting for further signals telling it what to do next. Thus, not seeing any animation is expected when running this cell."

"cell_type": "markdown",
"metadata": {},
"source": [
"### 5. Close the environment when finished\n",
"### 6. Close the environment when finished\n",
"When we are finished using an environment, we can close it with the function below."
]
},

27
notebooks/getting-started.ipynb


"source": [
"### 1. Set environment parameters\n",
"\n",
"Be sure to set `env_name` to the name of the Unity environment file you want to launch. Ensure that the environment build is in `../envs`."
"Be sure to set `env_name` to the name of the Unity environment file you want to launch. "
]
},
{

"outputs": [],
"source": [
"env_name = \"../envs/GridWorld\" # Name of the Unity environment binary to launch\n",
"train_mode = True # Whether to run the environment in training or inference mode"
"env_name = \"../envs/GridWorld\" # Name of the Unity environment binary to launch"
]
},
{

"outputs": [],
"source": [
"engine_configuration_channel = EngineConfigurationChannel()\n",
"env = UnityEnvironment(base_port = UnityEnvironment.DEFAULT_EDITOR_PORT, file_name=env_name, side_channels = [engine_configuration_channel])\n",
"env = UnityEnvironment(file_name=env_name, side_channels = [engine_configuration_channel])\n",
"\n",
"#Reset the environment\n",
"env.reset()\n",

"# Examine the number of observations per Agent\n",
"print(\"Number of observations : \", len(group_spec.observation_shapes))\n",
"\n",
"# Examine the state space for the first observation for all agents\n",
"print(\"Agent state looks like: \\n{}\".format(step_result.obs[0]))\n",
"\n",
"# Examine the state space for the first observation for the first agent\n",
"print(\"Agent state looks like: \\n{}\".format(step_result.obs[0][0]))\n",
"\n",
"# Is there a visual observation ?\n",
"vis_obs = any([len(shape) == 3 for shape in group_spec.observation_shapes])\n",
"print(\"Is there a visual observation ?\", vis_obs)\n",

" vis_obs_index = next(i for i,v in enumerate(group_spec.observation_shapes) if len(v) == 3)\n",
" print(\"Agent visual observation look like:\")\n",
" print(\"Agent visual observation looks like:\")\n",
" plt.imshow(obs[0,:,:,:])\n"
" plt.imshow(obs[0,:,:,:])\n",
"else:\n",
" # Examine the state space for the first observation for the first agent\n",
" print(\"First Agent observation looks like: \\n{}\".format(step_result.obs[0][0]))"
]
},
{

"source": [
"env.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {

8
com.unity.ml-agents/Runtime/Communicator/ICommunicator.cs


/// <summary>
/// Registers a new Brain to the Communicator.
/// </summary>
/// <param name="name">The name or key uniquely identifying the Brain</param>
/// <param name="brainParameters">The Parameters for the Brain being registered</param>
/// <param name="name">The name or key uniquely identifying the Brain.</param>
/// <param name="brainParameters">The Parameters for the Brain being registered.</param>
void SubscribeBrain(string name, BrainParameters brainParameters);
/// <summary>

/// <summary>
/// Gets the AgentActions based on the batching key.
/// </summary>
/// <param name="key">A key to identify which behavior actions to get</param>
/// <param name="agentId">A key to identify which Agent actions to get</param>
/// <param name="key">A key to identify which behavior actions to get.</param>
/// <param name="agentId">A key to identify which Agent actions to get.</param>
/// <returns></returns>
float[] GetActions(string key, int agentId);

40
.yamato/protobuf-generation-test.yml


test_mac_protobuf_generation:
name: Protobuf Generation Tests
agent:
type: Unity::VM::osx
image: ml-agents/ml-agents-bokken-mac:0.1.4-492264
flavor: b1.small
variables:
GRPC_VERSION: "1.14.1"
CS_PROTO_PATH: "com.unity.ml-agents/Runtime/Grpc/CommunicatorObjects"
commands:
- |
brew install nuget
nuget install Grpc.Tools -Version $GRPC_VERSION -OutputDirectory protobuf-definitions/
python3 -m venv venv
. venv/bin/activate
pip install --upgrade pip
pip install grpcio-tools==1.13.0 --progress-bar=off
pip install mypy-protobuf==1.16.0 --progress-bar=off
cd protobuf-definitions
chmod +x Grpc.Tools.$GRPC_VERSION/tools/macosx_x64/protoc
chmod +x Grpc.Tools.$GRPC_VERSION/tools/macosx_x64/grpc_csharp_plugin
COMPILER=Grpc.Tools.$GRPC_VERSION/tools/macosx_x64 ./make.sh
mkdir -p artifacts
touch artifacts/proto.patch
git diff --exit-code -- :/ ":(exclude,top)$CS_PROTO_PATH/*.meta" \
|| { GIT_ERR=$?; echo "protobufs need to be regenerated, apply the patch uploaded to artifacts."; \
echo "Apply the patch with the command 'git apply proto.patch'"; \
git diff -- :/ ":(exclude,top)$CS_PROTO_PATH/*.meta" > artifacts/proto.patch; exit $GIT_ERR; }
triggers:
changes:
only:
- "protobuf-definitions/**"
- ".yamato/protobuf-generation-test.yml"
except:
- "protobuf-definitions/*.md"
- "protobuf-definitions/**/*.md"
artifacts:
dist:
paths:
- "artifacts/*"

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


using UnityEngine;
using UnityEditor;
using Barracuda;
namespace MLAgents
{
internal class RayPerceptionSensorComponentBaseEditor : Editor
{
bool m_RequireSensorUpdate;
protected void OnRayPerceptionInspectorGUI(bool is3d)
{
var so = serializedObject;
so.Update();
// Drawing the RayPerceptionSensorComponent
EditorGUI.BeginChangeCheck();
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(so.FindProperty("m_SensorName"), true);
// Because the number of rays and the tags affect the observation shape,
// they are not editable during play mode.
EditorGUI.BeginDisabledGroup(Application.isPlaying);
{
EditorGUILayout.PropertyField(so.FindProperty("m_DetectableTags"), true);
EditorGUILayout.PropertyField(so.FindProperty("m_RaysPerDirection"), true);
}
EditorGUI.EndDisabledGroup();
EditorGUILayout.PropertyField(so.FindProperty("m_MaxRayDegrees"), true);
EditorGUILayout.PropertyField(so.FindProperty("m_SphereCastRadius"), true);
EditorGUILayout.PropertyField(so.FindProperty("m_RayLength"), true);
EditorGUILayout.PropertyField(so.FindProperty("m_RayLayerMask"), true);
// Because the number of observation stacks affects the observation shape,
// it is not editable during play mode.
EditorGUI.BeginDisabledGroup(Application.isPlaying);
{
EditorGUILayout.PropertyField(so.FindProperty("m_ObservationStacks"), true);
}
EditorGUI.EndDisabledGroup();
if (is3d)
{
EditorGUILayout.PropertyField(so.FindProperty("m_StartVerticalOffset"), true);
EditorGUILayout.PropertyField(so.FindProperty("m_EndVerticalOffset"), true);
}
EditorGUILayout.PropertyField(so.FindProperty("rayHitColor"), true);
EditorGUILayout.PropertyField(so.FindProperty("rayMissColor"), true);
EditorGUI.indentLevel--;
if (EditorGUI.EndChangeCheck())
{
m_RequireSensorUpdate = true;
}
UpdateSensorIfDirty();
so.ApplyModifiedProperties();
}
void UpdateSensorIfDirty()
{
if (m_RequireSensorUpdate)
{
var sensorComponent = serializedObject.targetObject as RayPerceptionSensorComponentBase;
sensorComponent?.UpdateSensor();
m_RequireSensorUpdate = false;
}
}
}
[CustomEditor(typeof(RayPerceptionSensorComponent2D))]
[CanEditMultipleObjects]
internal class RayPerceptionSensorComponent2DEditor : RayPerceptionSensorComponentBaseEditor
{
public override void OnInspectorGUI()
{
OnRayPerceptionInspectorGUI(false);
}
}
[CustomEditor(typeof(RayPerceptionSensorComponent3D))]
[CanEditMultipleObjects]
internal class RayPerceptionSensorComponent3DEditor : RayPerceptionSensorComponentBaseEditor
{
public override void OnInspectorGUI()
{
OnRayPerceptionInspectorGUI(true);
}
}
}

11
com.unity.ml-agents/Editor/RayPerceptionSensorComponentBaseEditor.cs.meta


fileFormatVersion: 2
guid: c0182483e53c24d0e9f264f711ed89a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
com.unity.ml-agents/Runtime/Communicator.meta


fileFormatVersion: 2
guid: 432bb08962b3944c6964c0db6af43669
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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


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

11
com.unity.ml-agents/Runtime/Grpc/AssemblyInfo.cs.meta


fileFormatVersion: 2
guid: 54959ce8e2e574f09b91f80a516acee3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

16
com.unity.ml-agents/Runtime/Grpc/Unity.ML-Agents.CommunicatorObjects.asmdef


{
"name": "Unity.ML-Agents.CommunicatorObjects",
"references": [],
"optionalUnityReferences": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [
"System.IO.Abstractions.dll",
"Google.Protobuf.dll",
"Grpc.Core.dll"
],
"autoReferenced": true,
"defineConstraints": []
}

7
com.unity.ml-agents/Runtime/Grpc/Unity.ML-Agents.CommunicatorObjects.asmdef.meta


fileFormatVersion: 2
guid: 61c5b659adf544b4baf3eef86248e13a
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

381
com.unity.ml-agents/Third Party Notices.md


This package contains third-party software components governed by the license(s) indicated below:
---------
Component Name: System.Buffers.dll
License Type: MIT
The MIT License (MIT)
Copyright (c) .NET Foundation and Contributors
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------
Component Name: System.Numerics.Vectors.dll
License Type: MIT
The MIT License (MIT)
Copyright (c) .NET Foundation and Contributors
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------
Component Name: System.Runtime.CompilerServices.Unsafe
License Type: MIT
The MIT License (MIT)
Copyright (c) .NET Foundation and Contributors
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------
Component Name: System.Memory.dll
License Type: MIT
The MIT License (MIT)
Copyright (c) .NET Foundation and Contributors
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------
Component Name: System.IO.Abstractions
License Type: MIT
The MIT License (MIT)
Copyright (c) Tatham Oddie and Contributors
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------
Component Name: System.Interactive.Async.dll
License Type: Apache-2.0
Copyright (c) .NET Foundation and Contributors
All Rights Reserved
Licensed under the Apache License, Version 2.0 (the "License"); you
may not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing permissions
and limitations under the License.
---------
Component Name: Grpc
License Type: Apache-2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

7
com.unity.ml-agents/Third Party Notices.md.meta


fileFormatVersion: 2
guid: 3fb7f1407083340b8921a0520b2d8870
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

/com.unity.ml-agents/Runtime/Grpc/GrpcExtensions.cs.meta → /com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs.meta

/com.unity.ml-agents/Runtime/Grpc/RpcCommunicator.cs.meta → /com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs.meta

/com.unity.ml-agents/Runtime/Grpc/GrpcExtensions.cs → /com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs

/com.unity.ml-agents/Runtime/Grpc/RpcCommunicator.cs → /com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs

/com.unity.ml-agents/Runtime/ICommunicator.cs.meta → /com.unity.ml-agents/Runtime/Communicator/ICommunicator.cs.meta

/com.unity.ml-agents/Runtime/ICommunicator.cs → /com.unity.ml-agents/Runtime/Communicator/ICommunicator.cs

正在加载...
取消
保存