UGUI中实现Tab键切换控件

在UGUI 中,虽然提供了控件之间的导航切换,但是存在一些问题,首先,只有方向键切换,并没有Tab键的切换;另一个问题是,对于InputField 控件来说,当Focus点按哦InputField 之后,所有的输入事件都会被使用(EventData.Use),InputFiled控件在输入时不能进行导航。

既然不能偷懒,只能自己来实现,好在实现该功能也很简单,这里先上代码,下面会对代码和使用稍作解释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(Selectable))]
public class TabNavController : MonoBehaviour, IUpdateSelectedHandler
{
//功能开关
public bool enableSubmit = true;
public bool enableVertical = true;
public bool enableHorizontal = false;

//定义各种按键
public string tabBtn = "Tab";
public string submitBtn = "Submit";
public string verticalNavBtn = "NavVertical";
public string horizontalNavBtn = "NavHorizontal";

private Selectable m_Selectable;
private AxisEventData m_AxisEventData;

private static Vector2 downVec = new Vector2(0.0f, -1.0f);
private static Vector2 rightVec = new Vector2(1.0f, 0.0f);

Selectable selectable
{
get
{
if (m_Selectable == null)
m_Selectable = GetComponent<Selectable>();
return m_Selectable;
}
}

private void Move(MoveDirection dir, Vector2 vec)
{
if (EventSystem.current.alreadySelecting)
return;

if (m_AxisEventData == null)
m_AxisEventData = new AxisEventData(EventSystem.current);

m_AxisEventData.moveVector = vec;
m_AxisEventData.moveDir = dir;
ExecuteEvents.Execute<IMoveHandler>(gameObject, m_AxisEventData, ExecuteEvents.moveHandler);
}

public void OnUpdateSelected(BaseEventData eventData)
{
BaseInput input = eventData.currentInputModule.input;
if (input.GetButtonDown(tabBtn))
{
if (selectable.FindSelectableOnRight() != null)
Move(MoveDirection.Right, rightVec);
else
Move(MoveDirection.Down, downVec);
}
else if (enableSubmit && input.GetButtonDown(submitBtn))
{
Move(MoveDirection.Down, downVec);
}
else if (enableVertical && input.GetButtonDown(verticalNavBtn))
{
float axis = input.GetAxisRaw(verticalNavBtn);
Move(axis > 0 ? MoveDirection.Up : MoveDirection.Down, new Vector2(0.0f, axis));
}
else if (enableHorizontal && input.GetButtonDown(horizontalNavBtn))
{
float axis = input.GetAxisRaw(horizontalNavBtn);
Move(axis > 0 ? MoveDirection.Right : MoveDirection.Left, new Vector2(axis, 0.0f));
}

//标记事件为used,避免后续继续处理该事件
eventData.Use();
}
}

关于使用

在使用时有两点需要注意:

  • 这里采用Button来定义各个切换按键,使用前需要在ProjectSetting里面定义Tab、Submit、NavVertical、NavHorizontal 四个按键,设置参数如下:
  • UGUI默认会自动设置导航控件,但这结果可能并不是我们想要的,所以就需要显示进行指定。