虽然UGUI的功能没有NGUI的多,但是UGUI要比NGUI稳定,还有就是自适应做的比较不错,但是UGUI要实现一些功能就得自己去写了,还好UGUI给我们留了好多接口,好多东西我们自己是可以修改或者重写的方法,之前写过一个ScrollView滑动居中的东西,有需要的可以去看看。好了其他的也不多说了,今天主要是要解决输入框Tab键切换光标的功能,这个网上有好多文章,但是没有循环切换的,我做了一些修改,可以进行循环切换,还可以设置水平垂直方向的切换。下面是代码。
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 UnityEngine; using System.Collections; using UnityEngine.EventSystems; using UnityEngine.UI; /// <summary> /// UGUI Tab键切换InputField /// </summary> public class InputNavigator : MonoBehaviour, ISelectHandler, IDeselectHandler { private EventSystem system; private bool isSelect = false; public Direction direction = Direction.vertical; public enum Direction { vertical = 0, horizontal = 1 } void Start() { system = EventSystem.current; } void Update() { if (Input.GetKeyDown(KeyCode.Tab) && isSelect) { Selectable next = null; var current = system.currentSelectedGameObject.GetComponent<Selectable>(); int mark = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) ? 1 : -1; Vector3 dir = direction == Direction.horizontal ? Vector3.left * mark : Vector3.up * mark; next = GetNextSelectable(current, dir); if (next != null) { var inputField = next.GetComponent<InputField>(); if (inputField == null) return; StartCoroutine(Wait(next)); } } } private static Selectable GetNextSelectable(Selectable current, Vector3 dir) { Selectable next = current.FindSelectable(dir); if (next == null) next = current.FindLoopSelectable(-dir); return next; } IEnumerator Wait(Selectable next) { yield return new WaitForEndOfFrame(); system.SetSelectedGameObject(next.gameObject, new BaseEventData(system)); } public void OnSelect(BaseEventData eventData) { isSelect = true; } public void OnDeselect(BaseEventData eventData) { isSelect = false; } } public static class Develop { public static Selectable FindLoopSelectable(this Selectable current, Vector3 dir) { Selectable first = current.FindSelectable(dir); if (first != null) { current = first.FindLoopSelectable(dir); } return current; } } |
把这个脚本拖到有InputField组件上就可以了,下面是水平和垂直的效果
上面是使用的效果,这个在使用的时候有一定的限制,就是输入框只能是水平,垂直放,不知道错开位置比较大的情况能不能行,,还有就是水平和垂直不能混用。文章源自大腿Plus-https://www.zhaoshijun.com/archives/663
文章源自大腿Plus-https://www.zhaoshijun.com/archives/663
我的微信
微信扫一扫
shijun_z
我的QQ
QQ扫一扫
846207670
1F
我觉得没必要在update里面识别下一个InputField吧,很少见InputField会动态改变位置。
B1
@ 狗蛋 没太明白你的意思,识别下一个是在点击按钮的时候找下一个InputField,不是一直在找
B2
@ 大腿Plus 就是说我的脚本里InputField都是固定的,不用每次都在点击按钮时去做”找”这个动作,所以我直接声明一个公开的Selectable,每次点击按钮时直接转跳去所声明的Selectable就可以。
B3
@ 狗蛋 我觉得除非情况是InputField会动态改变下一个InputField的位置,否则没有必要在点击按钮时去做”找”这个动作。
B4
@ 狗蛋 可以啊,什么时候找都可以,根据自己需求来决定就好,我只是提供了方法。
2F
我改成了这样:
public Selectable nextInputField;
void Update()
{
if (Input.GetKeyDown(KeyCode.Tab) && isSelect)
{
StartCoroutine(Wait(nextInputField));
}
}