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

大腿Plus 2017年8月28日14:56:16Unity3D之UGUI拓展61,595阅读模式

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

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;
    }
}
Unity3D UGUI:Tab键切换InputField光标位置
Unity3D UGUI:Tab键切换InputField光标位置

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


上面是使用的效果,这个在使用的时候有一定的限制,就是输入框只能是水平,垂直放,不知道错开位置比较大的情况能不能行,,还有就是水平和垂直不能混用。文章源自大腿Plus-https://www.shijunzh.com/archives/663

大腿Plus
  • 本文由 发表于 2017年8月28日14:56:16
  • 转载请务必保留本文链接:https://www.shijunzh.com/archives/663

发表评论

评论:6   其中:访客  4   博主  2
    • 狗蛋
      狗蛋 1

      我觉得没必要在update里面识别下一个InputField吧,很少见InputField会动态改变位置。

        • 大腿Plus
          大腿Plus

          @ 狗蛋 没太明白你的意思,识别下一个是在点击按钮的时候找下一个InputField,不是一直在找

            • 狗蛋
              狗蛋 1

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

                • 狗蛋
                  狗蛋 1

                  @ 狗蛋 我觉得除非情况是InputField会动态改变下一个InputField的位置,否则没有必要在点击按钮时去做”找”这个动作。

                    • 大腿Plus
                      大腿Plus

                      @ 狗蛋 可以啊,什么时候找都可以,根据自己需求来决定就好,我只是提供了方法。

              • 狗蛋
                狗蛋 1

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