Unity3D UGUI:Tab键切换InputField光标位置

虽然UGUI的功能没有NGUI的多,但是UGUI要比NGUI稳定,还有就是自适应做的比较不错,但是UGUI要实现一些功能就得自己去写了,还好UGUI给我们留了好多接口,好多东西我们自己是可以修改或者重写的方法,之前写过一个ScrollView滑动居中的东西,有需要的可以去看看。好了其他的也不多说了,今天主要是要解决输入框Tab键切换光标的功能,这个网上有好多文章,但是没有循环切换的,我做了一些修改,可以进行循环切换,还可以设置水平垂直方向的切换。下面是代码。

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;
    }
}
1
2

把这个脚本拖到有InputField组件上就可以了,下面是水平和垂直的效果


上面是使用的效果,这个在使用的时候有一定的限制,就是输入框只能是水平,垂直放,不知道错开位置比较大的情况能不能行,,还有就是水平和垂直不能混用。

You May Also Like

About the Author: 大腿Plus

6 Comments

      1. 就是说我的脚本里InputField都是固定的,不用每次都在点击按钮时去做”找”这个动作,所以我直接声明一个公开的Selectable,每次点击按钮时直接转跳去所声明的Selectable就可以。

  1. 我改成了这样:
    public Selectable nextInputField;
    void Update()
    {
    if (Input.GetKeyDown(KeyCode.Tab) && isSelect)
    {
    StartCoroutine(Wait(nextInputField));
    }
    }

发表评论