227 lines
7.3 KiB
C#
227 lines
7.3 KiB
C#
|
/// Credit Simon (darkside) Jackson
|
||
|
/// Sourced from - UI SIM source and My Brain
|
||
|
|
||
|
namespace UnityEngine.EventSystems
|
||
|
{
|
||
|
[AddComponentMenu("Event/Extensions/GamePad Input Module")]
|
||
|
public class GamePadInputModule : BaseInputModule
|
||
|
{
|
||
|
private float m_PrevActionTime;
|
||
|
Vector2 m_LastMoveVector;
|
||
|
int m_ConsecutiveMoveCount = 0;
|
||
|
|
||
|
protected GamePadInputModule()
|
||
|
{}
|
||
|
|
||
|
[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 float m_RepeatDelay = 0.1f;
|
||
|
|
||
|
public float inputActionsPerSecond
|
||
|
{
|
||
|
get { return m_InputActionsPerSecond; }
|
||
|
set { m_InputActionsPerSecond = value; }
|
||
|
}
|
||
|
|
||
|
public float repeatDelay
|
||
|
{
|
||
|
get { return m_RepeatDelay; }
|
||
|
set { m_RepeatDelay = 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 ShouldActivateModule()
|
||
|
{
|
||
|
if (!base.ShouldActivateModule())
|
||
|
return false;
|
||
|
|
||
|
var shouldActivate = true;
|
||
|
shouldActivate |= Input.GetButtonDown(m_SubmitButton);
|
||
|
shouldActivate |= Input.GetButtonDown(m_CancelButton);
|
||
|
shouldActivate |= !Mathf.Approximately(Input.GetAxisRaw(m_HorizontalAxis), 0.0f);
|
||
|
shouldActivate |= !Mathf.Approximately(Input.GetAxisRaw(m_VerticalAxis), 0.0f);
|
||
|
return shouldActivate;
|
||
|
}
|
||
|
|
||
|
public override void ActivateModule()
|
||
|
{
|
||
|
StandaloneInputModule StandAloneSystem = GetComponent<StandaloneInputModule>();
|
||
|
|
||
|
if (StandAloneSystem && StandAloneSystem.enabled)
|
||
|
{
|
||
|
Debug.LogError("StandAloneInputSystem should not be used with the GamePadInputModule, " +
|
||
|
"please remove it from the Event System in this scene or disable it when this module is in use");
|
||
|
}
|
||
|
|
||
|
base.ActivateModule();
|
||
|
|
||
|
var toSelect = eventSystem.currentSelectedGameObject;
|
||
|
if (toSelect == null)
|
||
|
toSelect = eventSystem.firstSelectedGameObject;
|
||
|
|
||
|
eventSystem.SetSelectedGameObject(toSelect, GetBaseEventData());
|
||
|
}
|
||
|
|
||
|
public override void DeactivateModule()
|
||
|
{
|
||
|
base.DeactivateModule();
|
||
|
}
|
||
|
|
||
|
public override void Process()
|
||
|
{
|
||
|
bool usedEvent = SendUpdateEventToSelectedObject();
|
||
|
|
||
|
if (eventSystem.sendNavigationEvents)
|
||
|
{
|
||
|
if (!usedEvent)
|
||
|
usedEvent |= SendMoveEventToSelectedObject();
|
||
|
|
||
|
if (!usedEvent)
|
||
|
SendSubmitEventToSelectedObject();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Process submit keys.
|
||
|
/// </summary>
|
||
|
protected bool SendSubmitEventToSelectedObject()
|
||
|
{
|
||
|
if (eventSystem.currentSelectedGameObject == null)
|
||
|
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 Vector2 GetRawMoveVector()
|
||
|
{
|
||
|
Vector2 move = Vector2.zero;
|
||
|
move.x = Input.GetAxisRaw(m_HorizontalAxis);
|
||
|
move.y = Input.GetAxisRaw(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 events.
|
||
|
/// </summary>
|
||
|
protected bool SendMoveEventToSelectedObject()
|
||
|
{
|
||
|
float time = Time.unscaledTime;
|
||
|
|
||
|
Vector2 movement = GetRawMoveVector();
|
||
|
if (Mathf.Approximately(movement.x, 0f) && Mathf.Approximately(movement.y, 0f))
|
||
|
{
|
||
|
m_ConsecutiveMoveCount = 0;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// If user pressed key again, always allow event
|
||
|
bool allow = Input.GetButtonDown(m_HorizontalAxis) || Input.GetButtonDown(m_VerticalAxis);
|
||
|
bool similarDir = (Vector2.Dot(movement, m_LastMoveVector) > 0);
|
||
|
if (!allow)
|
||
|
{
|
||
|
// Otherwise, user held down key or axis.
|
||
|
// If direction didn't change at least 90 degrees, wait for delay before allowing consequtive event.
|
||
|
if (similarDir && m_ConsecutiveMoveCount == 1)
|
||
|
allow = (time > m_PrevActionTime + m_RepeatDelay);
|
||
|
// If direction changed at least 90 degree, or we already had the delay, repeat at repeat rate.
|
||
|
else
|
||
|
allow = (time > m_PrevActionTime + 1f / m_InputActionsPerSecond);
|
||
|
}
|
||
|
if (!allow)
|
||
|
return false;
|
||
|
|
||
|
var axisEventData = GetAxisEventData(movement.x, movement.y, 0.6f);
|
||
|
ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler);
|
||
|
if (!similarDir)
|
||
|
m_ConsecutiveMoveCount = 0;
|
||
|
m_ConsecutiveMoveCount++;
|
||
|
m_PrevActionTime = time;
|
||
|
m_LastMoveVector = movement;
|
||
|
return axisEventData.used;
|
||
|
}
|
||
|
|
||
|
protected bool SendUpdateEventToSelectedObject()
|
||
|
{
|
||
|
if (eventSystem.currentSelectedGameObject == null)
|
||
|
return false;
|
||
|
|
||
|
var data = GetBaseEventData();
|
||
|
ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);
|
||
|
return data.used;
|
||
|
}
|
||
|
}
|
||
|
}
|