diff --git a/DevProject/Packages/packages-lock.json b/DevProject/Packages/packages-lock.json index 3ceb180eeb..c8f02170ac 100644 --- a/DevProject/Packages/packages-lock.json +++ b/DevProject/Packages/packages-lock.json @@ -31,7 +31,7 @@ "url": "https://artifactory.prd.cds.internal.unity3d.com/artifactory/api/npm/upm-candidates" }, "com.unity.barracuda": { - "version": "1.3.0-preview", + "version": "1.3.1-preview", "depth": 1, "source": "registry", "dependencies": { @@ -108,7 +108,7 @@ "depth": 0, "source": "local", "dependencies": { - "com.unity.barracuda": "1.3.0-preview", + "com.unity.barracuda": "1.3.1-preview", "com.unity.modules.imageconversion": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0", "com.unity.modules.physics": "1.0.0", @@ -121,7 +121,7 @@ "depth": 0, "source": "local", "dependencies": { - "com.unity.ml-agents": "1.7.2-preview" + "com.unity.ml-agents": "1.8.0-preview" } }, "com.unity.multiplayer-hlapi": { diff --git a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs index 46cc297ae7..e2edd19d86 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs @@ -2,6 +2,7 @@ using Unity.MLAgents.Actuators; using UnityEngine; using UnityEngine.InputSystem; +using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.LowLevel; namespace Unity.MLAgents.Extensions.Input @@ -26,11 +27,11 @@ public ActionSpec GetActionSpecForInputAction(InputAction action) } /// TODO again this might need to be more nuanced for things like continuous buttons. - /// - public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) + /// + public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) { var val = actionBuffers.DiscreteActions[0]; - InputSystem.QueueDeltaStateEvent(control, (byte)val); + ((ButtonControl)control).WriteValueIntoEvent((float)val, eventPtr); } /// > diff --git a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs index 9b2f58e74a..7fd143b570 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs @@ -1,6 +1,7 @@ #if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER using Unity.MLAgents.Actuators; using UnityEngine.InputSystem; +using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.LowLevel; namespace Unity.MLAgents.Extensions.Input @@ -16,11 +17,11 @@ public ActionSpec GetActionSpecForInputAction(InputAction action) return ActionSpec.MakeContinuous(1); } - /// - public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) + /// + public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) { var val = actionBuffers.ContinuousActions[0]; - InputSystem.QueueDeltaStateEvent(control,(double)val); + ((DoubleControl)control).WriteValueIntoEvent((double)val, eventPtr); } /// diff --git a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs index c39960cb12..ea77bb5413 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs @@ -16,11 +16,11 @@ public ActionSpec GetActionSpecForInputAction(InputAction action) return ActionSpec.MakeContinuous(1); } - /// - public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) + /// + public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) { var val = actionBuffers.ContinuousActions[0]; - InputSystem.QueueDeltaStateEvent(control, val); + control.WriteValueIntoEvent(val, eventPtr); } /// diff --git a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs index a7501aa987..bd920ab169 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs @@ -17,11 +17,11 @@ public ActionSpec GetActionSpecForInputAction(InputAction action) return ActionSpec.MakeDiscrete(2); } - /// - public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) + /// + public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) { var val = actionBuffers.DiscreteActions[0]; - InputSystem.QueueDeltaStateEvent(control, val); + control.WriteValueIntoEvent(val, eventPtr); } /// diff --git a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs index 9c3e4b2620..95e7ed7124 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs @@ -3,6 +3,7 @@ using Unity.MLAgents.Actuators; using UnityEngine; using UnityEngine.InputSystem; +using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.LowLevel; namespace Unity.MLAgents.Extensions.Input @@ -19,15 +20,15 @@ public ActionSpec GetActionSpecForInputAction(InputAction action) return ActionSpec.MakeContinuous(2); } - /// - public void QueueInputEventForAction(InputAction action, + /// + public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) { var x = actionBuffers.ContinuousActions[0]; var y = actionBuffers.ContinuousActions[1]; - InputSystem.QueueDeltaStateEvent(control, new Vector2(x, y)); + control.WriteValueIntoEvent(new Vector2(x, y), eventPtr); } /// diff --git a/com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs b/com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs index 173db482ae..d61aaa8f3b 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs @@ -2,6 +2,7 @@ using System; using Unity.MLAgents.Actuators; using UnityEngine.InputSystem; +using UnityEngine.InputSystem.LowLevel; namespace Unity.MLAgents.Extensions.Input { @@ -22,11 +23,12 @@ public interface IRLActionInputAdaptor /// /// Translates data from the object to the . /// + /// The Event pointer to write to. /// The action associated with this adaptor. /// The control which will write the event to the . /// The associated with this action and adaptor pair. /// The object to read from. - void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers); + void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers); /// /// Writes data from the to the . diff --git a/com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs b/com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs index 9b9cea1dba..0050bf9cca 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs @@ -19,6 +19,7 @@ public class InputActionActuator : IActuator, IHeuristicProvider, IBuiltInActuat readonly BehaviorParameters m_BehaviorParameters; readonly InputAction m_Action; readonly IRLActionInputAdaptor m_InputAdaptor; + InputActuatorEventContext m_InputActuatorEventContext; InputDevice m_Device; InputControl m_Control; @@ -34,14 +35,17 @@ public class InputActionActuator : IActuator, IHeuristicProvider, IBuiltInActuat /// via the . /// The that will convert data between ML-Agents /// and the . + /// The object that will provide the event ptr to write to. public InputActionActuator(InputDevice inputDevice, BehaviorParameters behaviorParameters, InputAction action, - IRLActionInputAdaptor adaptor) + IRLActionInputAdaptor adaptor, + InputActuatorEventContext inputActuatorEventContext) { m_BehaviorParameters = behaviorParameters; Name = $"InputActionActuator-{action.name}"; m_Action = action; m_InputAdaptor = adaptor; + m_InputActuatorEventContext = inputActuatorEventContext; ActionSpec = adaptor.GetActionSpecForInputAction(m_Action); m_Device = inputDevice; m_Control = m_Device?.GetChildControl(m_Action.name); @@ -53,7 +57,11 @@ public void OnActionReceived(ActionBuffers actionBuffers) Profiler.BeginSample("InputActionActuator.OnActionReceived"); if (!m_BehaviorParameters.IsInHeuristicMode()) { - m_InputAdaptor.QueueInputEventForAction(m_Action, m_Control, ActionSpec, actionBuffers); + using (m_InputActuatorEventContext.GetEventForFrame(out var eventPtr)) + { + m_InputAdaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, ActionSpec, actionBuffers); + } + } Profiler.EndSample(); } diff --git a/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs b/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs index c3fed4974c..665d6844f9 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs +++ b/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs @@ -1,12 +1,14 @@ #if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER using System; using System.Collections.Generic; +using Unity.Collections; using Unity.MLAgents.Actuators; using Unity.MLAgents.Policies; using UnityEngine; using UnityEngine.Assertions; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; +using UnityEngine.InputSystem.LowLevel; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.Utilities; #if UNITY_EDITOR @@ -57,9 +59,18 @@ public override ActionSpec ActionSpec get { #if UNITY_EDITOR - FindNeededComponents(); - var actuators = CreateActuatorsFromMap(m_InputAsset.FindActionMap(m_PlayerInput.defaultActionMap), m_BehaviorParameters, null); - m_ActionSpec = CombineActuatorActionSpecs(actuators); + if (!EditorApplication.isPlaying && m_ActionSpec.NumContinuousActions == 0 + && m_ActionSpec.BranchSizes == null + || m_ActionSpec.BranchSizes.Length == 0) + { + FindNeededComponents(); + var actuators = CreateActuatorsFromMap(m_InputAsset.FindActionMap(m_PlayerInput.defaultActionMap), + m_BehaviorParameters, + null, + InputActuatorEventContext.s_EditorContext); + m_ActionSpec = CombineActuatorActionSpecs(actuators); + + } #endif return m_ActionSpec; } @@ -119,7 +130,8 @@ public override IActuator[] CreateActuators() RegisterLayoutBuilder(inputActionMap, m_LayoutName); m_Device = InputSystem.AddDevice(m_LayoutName); - m_Actuators = CreateActuatorsFromMap(inputActionMap, m_BehaviorParameters, m_Device); + var context = new InputActuatorEventContext(inputActionMap.actions.Count, m_Device); + m_Actuators = CreateActuatorsFromMap(inputActionMap, m_BehaviorParameters, m_Device, context); UpdateDeviceBinding(m_BehaviorParameters.IsInHeuristicMode()); inputActionMap.Enable(); @@ -141,7 +153,8 @@ static ActionSpec CombineActuatorActionSpecs(IActuator[] actuators) internal static IActuator[] CreateActuatorsFromMap(InputActionMap inputActionMap, BehaviorParameters behaviorParameters, - InputDevice inputDevice) + InputDevice inputDevice, + InputActuatorEventContext context) { var actuators = new IActuator[inputActionMap.actions.Count]; for (var i = 0; i < inputActionMap.actions.Count; i++) @@ -149,7 +162,7 @@ internal static IActuator[] CreateActuatorsFromMap(InputActionMap inputActionMap var action = inputActionMap.actions[i]; var actionLayout = InputSystem.LoadLayout(action.expectedControlType); var adaptor = (IRLActionInputAdaptor)Activator.CreateInstance(controlTypeToAdaptorType[actionLayout.type]); - actuators[i] = new InputActionActuator(inputDevice, behaviorParameters, action, adaptor); + actuators[i] = new InputActionActuator(inputDevice, behaviorParameters, action, adaptor, context); // Reasonably, the input system starts adding numbers after the first none numbered name // is added. So for device ID of 0, we use the empty string in the path. @@ -158,6 +171,7 @@ internal static IActuator[] CreateActuatorsFromMap(InputActionMap inputActionMap action.interactions, action.processors, mlAgentsControlSchemeName); + action.bindingMask = InputBinding.MaskByGroup(mlAgentsControlSchemeName); } return actuators; } @@ -326,6 +340,43 @@ internal void CleanupActionAsset() m_BehaviorParameters = null; m_Device = null; } + + int m_ActuatorsWrittenToEvent; + NativeArray m_InputBufferForFrame; + InputEventPtr m_InputEventPtrForFrame; + public InputEventPtr GetEventForFrame() + { +#if UNITY_EDITOR + if (!EditorApplication.isPlaying) + { + return new InputEventPtr(); + } +#endif + if (m_ActuatorsWrittenToEvent % m_Actuators.Length == 0 || !m_InputEventPtrForFrame.valid) + { + m_ActuatorsWrittenToEvent = 0; + m_InputEventPtrForFrame = new InputEventPtr(); + m_InputBufferForFrame = StateEvent.From(m_Device, out m_InputEventPtrForFrame); + } + + return m_InputEventPtrForFrame; + } + + public void EventProcessedInFrame() + { +#if UNITY_EDITOR + if (!EditorApplication.isPlaying) + { + return; + } +#endif + m_ActuatorsWrittenToEvent++; + if (m_ActuatorsWrittenToEvent == m_Actuators.Length && m_InputEventPtrForFrame.valid) + { + InputSystem.QueueEvent(m_InputEventPtrForFrame); + m_InputBufferForFrame.Dispose(); + } + } } } #endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER diff --git a/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs b/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs new file mode 100644 index 0000000000..de8463fd18 --- /dev/null +++ b/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs @@ -0,0 +1,81 @@ +#if MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER +using System; +using Unity.Collections; +using UnityEngine.InputSystem; +using UnityEngine.InputSystem.LowLevel; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace Unity.MLAgents.Extensions.Input +{ + /// + /// This interface is passed to InputActionActuators to allow them to write to InputEvents. + /// The way this interface should be used is to request the by calling + /// then call before returning from + /// + public class InputActuatorEventContext : IDisposable + { + + /// + /// The number of times to allow the use of an event before queuing it in the InputSystem. + /// + public readonly int NumTimesToProcess; + public readonly InputDevice InputDevice; + NativeArray m_EventBuffer; + InputEventPtr m_Ptr; + int m_Count; + +#if UNITY_EDITOR + public static InputActuatorEventContext s_EditorContext = new InputActuatorEventContext(); +#endif + + public InputActuatorEventContext(int numTimesToProcess = 1, InputDevice device = null) + { + NumTimesToProcess = numTimesToProcess; + InputDevice = device; + m_Count = 0; + m_Ptr = new InputEventPtr(); + m_EventBuffer = new NativeArray(); + } + + /// + /// Returns the to write to for the current frame. + /// + /// The to write to for the current frame. + public IDisposable GetEventForFrame(out InputEventPtr eventPtr) + { +#if UNITY_EDITOR + if (!EditorApplication.isPlaying) + { + eventPtr = new InputEventPtr(); + } +#endif + if (m_Count % NumTimesToProcess == 0) + { + m_Count = 0; + m_EventBuffer = StateEvent.From(InputDevice, out m_Ptr); + } + eventPtr = m_Ptr; + return this; + } + + public void Dispose() + { +#if UNITY_EDITOR + if (!EditorApplication.isPlaying) + { + return; + } +#endif + m_Count++; + if (m_Count == NumTimesToProcess && m_Ptr.valid) + { + InputSystem.QueueEvent(m_Ptr); + m_EventBuffer.Dispose(); + } + + } + } +} +#endif // MLA_INPUT_SYSTEM && UNITY_2019_4_OR_NEWER diff --git a/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs.meta b/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs.meta new file mode 100644 index 0000000000..bc7c18aeab --- /dev/null +++ b/com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 76c31df314114ec6bf104e8db4e5568b +timeCreated: 1614892215 \ No newline at end of file diff --git a/com.unity.ml-agents.extensions/Runtime/Input/Unity.ML-Agents.Extensions.Input.asmdef b/com.unity.ml-agents.extensions/Runtime/Input/Unity.ML-Agents.Extensions.Input.asmdef index c1cdc58563..ccc3b6bf91 100644 --- a/com.unity.ml-agents.extensions/Runtime/Input/Unity.ML-Agents.Extensions.Input.asmdef +++ b/com.unity.ml-agents.extensions/Runtime/Input/Unity.ML-Agents.Extensions.Input.asmdef @@ -15,9 +15,9 @@ "versionDefines": [ { "name": "com.unity.inputsystem", - "expression": "1.1.0-preview", + "expression": "1.1.0-preview.3", "define": "MLA_INPUT_SYSTEM" } ], "noEngineReferences": false -} +} \ No newline at end of file diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs index d2a613f389..26378f170b 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs @@ -51,7 +51,11 @@ public void TestGenerateActionSpec() public void TestQueueEvent() { var actionBuffers = new ActionBuffers(ActionSegment.Empty, new ActionSegment(new[] { 1 })); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var val = m_Action.ReadValue(); Assert.IsTrue(Mathf.Approximately(1f, val)); @@ -61,7 +65,11 @@ public void TestQueueEvent() public void TestWriteToHeuristic() { var actionBuffers = new ActionBuffers(ActionSegment.Empty, new ActionSegment(new[] { 1 })); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var buffer = new ActionBuffers(ActionSegment.Empty, new ActionSegment(new[] { 1 })); m_Adaptor.WriteToHeuristic(m_Action, buffer); diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs index 4f52a075d3..8beeb08727 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs @@ -50,7 +50,11 @@ public void TestGenerateActionSpec() public void TestQueueEvent() { var actionBuffers = new ActionBuffers(new ActionSegment(new[] { 1f }), ActionSegment.Empty); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); Assert.IsTrue(Mathf.Approximately(1f, (float)m_Action.ReadValue())); } @@ -59,7 +63,11 @@ public void TestQueueEvent() public void TestWriteToHeuristic() { var actionBuffers = new ActionBuffers(new ActionSegment(new[] { 1f }), ActionSegment.Empty); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var buffer = new ActionBuffers(new ActionSegment(new[] { 1f }), ActionSegment.Empty); m_Adaptor.WriteToHeuristic(m_Action, buffer); diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs index 04ef1ea09d..7b6cb400e0 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs @@ -50,7 +50,11 @@ public void TestGenerateActionSpec() public void TestQueueEvent() { var actionBuffers = new ActionBuffers(new ActionSegment(new[] { 1f }), ActionSegment.Empty); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var val = m_Action.ReadValue(); Assert.IsTrue(Mathf.Approximately(1f, val)); @@ -60,7 +64,11 @@ public void TestQueueEvent() public void TestWriteToHeuristic() { var actionBuffers = new ActionBuffers(new ActionSegment(new[] { 1f }), ActionSegment.Empty); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var buffer = new ActionBuffers(new ActionSegment(new[] { 1f }), ActionSegment.Empty); m_Adaptor.WriteToHeuristic(m_Action, buffer); diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs index 3655bc31d0..905586aeb9 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs @@ -52,7 +52,11 @@ public void TestGenerateActionSpec() public void TestQueueEvent() { var actionBuffers = new ActionBuffers(ActionSegment.Empty, new ActionSegment(new[] { 1 })); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var val = m_Action.ReadValue(); Assert.IsTrue(val == 1); @@ -62,7 +66,11 @@ public void TestQueueEvent() public void TestWriteToHeuristic() { var actionBuffers = new ActionBuffers(ActionSegment.Empty, new ActionSegment(new[] { 1 })); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var buffer = new ActionBuffers(ActionSegment.Empty, new ActionSegment(new int[1])); m_Adaptor.WriteToHeuristic(m_Action, buffer); diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs index e699c2da96..6002312512 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs @@ -50,7 +50,11 @@ public void TestGenerateActionSpec() public void TestQueueEvent() { var actionBuffers = new ActionBuffers(new ActionSegment(new[] { 0f, 1f }), ActionSegment.Empty); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var val = m_Action.ReadValue(); Assert.IsTrue(Mathf.Approximately(0f, val.x)); @@ -61,7 +65,11 @@ public void TestQueueEvent() public void TestWriteToHeuristic() { var actionBuffers = new ActionBuffers(new ActionSegment(new[] { 0f, 1f }), ActionSegment.Empty); - m_Adaptor.QueueInputEventForAction(m_Action, m_Control, new ActionSpec(), actionBuffers); + var context = new InputActuatorEventContext(1, m_Device); + using (context.GetEventForFrame(out var eventPtr)) + { + m_Adaptor.WriteToInputEventForAction(eventPtr, m_Action, m_Control, new ActionSpec(), actionBuffers); + } InputSystem.Update(); var buffer = new ActionBuffers(new ActionSegment(new float[2]), ActionSegment.Empty); m_Adaptor.WriteToHeuristic(m_Action, buffer); diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs b/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs index d5f2f15ce4..514bc48df2 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs @@ -6,12 +6,13 @@ using Unity.MLAgents.Policies; using UnityEngine; using UnityEngine.InputSystem; +using UnityEngine.InputSystem.LowLevel; namespace Unity.MLAgents.Extensions.Tests.Runtime.Input { class TestAdaptor : IRLActionInputAdaptor { - public bool eventQueued; + public bool eventWritten; public bool writtenToHeuristic; public ActionSpec GetActionSpecForInputAction(InputAction action) @@ -19,9 +20,9 @@ public ActionSpec GetActionSpecForInputAction(InputAction action) return ActionSpec.MakeContinuous(1); } - public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) + public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers) { - eventQueued = true; + eventWritten = true; } public void WriteToHeuristic(InputAction action, in ActionBuffers actionBuffers) @@ -31,7 +32,7 @@ public void WriteToHeuristic(InputAction action, in ActionBuffers actionBuffers) public void Reset() { - eventQueued = false; + eventWritten = false; writtenToHeuristic = false; } } @@ -50,7 +51,7 @@ public void Setup() m_BehaviorParameters = go.AddComponent(); var action = new InputAction("action"); m_Adaptor = new TestAdaptor(); - m_Actuator = new InputActionActuator(null, m_BehaviorParameters, action, m_Adaptor); + m_Actuator = new InputActionActuator(null, m_BehaviorParameters, action, m_Adaptor, new InputActuatorEventContext(1, InputSystem.AddDevice())); } [Test] @@ -59,18 +60,18 @@ public void TestOnActionReceived() m_BehaviorParameters.BehaviorType = BehaviorType.HeuristicOnly; m_Actuator.OnActionReceived(new ActionBuffers()); m_Actuator.Heuristic(new ActionBuffers()); - Assert.IsFalse(m_Adaptor.eventQueued); + Assert.IsFalse(m_Adaptor.eventWritten); Assert.IsTrue(m_Adaptor.writtenToHeuristic); m_Adaptor.Reset(); m_BehaviorParameters.BehaviorType = BehaviorType.Default; m_Actuator.OnActionReceived(new ActionBuffers()); - Assert.IsFalse(m_Adaptor.eventQueued); + Assert.IsFalse(m_Adaptor.eventWritten); m_Adaptor.Reset(); m_BehaviorParameters.Model = ScriptableObject.CreateInstance(); m_Actuator.OnActionReceived(new ActionBuffers()); - Assert.IsTrue(m_Adaptor.eventQueued); + Assert.IsTrue(m_Adaptor.eventWritten); m_Adaptor.Reset(); Assert.AreEqual(m_Actuator.Name, "InputActionActuator-action"); diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActuatorComponentTests.cs b/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActuatorComponentTests.cs index 459a4ba61c..35bc52254f 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActuatorComponentTests.cs +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActuatorComponentTests.cs @@ -81,7 +81,7 @@ public void InputActuatorComponentTestGenerateActuatorsFromAsset() var device = InputSystem.AddDevice("TestLayout"); - var actuators = InputActuatorComponent.CreateActuatorsFromMap(inputActionMap, m_BehaviorParameters, device); + var actuators = InputActuatorComponent.CreateActuatorsFromMap(inputActionMap, m_BehaviorParameters, device, new InputActuatorEventContext()); Assert.IsTrue(actuators.Length == 2); Assert.IsTrue(actuators[0].ActionSpec.Equals(ActionSpec.MakeContinuous(2))); Assert.IsTrue(actuators[1].ActionSpec.NumDiscreteActions == 1); diff --git a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Unity.ML-Agents.Extensions.Input.Tests.Runtime.asmdef b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Unity.ML-Agents.Extensions.Input.Tests.Runtime.asmdef index 40056f274b..f028c5ff7c 100644 --- a/com.unity.ml-agents.extensions/Tests/Runtime/Input/Unity.ML-Agents.Extensions.Input.Tests.Runtime.asmdef +++ b/com.unity.ml-agents.extensions/Tests/Runtime/Input/Unity.ML-Agents.Extensions.Input.Tests.Runtime.asmdef @@ -23,7 +23,7 @@ "versionDefines": [ { "name": "com.unity.inputsystem", - "expression": "1.1.0", + "expression": "1.1.0-preview.3", "define": "MLA_INPUT_TESTS" } ], diff --git a/com.unity.ml-agents/CHANGELOG.md b/com.unity.ml-agents/CHANGELOG.md index 97d41000d6..6f829aa9df 100755 --- a/com.unity.ml-agents/CHANGELOG.md +++ b/com.unity.ml-agents/CHANGELOG.md @@ -19,9 +19,10 @@ and this project adheres to - The `cattrs` version dependency was updated to allow `>=1.1.0` on Python 3.8 or higher. (#4821) ### Bug Fixes -#### com.unity.ml-agents (C#) +#### com.unity.ml-agents / com.unity.ml-agents.extensions (C#) #### ml-agents / ml-agents-envs / gym-unity (Python) - An issue that caused `GAIL` to fail for environments where agents can terminate episodes by self-sacrifice has been fixed. (#4971) +- Fix an issue where queuing InputEvents overwrote data from previous events in the same frame. ## [1.8.0-preview] - 2021-02-17 ### Major Changes