浏览代码

Fix issue with queuing input events that stomp on others. (#5034)

/release_14_branch
Christopher Goy 4 年前
当前提交
881b71be
共有 21 个文件被更改,包括 240 次插入50 次删除
  1. 6
      DevProject/Packages/packages-lock.json
  2. 7
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs
  3. 7
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs
  4. 6
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs
  5. 6
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs
  6. 7
      com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs
  7. 4
      com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs
  8. 12
      com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs
  9. 63
      com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs
  10. 4
      com.unity.ml-agents.extensions/Runtime/Input/Unity.ML-Agents.Extensions.Input.asmdef
  11. 12
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs
  12. 12
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs
  13. 12
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs
  14. 12
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs
  15. 12
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs
  16. 17
      com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs
  17. 2
      com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActuatorComponentTests.cs
  18. 2
      com.unity.ml-agents.extensions/Tests/Runtime/Input/Unity.ML-Agents.Extensions.Input.Tests.Runtime.asmdef
  19. 3
      com.unity.ml-agents/CHANGELOG.md
  20. 81
      com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs
  21. 3
      com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs.meta

6
DevProject/Packages/packages-lock.json


"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": {

"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",

"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": {

7
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/ButtonInputActionAdaptor.cs


using Unity.MLAgents.Actuators;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.LowLevel;
namespace Unity.MLAgents.Extensions.Input

}
/// TODO again this might need to be more nuanced for things like continuous buttons.
/// <inheritdoc cref="IRLActionInputAdaptor.QueueInputEventForAction"/>
public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToInputEventForAction"/>
public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
InputSystem.QueueDeltaStateEvent(control, (byte)val);
((ButtonControl)control).WriteValueIntoEvent((float)val, eventPtr);
}
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToHeuristic"/>>

7
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/DoubleInputActionAdaptor.cs


#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

return ActionSpec.MakeContinuous(1);
}
/// <inheritdoc cref="IRLActionInputAdaptor.QueueInputEventForAction"/>
public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToInputEventForAction"/>
public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
InputSystem.QueueDeltaStateEvent(control,(double)val);
((DoubleControl)control).WriteValueIntoEvent((double)val, eventPtr);
}
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToHeuristic"/>

6
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/FloatInputActionAdaptor.cs


return ActionSpec.MakeContinuous(1);
}
/// <inheritdoc cref="IRLActionInputAdaptor.QueueInputEventForAction"/>
public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToInputEventForAction"/>
public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
InputSystem.QueueDeltaStateEvent(control, val);
control.WriteValueIntoEvent(val, eventPtr);
}
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToHeuristic"/>

6
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/IntegerInputActionAdaptor.cs


return ActionSpec.MakeDiscrete(2);
}
/// <inheritdoc cref="IRLActionInputAdaptor.QueueInputEventForAction"/>
public void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToInputEventForAction"/>
public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers)
InputSystem.QueueDeltaStateEvent(control, val);
control.WriteValueIntoEvent(val, eventPtr);
}
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToHeuristic"/>

7
com.unity.ml-agents.extensions/Runtime/Input/Adaptors/Vector2InputActionAdaptor.cs


using Unity.MLAgents.Actuators;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.LowLevel;
namespace Unity.MLAgents.Extensions.Input

return ActionSpec.MakeContinuous(2);
}
/// <inheritdoc cref="IRLActionInputAdaptor.QueueInputEventForAction"/>
public void QueueInputEventForAction(InputAction action,
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToInputEventForAction"/>
public void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action,
InputControl control,
ActionSpec actionSpec,
in ActionBuffers actionBuffers)

InputSystem.QueueDeltaStateEvent(control, new Vector2(x, y));
control.WriteValueIntoEvent(new Vector2(x, y), eventPtr);
}
/// <inheritdoc cref="IRLActionInputAdaptor.WriteToHeuristic"/>

4
com.unity.ml-agents.extensions/Runtime/Input/IRLActionInputAdaptor.cs


using System;
using Unity.MLAgents.Actuators;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;
namespace Unity.MLAgents.Extensions.Input
{

/// <summary>
/// Translates data from the <see cref="ActionBuffers"/> object to the <see cref="InputSystem"/>.
/// </summary>
/// <param name="eventPtr">The Event pointer to write to.</param>
void QueueInputEventForAction(InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers);
void WriteToInputEventForAction(InputEventPtr eventPtr, InputAction action, InputControl control, ActionSpec actionSpec, in ActionBuffers actionBuffers);
/// <summary>
/// Writes data from the <paramref name="action"/> to the <paramref name="actionBuffers"/>.

12
com.unity.ml-agents.extensions/Runtime/Input/InputActionActuator.cs


readonly BehaviorParameters m_BehaviorParameters;
readonly InputAction m_Action;
readonly IRLActionInputAdaptor m_InputAdaptor;
InputActuatorEventContext m_InputActuatorEventContext;
InputDevice m_Device;
InputControl m_Control;

/// via the <see cref="IRLActionInputAdaptor"/>.</param>
/// <param name="adaptor">The <see cref="IRLActionInputAdaptor"/> that will convert data between ML-Agents
/// and the <see cref="InputSystem"/>.</param>
/// <param name="inputActuatorEventContext">The object that will provide the event ptr to write to.</param>
IRLActionInputAdaptor adaptor)
IRLActionInputAdaptor adaptor,
InputActuatorEventContext inputActuatorEventContext)
m_InputActuatorEventContext = inputActuatorEventContext;
ActionSpec = adaptor.GetActionSpecForInputAction(m_Action);
m_Device = inputDevice;
m_Control = m_Device?.GetChildControl(m_Action.name);

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();
}

63
com.unity.ml-agents.extensions/Runtime/Input/InputActuatorComponent.cs


#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.InputSystem.LowLevel;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.Utilities;
#if UNITY_EDITOR

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;
}

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();

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++)

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.

action.processors,
mlAgentsControlSchemeName);
action.bindingMask = InputBinding.MaskByGroup(mlAgentsControlSchemeName);
}
return actuators;
}

m_PlayerInput = null;
m_BehaviorParameters = null;
m_Device = null;
}
int m_ActuatorsWrittenToEvent;
NativeArray<byte> 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();
}
}
}
}

4
com.unity.ml-agents.extensions/Runtime/Input/Unity.ML-Agents.Extensions.Input.asmdef


"versionDefines": [
{
"name": "com.unity.inputsystem",
"expression": "1.1.0-preview",
"expression": "1.1.0-preview.3",
}
}

12
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/ButtonInputActionAdaptorTests.cs


public void TestQueueEvent()
{
var actionBuffers = new ActionBuffers(ActionSegment<float>.Empty, new ActionSegment<int>(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<float>();
Assert.IsTrue(Mathf.Approximately(1f, val));

public void TestWriteToHeuristic()
{
var actionBuffers = new ActionBuffers(ActionSegment<float>.Empty, new ActionSegment<int>(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<float>.Empty, new ActionSegment<int>(new[] { 1 }));
m_Adaptor.WriteToHeuristic(m_Action, buffer);

12
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/DoubleInputActionAdaptorTests.cs


public void TestQueueEvent()
{
var actionBuffers = new ActionBuffers(new ActionSegment<float>(new[] { 1f }), ActionSegment<int>.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<double>()));
}

{
var actionBuffers = new ActionBuffers(new ActionSegment<float>(new[] { 1f }), ActionSegment<int>.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<float>(new[] { 1f }), ActionSegment<int>.Empty);
m_Adaptor.WriteToHeuristic(m_Action, buffer);

12
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/FloatInputActionAdapatorTests.cs


public void TestQueueEvent()
{
var actionBuffers = new ActionBuffers(new ActionSegment<float>(new[] { 1f }), ActionSegment<int>.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<float>();
Assert.IsTrue(Mathf.Approximately(1f, val));

public void TestWriteToHeuristic()
{
var actionBuffers = new ActionBuffers(new ActionSegment<float>(new[] { 1f }), ActionSegment<int>.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<float>(new[] { 1f }), ActionSegment<int>.Empty);
m_Adaptor.WriteToHeuristic(m_Action, buffer);

12
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/IntegerInputActionAdaptorTests.cs


public void TestQueueEvent()
{
var actionBuffers = new ActionBuffers(ActionSegment<float>.Empty, new ActionSegment<int>(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<int>();
Assert.IsTrue(val == 1);

public void TestWriteToHeuristic()
{
var actionBuffers = new ActionBuffers(ActionSegment<float>.Empty, new ActionSegment<int>(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<float>.Empty, new ActionSegment<int>(new int[1]));
m_Adaptor.WriteToHeuristic(m_Action, buffer);

12
com.unity.ml-agents.extensions/Tests/Runtime/Input/Adaptors/Vector2InputActionAdaptorTests.cs


public void TestQueueEvent()
{
var actionBuffers = new ActionBuffers(new ActionSegment<float>(new[] { 0f, 1f }), ActionSegment<int>.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<Vector2>();
Assert.IsTrue(Mathf.Approximately(0f, val.x));

public void TestWriteToHeuristic()
{
var actionBuffers = new ActionBuffers(new ActionSegment<float>(new[] { 0f, 1f }), ActionSegment<int>.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<float>(new float[2]), ActionSegment<int>.Empty);
m_Adaptor.WriteToHeuristic(m_Action, buffer);

17
com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActionActuatorTests.cs


using Unity.MLAgents.Policies;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.LowLevel;
public bool eventQueued;
public bool eventWritten;
public bool writtenToHeuristic;
public ActionSpec GetActionSpecForInputAction(InputAction action)

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)

public void Reset()
{
eventQueued = false;
eventWritten = false;
writtenToHeuristic = false;
}
}

m_BehaviorParameters = go.AddComponent<BehaviorParameters>();
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<Gamepad>()));
}
[Test]

m_Actuator.OnActionReceived(new ActionBuffers());
m_Actuator.Heuristic(new ActionBuffers());
Assert.IsFalse(m_Adaptor.eventQueued);
Assert.IsFalse(m_Adaptor.eventWritten);
Assert.IsFalse(m_Adaptor.eventQueued);
Assert.IsFalse(m_Adaptor.eventWritten);
Assert.IsTrue(m_Adaptor.eventQueued);
Assert.IsTrue(m_Adaptor.eventWritten);
m_Adaptor.Reset();
Assert.AreEqual(m_Actuator.Name, "InputActionActuator-action");

2
com.unity.ml-agents.extensions/Tests/Runtime/Input/InputActuatorComponentTests.cs


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);

2
com.unity.ml-agents.extensions/Tests/Runtime/Input/Unity.ML-Agents.Extensions.Input.Tests.Runtime.asmdef


"versionDefines": [
{
"name": "com.unity.inputsystem",
"expression": "1.1.0",
"expression": "1.1.0-preview.3",
"define": "MLA_INPUT_TESTS"
}
],

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


- 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#)
- Fix an issue where queuing InputEvents overwrote data from previous events in the same frame.
## [1.8.0-preview] - 2021-02-17
### Major Changes

81
com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs


#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
{
/// <summary>
/// This interface is passed to InputActionActuators to allow them to write to InputEvents.
/// The way this interface should be used is to request the <see cref="InputEventPtr"/> by calling
/// <see cref="GetEventForFrame"/> then call <see cref="EventProcessedInFrame"/> before returning from
/// </summary>
public class InputActuatorEventContext : IDisposable
{
/// <summary>
/// The number of times to allow the use of an event before queuing it in the InputSystem.
/// </summary>
public readonly int NumTimesToProcess;
public readonly InputDevice InputDevice;
NativeArray<byte> 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<byte>();
}
/// <summary>
/// Returns the <see cref="InputEventPtr"/> to write to for the current frame.
/// </summary>
/// <returns>The <see cref="InputEventPtr"/> to write to for the current frame.</returns>
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

3
com.unity.ml-agents.extensions/Runtime/Input/InputActuatorEventContext.cs.meta


fileFormatVersion: 2
guid: 76c31df314114ec6bf104e8db4e5568b
timeCreated: 1614892215
正在加载...
取消
保存