- Home /
Unity 4.6 ui restrict eventSystem only to keyboard input
I have a game which is strictly controlled by keyboard. Even though mouse is not set-up in the input manager so that vertical and horizontal axis are not effected by it, the mouse pointer and buttons are still interacting with the gui. How can I disable it and still get input from keyboard?
Answer by AyAMrau · Sep 01, 2014 at 01:17 PM
This appears to be driven by the input modules, the automatically created EventSystem object includes both the Standalone Input Module and Touch Input Module, and those seem to be the only two provided with the current version.
The Standalone Input Module handles mouse, keyboard, and controller at once - with nothing obvious to exclude a part of this.
The documentation suggests writing your own version inheriting from BaseInputModule if you want something beyond those two.
You can find out more from the documentation that is included with the Unity installation. Just go to Help > Scripting Reference and then search for BaseInputModule
Answer by recon472 · Sep 01, 2014 at 11:06 PM
for anyone with the same problem here is the modified version to accept keyboard input only.
EDIT: updated (there was a bug with text input field)
EDIT 2: updated to the official release, tested with unity 4.6.1
namespace UnityEngine.EventSystems
{
[AddComponentMenu("Event/Keyboard Input Module")]
public class KeyboardInputModule : PointerInputModule
{
private float m_NextAction;
private InputMode m_CurrentInputMode = InputMode.Buttons;
protected KeyboardInputModule()
{}
private enum InputMode
{
Mouse,
Buttons
}
[SerializeField]
private string m_HorizontalAxis = "Horizontal";
/// <summary>
/// Name of the vertical axis for movement (if axis events are used).
/// </summary>
[SerializeField]
private string m_VerticalAxis = "Vertical";
/// <summary>
/// Name of the submit button.
/// </summary>
[SerializeField]
private string m_SubmitButton = "Submit";
/// <summary>
/// Name of the submit button.
/// </summary>
[SerializeField]
private string m_CancelButton = "Cancel";
[SerializeField]
private float m_InputActionsPerSecond = 10;
[SerializeField]
private bool m_AllowActivationOnMobileDevice;
public bool allowActivationOnMobileDevice
{
get { return m_AllowActivationOnMobileDevice; }
set { m_AllowActivationOnMobileDevice = value; }
}
public float inputActionsPerSecond
{
get { return m_InputActionsPerSecond; }
set { m_InputActionsPerSecond = value; }
}
/// <summary>
/// Name of the horizontal axis for movement (if axis events are used).
/// </summary>
public string horizontalAxis
{
get { return m_HorizontalAxis; }
set { m_HorizontalAxis = value; }
}
/// <summary>
/// Name of the vertical axis for movement (if axis events are used).
/// </summary>
public string verticalAxis
{
get { return m_VerticalAxis; }
set { m_VerticalAxis = value; }
}
public string submitButton
{
get { return m_SubmitButton; }
set { m_SubmitButton = value; }
}
public string cancelButton
{
get { return m_CancelButton; }
set { m_CancelButton = value; }
}
public override bool IsModuleSupported()
{
return m_AllowActivationOnMobileDevice || !Application.isMobilePlatform;
}
public override bool ShouldActivateModule()
{
if (!base.ShouldActivateModule ())
return false;
var shouldActivate = Input.GetButtonDown (m_SubmitButton);
shouldActivate |= Input.GetButtonDown (m_CancelButton);
shouldActivate |= !Mathf.Approximately (Input.GetAxis (m_HorizontalAxis), 0.0f);
shouldActivate |= !Mathf.Approximately (Input.GetAxis (m_VerticalAxis), 0.0f);
return shouldActivate;
}
public override void ActivateModule()
{
base.ActivateModule ();
var toSelect = eventSystem.currentSelectedGameObject;
if (toSelect == null)
toSelect = eventSystem.lastSelectedGameObject;
if (toSelect == null)
toSelect = eventSystem.firstSelectedGameObject;
eventSystem.SetSelectedGameObject (null, GetBaseEventData ());
eventSystem.SetSelectedGameObject (toSelect, GetBaseEventData ());
}
public override void DeactivateModule()
{
base.DeactivateModule ();
ClearSelection ();
}
public override void Process()
{
bool usedEvent = SendUpdateEventToSelectedObject ();
if (!usedEvent)
usedEvent |= SendMoveEventToSelectedObject ();
if (!usedEvent)
SendSubmitEventToSelectedObject ();
}
/// <summary>
/// Process submit keys.
/// </summary>
private bool SendSubmitEventToSelectedObject()
{
if (eventSystem.currentSelectedGameObject == null || m_CurrentInputMode != InputMode.Buttons)
return false;
var data = GetBaseEventData ();
if (Input.GetButtonDown (m_SubmitButton))
ExecuteEvents.Execute (eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler);
if (Input.GetButtonDown (m_CancelButton))
ExecuteEvents.Execute (eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler);
return data.used;
}
private bool AllowMoveEventProcessing(float time)
{
bool allow = Input.GetButtonDown (m_HorizontalAxis);
allow |= Input.GetButtonDown (m_VerticalAxis);
allow |= (time > m_NextAction);
return allow;
}
private Vector2 GetRawMoveVector()
{
Vector2 move = Vector2.zero;
move.x = Input.GetAxis (m_HorizontalAxis);
move.y = Input.GetAxis (m_VerticalAxis);
if (Input.GetButtonDown (m_HorizontalAxis))
{
if (move.x < 0)
move.x = -1f;
if (move.x > 0)
move.x = 1f;
}
if (Input.GetButtonDown (m_VerticalAxis))
{
if (move.y < 0)
move.y = -1f;
if (move.y > 0)
move.y = 1f;
}
return move;
}
/// <summary>
/// Process keyboard events.
/// </summary>
private bool SendMoveEventToSelectedObject()
{
float time = Time.unscaledTime;
if (!AllowMoveEventProcessing (time))
return false;
Vector2 movement = GetRawMoveVector ();
//Debug.Log(m_ProcessingEvent.rawType + " axis:" + m_AllowAxisEvents + " value:" + "(" + x + "," + y + ")");
var axisEventData = GetAxisEventData (movement.x, movement.y, 0.6f);
if (!Mathf.Approximately (axisEventData.moveVector.x, 0f)
|| !Mathf.Approximately (axisEventData.moveVector.y, 0f))
{
if (m_CurrentInputMode != InputMode.Buttons)
{
// so if we are chaning to keyboard
m_CurrentInputMode = InputMode.Buttons;
// if we are doing a 'fresh selection'
// return as we don't want to do a move.
if (ResetSelection ())
{
m_NextAction = time + 1f / m_InputActionsPerSecond;
return true;
}
}
ExecuteEvents.Execute (eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler);
}
m_NextAction = time + 1f / m_InputActionsPerSecond;
return axisEventData.used;
}
private bool ResetSelection()
{
var baseEventData = GetBaseEventData ();
// clear all selection
// & figure out what the mouse is over
eventSystem.SetSelectedGameObject (null, baseEventData);
// if we were hovering something...
// use this as the basis for the selection
bool resetSelection = false;
GameObject toSelect = eventSystem.lastSelectedGameObject;
resetSelection = true;
eventSystem.SetSelectedGameObject (toSelect, baseEventData);
return resetSelection;
}
private bool SendUpdateEventToSelectedObject()
{
if (eventSystem.currentSelectedGameObject == null)
return false;
var data = GetBaseEventData ();
ExecuteEvents.Execute (eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);
return data.used;
}
}
}
Recon, how did you get this code working? There seems to be a few input errors in 4.6.1, but those are easily fixed. And when I add this to the event system, nothing seems to happen. Any advice helps..
I've copied the newest version which works alright for me so this should not throw any errors. you use this ins$$anonymous$$d of the standalone input module. $$anonymous$$eaning you'll remove the standalone input module and add this one to the game object containing the event system component.
btw don't forget to set some gameObject to be selected on start (First select in the EventSystem component) and make sure that you have set up the navigation between your buttons (or whatever you are switching) properly. Also check the input settings whether you have your horizontal and vertical axis' set up and the submit button as well...
Let me know if got it working :)
I got this working without problems. It works fine but is not too responsive, especially when I go back and forth between 2 buttons. Any ideas?
[EDIT]
Well, increasing the Sensitivity in the Vertical and Horizontal axis fixed the issue. Now it works like a charm. Thanks for sharing :)
I tried to use the script, but I get errors saying that lastSelectedGameObject is obsolete; and also, if I make a script, add it to the object that has the eventsystem on it and just paste this code on the script, it doesn't detect my script anymore since "the name of the class doesn't match". Could someone help me solve this?
Answer by roger_lew · Apr 16, 2015 at 09:00 PM
Another alternative is to add 2 axes to your InputManager that will never be used and specify these in the StandaloneInputModule component of the EventSystem.
Open InputManager (Edit -> Project Settings -> Input) and increase the Size of the Axes list by 2. At the bottom specify a "NullHorizontal" and a "NullVertical" of type Joystick Axis that correspond to Joystick 11.
Then under your event system specify Horizontal Axis as NullHorizontal and the Vertical Axis as NullVertical.
Voila!
Your answer
Follow this Question
Related Questions
Unity 4.6 UI - How to left-align scroll rect content 3 Answers
Unity 4.6 scrollbar defaults to wrong position with grid layout 1 Answer
Create Dynamic buttons with info and update in new Unity 4.6 UI 1 Answer
U4.6-Maintaining Canvas 'screen fit' functionality with zooming - help with set up 0 Answers
How to achieve this desired render order with the new 4.6 UI? 2 Answers