diff --git a/com.unity.ml-agents/Runtime/Academy.cs b/com.unity.ml-agents/Runtime/Academy.cs
index 9d64b35e7f..a3d540e79c 100644
--- a/com.unity.ml-agents/Runtime/Academy.cs
+++ b/com.unity.ml-agents/Runtime/Academy.cs
@@ -422,12 +422,7 @@ void InitializeEnvironment()
var port = ReadPortFromArgs();
if (port > 0)
{
- Communicator = new RpcCommunicator(
- new CommunicatorInitParameters
- {
- port = port
- }
- );
+ Communicator = CommunicatorFactory.Create();
}
if (Communicator != null)
@@ -438,6 +433,7 @@ void InitializeEnvironment()
bool initSuccessful = false;
var communicatorInitParams = new CommunicatorInitParameters
{
+ port = port,
unityCommunicationVersion = k_ApiVersion,
unityPackageVersion = k_PackageVersion,
name = "AcademySingleton",
diff --git a/com.unity.ml-agents/Runtime/Communicator/CommunicatorFactory.cs b/com.unity.ml-agents/Runtime/Communicator/CommunicatorFactory.cs
new file mode 100644
index 0000000000..d6042863a4
--- /dev/null
+++ b/com.unity.ml-agents/Runtime/Communicator/CommunicatorFactory.cs
@@ -0,0 +1,35 @@
+namespace Unity.MLAgents
+{
+ ///
+ /// Factory class for an ICommunicator instance. This is used to the at startup.
+ /// By default, on desktop platforms, an ICommunicator will be created and attempt to connect
+ /// to a trainer. This behavior can be prevented by setting to false
+ /// *before* the is initialized.
+ ///
+ public static class CommunicatorFactory
+ {
+ static bool s_Enabled = true;
+
+ ///
+ /// Whether or not an ICommunicator instance will be created when the is initialized.
+ /// Changing this has no effect after the has already been initialized.
+ ///
+ public static bool Enabled
+ {
+ get => s_Enabled;
+ set => s_Enabled = value;
+ }
+
+ internal static ICommunicator Create()
+ {
+#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
+ if (s_Enabled)
+ {
+ return new RpcCommunicator();
+ }
+#endif
+ // Non-desktop or disabled
+ return null;
+ }
+ }
+}
diff --git a/com.unity.ml-agents/Runtime/Communicator/CommunicatorFactory.cs.meta b/com.unity.ml-agents/Runtime/Communicator/CommunicatorFactory.cs.meta
new file mode 100644
index 0000000000..1d208003e3
--- /dev/null
+++ b/com.unity.ml-agents/Runtime/Communicator/CommunicatorFactory.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 0b604cddc07e4484a2cdaba630a971ea
+timeCreated: 1613617949
\ No newline at end of file
diff --git a/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs b/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
index 6929ae6899..72ae82a0b8 100644
--- a/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
+++ b/com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
@@ -1,6 +1,5 @@
-# if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
+#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
using Grpc.Core;
-#endif
#if UNITY_EDITOR
using UnityEditor;
#endif
@@ -44,23 +43,17 @@ internal class RpcCommunicator : ICommunicator
Dictionary m_UnsentBrainKeys = new Dictionary();
-#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
/// The Unity to External client.
UnityToExternalProto.UnityToExternalProtoClient m_Client;
-#endif
- /// The communicator parameters sent at construction
- CommunicatorInitParameters m_CommunicatorInitParameters;
///
/// Initializes a new instance of the RPCCommunicator class.
///
- /// Communicator parameters.
- public RpcCommunicator(CommunicatorInitParameters communicatorInitParameters)
+ public RpcCommunicator()
{
- m_CommunicatorInitParameters = communicatorInitParameters;
}
- #region Initialization
+#region Initialization
internal static bool CheckCommunicationVersionsAreCompatible(
string unityCommunicationVersion,
@@ -110,6 +103,7 @@ public bool Initialize(CommunicatorInitParameters initParameters, out UnityRLIni
try
{
initializationInput = Initialize(
+ initParameters.port,
new UnityOutputProto
{
RlInitializationOutput = academyParameters
@@ -211,13 +205,10 @@ void UpdateEnvironmentWithInput(UnityRLInputProto rlInput)
SendCommandEvent(rlInput.Command);
}
- UnityInputProto Initialize(UnityOutputProto unityOutput, out UnityInputProto unityInput)
+ UnityInputProto Initialize(int port, UnityOutputProto unityOutput, out UnityInputProto unityInput)
{
-#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
m_IsOpen = true;
- var channel = new Channel(
- "localhost:" + m_CommunicatorInitParameters.port,
- ChannelCredentials.Insecure);
+ var channel = new Channel($"localhost:{port}", ChannelCredentials.Insecure);
m_Client = new UnityToExternalProto.UnityToExternalProtoClient(channel);
var result = m_Client.Exchange(WrapMessage(unityOutput, 200));
@@ -232,21 +223,17 @@ UnityInputProto Initialize(UnityOutputProto unityOutput, out UnityInputProto uni
QuitCommandReceived?.Invoke();
}
return result.UnityInput;
-#else
- throw new UnityAgentsException("You cannot perform training on this platform.");
-#endif
}
- #endregion
+#endregion
- #region Destruction
+#region Destruction
///
/// Close the communicator gracefully on both sides of the communication.
///
public void Dispose()
{
-#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
if (!m_IsOpen)
{
return;
@@ -261,15 +248,11 @@ public void Dispose()
{
// ignored
}
-#else
- throw new UnityAgentsException(
- "You cannot perform training on this platform.");
-#endif
}
- #endregion
+#endregion
- #region Sending Events
+#region Sending Events
void SendCommandEvent(CommandProto command)
{
@@ -296,9 +279,9 @@ void SendCommandEvent(CommandProto command)
}
}
- #endregion
+#endregion
- #region Sending and retreiving data
+#region Sending and retreiving data
public void DecideBatch()
{
@@ -447,7 +430,6 @@ public ActionBuffers GetActions(string behaviorName, int agentId)
/// The UnityOutput to be sent.
UnityInputProto Exchange(UnityOutputProto unityOutput)
{
-#if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX
if (!m_IsOpen)
{
return null;
@@ -500,10 +482,6 @@ UnityInputProto Exchange(UnityOutputProto unityOutput)
QuitCommandReceived?.Invoke();
return null;
}
-#else
- throw new UnityAgentsException(
- "You cannot perform training on this platform.");
-#endif
}
///
@@ -573,7 +551,7 @@ void UpdateSentActionSpec(UnityRLInitializationOutputProto output)
}
}
- #endregion
+#endregion
#if UNITY_EDITOR
///
@@ -592,3 +570,4 @@ void HandleOnPlayModeChanged(PlayModeStateChange state)
#endif
}
}
+#endif // UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_STANDALONE_LINUX