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