Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: ISXB-766, ISXB-808, ISXB-704 scroll wheel factor bugs #1940

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ public override void OnGUI(string searchContext)
if (!runInBackground)
EditorGUILayout.HelpBox("Focus change behavior can only be changed if 'Run In Background' is enabled in Player Settings.", MessageType.Info);

#if UNITY_6000_0_OR_NEWER
EditorGUILayout.PropertyField(m_ScrollDeltaBehavior, m_ScrollDeltaBehaviorContent);
#endif

EditorGUILayout.Space();
EditorGUILayout.PropertyField(m_CompensateForScreenOrientation, m_CompensateForScreenOrientationContent);

Expand Down Expand Up @@ -266,6 +270,7 @@ private void InitializeWithCurrentSettings()
// Look up properties.
m_SettingsObject = new SerializedObject(m_Settings);
m_UpdateMode = m_SettingsObject.FindProperty("m_UpdateMode");
m_ScrollDeltaBehavior = m_SettingsObject.FindProperty("m_ScrollDeltaBehavior");
m_CompensateForScreenOrientation = m_SettingsObject.FindProperty("m_CompensateForScreenOrientation");
m_BackgroundBehavior = m_SettingsObject.FindProperty("m_BackgroundBehavior");
m_EditorInputBehaviorInPlayMode = m_SettingsObject.FindProperty("m_EditorInputBehaviorInPlayMode");
Expand All @@ -281,6 +286,9 @@ private void InitializeWithCurrentSettings()
m_ShortcutKeysConsumeInputs = m_SettingsObject.FindProperty("m_ShortcutKeysConsumeInputs");

m_UpdateModeContent = new GUIContent("Update Mode", "When should the Input System be updated?");
#if UNITY_6000_0_OR_NEWER
m_ScrollDeltaBehaviorContent = new GUIContent("Scroll Delta Behavior", "What value range should be used for scroll wheel delta?");
#endif
m_CompensateForScreenOrientationContent = new GUIContent("Compensate Orientation", "Whether sensor input on mobile devices should be transformed to be relative to the current device orientation.");
m_BackgroundBehaviorContent = new GUIContent("Background Behavior", "If runInBackground is true (and in standalone *development* players and the editor), "
+ "determines what happens to InputDevices and events when the application moves in and out of running in the foreground.\n\n"
Expand Down Expand Up @@ -404,6 +412,7 @@ private static string[] FindInputSettingsInProject()
[NonSerialized] private int m_SettingsDirtyCount;
[NonSerialized] private SerializedObject m_SettingsObject;
[NonSerialized] private SerializedProperty m_UpdateMode;
[NonSerialized] private SerializedProperty m_ScrollDeltaBehavior;
[NonSerialized] private SerializedProperty m_CompensateForScreenOrientation;
[NonSerialized] private SerializedProperty m_BackgroundBehavior;
[NonSerialized] private SerializedProperty m_EditorInputBehaviorInPlayMode;
Expand All @@ -427,6 +436,9 @@ private static string[] FindInputSettingsInProject()
[NonSerialized] private GUIStyle m_NewAssetButtonStyle;

private GUIContent m_UpdateModeContent;
#if UNITY_6000_0_OR_NEWER
private GUIContent m_ScrollDeltaBehaviorContent;
#endif
private GUIContent m_CompensateForScreenOrientationContent;
private GUIContent m_BackgroundBehaviorContent;
private GUIContent m_EditorInputBehaviorInPlayModeContent;
Expand Down
2 changes: 2 additions & 0 deletions Packages/com.unity.inputsystem/InputSystem/IInputRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ internal unsafe interface IInputRuntime

Vector2 screenSize { get; }
ScreenOrientation screenOrientation { get; }
bool normalizeScrollWheelDelta { get; set; }
float scrollWheelDeltaPerTick { get; }

// If analytics are enabled, the runtime receives analytics events from the input manager.
// See InputAnalytics.
Expand Down
24 changes: 24 additions & 0 deletions Packages/com.unity.inputsystem/InputSystem/InputManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,21 @@ public InputUpdateType defaultUpdateType
}
}

public InputSettings.ScrollDeltaBehavior scrollDeltaBehavior
{
get => m_ScrollDeltaBehavior;
set
{
if (m_ScrollDeltaBehavior == value)
return;

m_ScrollDeltaBehavior = value;

InputRuntime.s_Instance.normalizeScrollWheelDelta =
m_ScrollDeltaBehavior == InputSettings.ScrollDeltaBehavior.UniformAcrossAllPlatforms;
}
}

public float pollingFrequency
{
get => m_PollingFrequency;
Expand Down Expand Up @@ -1851,6 +1866,8 @@ internal void InitializeData()
m_UpdateMask |= InputUpdateType.Editor;
#endif

m_ScrollDeltaBehavior = InputSettings.ScrollDeltaBehavior.UniformAcrossAllPlatforms;

// Default polling frequency is 60 Hz.
m_PollingFrequency = 60;

Expand Down Expand Up @@ -2067,6 +2084,8 @@ internal struct AvailableDevice
private InputUpdateType m_CurrentUpdate;
internal InputStateBuffers m_StateBuffers;

private InputSettings.ScrollDeltaBehavior m_ScrollDeltaBehavior;

#if UNITY_EDITOR
// remember time offset to correctly restore it after editor mode is done
private double latestNonEditorTimeOffsetToRealtimeSinceStartup;
Expand Down Expand Up @@ -2596,6 +2615,8 @@ internal void ApplySettings()
#endif
updateMask = newUpdateMask;

scrollDeltaBehavior = m_Settings.scrollDeltaBehavior;

////TODO: optimize this so that we don't repeatedly recreate state if we add/remove multiple devices
//// (same goes for not resolving actions repeatedly)

Expand Down Expand Up @@ -3801,6 +3822,7 @@ internal struct SerializedState
public InputStateBuffers buffers;
public InputUpdate.SerializedState updateState;
public InputUpdateType updateMask;
public InputSettings.ScrollDeltaBehavior scrollDeltaBehavior;
public InputMetrics metrics;
public InputSettings settings;
public InputActionAsset actions;
Expand Down Expand Up @@ -3845,6 +3867,7 @@ internal SerializedState SaveState()
buffers = m_StateBuffers,
updateState = InputUpdate.Save(),
updateMask = m_UpdateMask,
scrollDeltaBehavior = m_ScrollDeltaBehavior,
metrics = m_Metrics,
settings = m_Settings,
#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
Expand All @@ -3862,6 +3885,7 @@ internal void RestoreStateWithoutDevices(SerializedState state)
m_StateBuffers = state.buffers;
m_LayoutRegistrationVersion = state.layoutRegistrationVersion + 1;
updateMask = state.updateMask;
scrollDeltaBehavior = state.scrollDeltaBehavior;
m_Metrics = state.metrics;
m_PollingFrequency = state.pollingFrequency;

Expand Down
41 changes: 41 additions & 0 deletions Packages/com.unity.inputsystem/InputSystem/InputSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ public UpdateMode updateMode
}
}

/// <summary>
/// Controls how platform-specific input should be converted when returning delta values for scroll wheel input actions.
/// By default, the range used for the delta is converted to be uniform across all platforms.
/// </summary>
/// <value>The conversion behavior.</value>
public ScrollDeltaBehavior scrollDeltaBehavior
{
get => m_ScrollDeltaBehavior;
set
{
if (m_ScrollDeltaBehavior == value)
return;
m_ScrollDeltaBehavior = value;
OnChange();
}
}

/// <summary>
/// If true, sensors that deliver rotation values on handheld devices will automatically adjust
/// rotations when the screen orientation changes.
Expand Down Expand Up @@ -748,6 +765,7 @@ public void SetInternalFeatureFlag(string featureName, bool enabled)
[Tooltip("Determine when Unity processes events. By default, accumulated input events are flushed out before each fixed update and "
+ "before each dynamic update. This setting can be used to restrict event processing to only where the application needs it.")]
[SerializeField] private UpdateMode m_UpdateMode = UpdateMode.ProcessEventsInDynamicUpdate;
[SerializeField] private ScrollDeltaBehavior m_ScrollDeltaBehavior = ScrollDeltaBehavior.UniformAcrossAllPlatforms;
[SerializeField] private int m_MaxEventBytesPerUpdate = 5 * 1024 * 1024;
[SerializeField] private int m_MaxQueuedEventsPerUpdate = 1000;

Expand Down Expand Up @@ -845,6 +863,29 @@ public enum UpdateMode
ProcessEventsManually,
}

/// <summary>
/// How platform-specific input should be converted when returning delta values for scroll wheel input actions.
/// </summary>
public enum ScrollDeltaBehavior
{
/// <summary>
/// The range used for the delta is converted to be uniform across all platforms.
/// </summary>
/// <remarks>
/// The resulting range will be [-1, 1] regardless of the platform used.
/// </remarks>
UniformAcrossAllPlatforms = 0,

/// <summary>
/// The range used for the delta is the same as returned by the platform input.
/// </summary>
/// <remarks>
/// The range will typically be [-120, 120] on Windows and [-1, 1] on MacOS and Linux.
/// Other platforms may have different ranges.
/// </remarks>
KeepPlatformSpecificInputRange = 1
}

/// <summary>
/// Determines how the applications behaves when running in the background. See <see cref="backgroundBehavior"/>.
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions Packages/com.unity.inputsystem/InputSystem/InputSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3423,6 +3423,8 @@ public static bool runInBackground
set => s_Manager.m_Runtime.runInBackground = value;
}

internal static float scrollWheelDeltaPerTick => InputRuntime.s_Instance.scrollWheelDeltaPerTick;

////REVIEW: restrict metrics to editor and development builds?
/// <summary>
/// Get various up-to-date metrics about the input system.
Expand Down
19 changes: 19 additions & 0 deletions Packages/com.unity.inputsystem/InputSystem/NativeInputRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,25 @@ private void OnFocusChanged(bool focus)
public Vector2 screenSize => new Vector2(Screen.width, Screen.height);
public ScreenOrientation screenOrientation => Screen.orientation;

public bool normalizeScrollWheelDelta
{
#if UNITY_6000_0_OR_NEWER
get => NativeInputSystem.normalizeScrollWheelDelta;
set => NativeInputSystem.normalizeScrollWheelDelta = value;
#else
get; set;
#endif
}

public float scrollWheelDeltaPerTick
{
#if UNITY_6000_0_OR_NEWER
get { return NativeInputSystem.GetScrollWheelDeltaPerTick(); }
#else
get => 1.0f;
#endif
}

public bool isInBatchMode => Application.isBatchMode;

#if UNITY_EDITOR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ internal class InputSystemProvider : IEventProviderImpl
NavigationEventRepeatHelper m_RepeatHelper = new();
bool m_ResetSeenEventsOnUpdate;

#if UNITY_6000_0_OR_NEWER
const float kScrollUGUIScaleFactor = UIElements.WheelEvent.scrollDeltaPerTick;
#else
const float kScrollUGUIScaleFactor = 3.0f;
#endif

static Action<InputActionAsset> s_OnRegisterActions;

Expand Down Expand Up @@ -529,8 +533,9 @@ void OnClickPerformed(InputAction.CallbackContext ctx, EventSource eventSource,

void OnScrollWheelPerformed(InputAction.CallbackContext ctx)
{
var scrollDelta = ctx.ReadValue<Vector2>();
if (scrollDelta.sqrMagnitude < k_SmallestReportedMovementSqrDist)
// ISXB-704: convert potentially platform-specific input value to uniform ticks before sending them to UI.
var scrollTicks = ctx.ReadValue<Vector2>() / InputSystem.scrollWheelDeltaPerTick;
if (scrollTicks.sqrMagnitude < k_SmallestReportedMovementSqrDist)
return;

var eventSource = GetEventSource(ctx);
Expand All @@ -550,9 +555,12 @@ void OnScrollWheelPerformed(InputAction.CallbackContext ctx)
targetDisplay = Mouse.current.displayIndex.ReadValue();
}

// Make it look similar to IMGUI event scroll values.
scrollDelta.x *= kScrollUGUIScaleFactor;
scrollDelta.y *= -kScrollUGUIScaleFactor;
// Make scrollDelta look similar to IMGUI event scroll values.
var scrollDelta = new Vector2
{
x = scrollTicks.x * kScrollUGUIScaleFactor,
y = -scrollTicks.y * kScrollUGUIScaleFactor
};

DispatchFromCallback(Event.From(new PointerEvent
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2062,18 +2062,19 @@ private bool CheckForRemovedDevice(ref InputAction.CallbackContext context)
return false;
}

internal const float kPixelPerLine = 20;

private void OnScrollCallback(InputAction.CallbackContext context)
{
var index = GetPointerStateIndexFor(ref context);
if (index == -1)
return;

ref var state = ref GetPointerStateForIndex(index);
// The old input system reported scroll deltas in lines, we report pixels.
// Need to scale as the UI system expects lines.
state.scrollDelta = context.ReadValue<Vector2>() * (1 / kPixelPerLine);

var scrollDelta = context.ReadValue<Vector2>();

// ISXB-704: convert potentially platform-specific input value to BaseInputModule convention.
state.scrollDelta = scrollDelta * (scrollWheelDeltaPerTick / InputSystem.scrollWheelDeltaPerTick);

#if UNITY_2022_3_OR_NEWER
state.eventData.displayIndex = GetDisplayIndexFor(context.control);
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ public struct PairedUser

public Vector2 screenSize { get; set; } = new Vector2(1024, 768);
public ScreenOrientation screenOrientation { set; get; } = ScreenOrientation.Portrait;
public bool normalizeScrollWheelDelta { get; set; } = true;
public float scrollWheelDeltaPerTick { get; } = 1.0f;

public List<PairedUser> userAccountPairings
{
Expand Down