using System; using System.ComponentModel; using UnityEngine.InputSystem.Controls; using UnityEngine.Scripting; #if UNITY_EDITOR using UnityEngine.InputSystem.Editor; using UnityEngine.UIElements; #endif ////REVIEW: this is confusing when considered next to HoldInteraction; also it's confusingly named namespace UnityEngine.InputSystem.Interactions { /// /// Performs the action if the control is pressed and held for at least the set /// duration (which defaults to ) /// and then released. /// [DisplayName("Long Tap")] public class SlowTapInteraction : IInputInteraction { /// /// The time in seconds within which the control needs to be pressed and released to perform the interaction. /// /// /// If this value is equal to or smaller than zero, the input system will use () instead. /// public float duration; /// /// The press point required to perform the interaction. /// /// /// For analog controls (such as trigger axes on a gamepad), the control needs to be engaged by at least this /// value to perform the interaction. /// If this value is equal to or smaller than zero, the input system will use () instead. /// public float pressPoint; ////REVIEW: this seems stupid; shouldn't a slow tap just be anything that takes longer than TapTime? private float durationOrDefault => duration > 0.0f ? duration : InputSystem.settings.defaultSlowTapTime; private float pressPointOrDefault => pressPoint > 0 ? pressPoint : ButtonControl.s_GlobalDefaultButtonPressPoint; private double m_SlowTapStartTime; public void Process(ref InputInteractionContext context) { if (context.isWaiting && context.ControlIsActuated(pressPointOrDefault)) { m_SlowTapStartTime = context.time; context.Started(); return; } if (context.isStarted && !context.ControlIsActuated(pressPointOrDefault)) { if (context.time - m_SlowTapStartTime >= durationOrDefault) context.Performed(); else ////REVIEW: does it matter to cancel right after expiration of 'duration' or is it enough to cancel on button up like here? context.Canceled(); } } public void Reset() { m_SlowTapStartTime = 0.0; } } #if UNITY_EDITOR internal class SlowTapInteractionEditor : InputParameterEditor { protected override void OnEnable() { m_DurationSetting.Initialize("Min Tap Duration", "Minimum time (in seconds) that a control has to be held for it to register as a slow tap. If the control is released " + "before this time, the slow tap is canceled.", "Default Slow Tap Time", () => target.duration, x => target.duration = x, () => InputSystem.settings.defaultSlowTapTime); m_PressPointSetting.Initialize("Press Point", "The amount of actuation a control requires before being considered pressed. If not set, default to " + "'Default Button Press Point' in the global input settings.", "Default Button Press Point", () => target.pressPoint, v => target.pressPoint = v, () => InputSystem.settings.defaultButtonPressPoint); } public override void OnGUI() { #if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS if (!InputSystem.settings.IsFeatureEnabled(InputFeatureNames.kUseIMGUIEditorForAssets)) return; #endif m_DurationSetting.OnGUI(); m_PressPointSetting.OnGUI(); } #if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { m_DurationSetting.OnDrawVisualElements(root, onChangedCallback); m_PressPointSetting.OnDrawVisualElements(root, onChangedCallback); } #endif private CustomOrDefaultSetting m_DurationSetting; private CustomOrDefaultSetting m_PressPointSetting; } #endif }