Unity 带文本联想的 InputField

Unity 带文本联想的 InputField

效果图
效果图
核心点
脚本继承 InputField,并在 InputField 上扩展了 Dropdown 的部分功能

  1. 不废话,直接上代码
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

public class SearchInputField : InputField
{
    [SerializeField]
    private RectTransform m_Template;
    public RectTransform template { get { return m_Template; } set { m_Template = value; } }

    [SerializeField]
    private List<string> m_Options = new List<string>();
    public List<string> options { get { return m_Options; } set { m_Options = value; } }

    [Serializable]
    public class SearchInputFieldEvent : UnityEvent<string> { }
    [SerializeField]
    private SearchInputFieldEvent m_OnMatched = new SearchInputFieldEvent();
    public SearchInputFieldEvent onMatched { get { return m_OnMatched; } set { m_OnMatched = value; } }

    private List<string> _matchResults = new List<string>();
    private List<DropdownItem> _items = new List<DropdownItem>();

    private bool _isValidTemplate = false;
    private GameObject _dropdown;
    private GameObject _blocker;

    protected override void Awake()
    {
        base.Awake();
    }

    protected override void OnEnable()
    {
        base.OnEnable();

    }

    protected override void Start()
    {
        base.Start();

        onValueChanged.AddListener(txt => { MatchTextAndShow(txt); });
    }

    protected override void OnDisable()
    {
        base.OnDisable();

    }

    protected override void OnDestroy()
    {
        base.OnDestroy();

    }

    private void MatchTextAndShow(string txt)
    {
        if (string.IsNullOrEmpty(txt))
        {
            Hide();
        }
        else
        {
            _matchResults.Clear();
            foreach (string item in m_Options)
            {
                if (item.Contains(txt))
                {
                    _matchResults.Add(item);
                }
            }

            if (_matchResults.Count > 0)
            {
                Hide();
                Show();
            }
            else
            {
                Hide();
            }
        }
    }

    protected internal class DropdownItem : MonoBehaviour
    {
        [SerializeField]
        private Text m_Text;
        [SerializeField]
        private RectTransform m_RectTransform;
        [SerializeField]
        private Button m_Button;

        public Text text { get { return m_Text; } set { m_Text = value; } }
        public RectTransform rectTransform { get { return m_RectTransform; } set { m_RectTransform = value; } }
        public Button button { get { return m_Button; } set { m_Button = value; } }
    }

    public void AddOption(string option)
    {
        m_Options.Add(option);
    }

    public void AddOptions(List<string> options)
    {
        m_Options.AddRange(options);
    }

    public void ClearOptions()
    {
        m_Options.Clear();
    }

    private void SetupTemplate()
    {
        GameObject templateGo = template.gameObject;
        templateGo.SetActive(true);
        Button itemBtn = template.GetComponentInChildren<Button>();
        Text itemTxt = template.GetComponentInChildren<Text>();

        DropdownItem item = itemBtn.gameObject.AddComponent<DropdownItem>();
        item.text = itemTxt;
        item.button = itemBtn;
        item.rectTransform = (RectTransform)itemBtn.transform;

        Canvas popupCanvas = GetOrAddComponent<Canvas>(templateGo);
        popupCanvas.overrideSorting = true;
        popupCanvas.sortingOrder = 30000;

        GetOrAddComponent<GraphicRaycaster>(templateGo);
        GetOrAddComponent<CanvasGroup>(templateGo);
        templateGo.SetActive(false);
        
        _isValidTemplate = true;
    }

    private static T GetOrAddComponent<T>(GameObject go) where T : Component
    {
        T comp = go.GetComponent<T>();
        if (!comp)
            comp = go.AddComponent<T>();
        return comp;
    }

    private void Show()
    {
        if (!IsActive() || !IsInteractable()) return;

        if (!_isValidTemplate)
        {
            SetupTemplate();
            if (!_isValidTemplate)
                return;
        }

        List<Canvas> list = new List<Canvas>();
        gameObject.GetComponentsInParent(false, list);
        if (list.Count == 0)
            return;
        Canvas rootCanvas = list[0];

        template.gameObject.SetActive(true);

        // Instantiate the drop-down template
        _dropdown = Instantiate(template.gameObject);
        _dropdown.name = "Dropdown List";
        _dropdown.SetActive(true);
        RectTransform dropdownRectTransform = _dropdown.transform as RectTransform;
        dropdownRectTransform.SetParent(template.transform.parent, false);

        // Find the dropdown item and disable it.
        DropdownItem itemTemplate = _dropdown.GetComponentInChildren<DropdownItem>();

        GameObject content = itemTemplate.rectTransform.parent.gameObject;
        RectTransform contentRectTransform = content.transform as RectTransform;
        itemTemplate.rectTransform.gameObject.SetActive(true);

        // Get the rects of the dropdown and item
        Rect dropdownContentRect = contentRectTransform.rect;
        Rect itemTemplateRect = itemTemplate.rectTransform.rect;

        // Calculate the visual offset between the item's edges and the background's edges
        Vector2 offsetMin = itemTemplateRect.min - dropdownContentRect.min + (Vector2)itemTemplate.rectTransform.localPosition;
        Vector2 offsetMax = itemTemplateRect.max - dropdownContentRect.max + (Vector2)itemTemplate.rectTransform.localPosition;
        Vector2 itemSize = itemTemplateRect.size;

        _items.Clear();
        Button prev = null;
        for (int i = 0; i < _matchResults.Count; ++i)
        {
            string data = _matchResults[i];
            DropdownItem item = AddItem(data, itemTemplate, _items);
            if (item == null)
                continue;

            // Automatically set up a toggle state change listener
            item.button.onClick.AddListener(() =>
            {
                m_Text = item.text.text;
                onMatched.Invoke(m_Text);
                //MoveTextEnd(true);
                Hide();
            });

            // 不要切换焦点
            //item.button.Select();

            // Automatically set up explicit navigation
            if (prev != null)
            {
                Navigation prevNav = prev.navigation;
                Navigation toggleNav = item.button.navigation;
                prevNav.mode = Navigation.Mode.Explicit;
                toggleNav.mode = Navigation.Mode.Explicit;

                prevNav.selectOnDown = item.button;
                prevNav.selectOnRight = item.button;
                toggleNav.selectOnLeft = prev;
                toggleNav.selectOnUp = prev;

                prev.navigation = prevNav;
                item.button.navigation = toggleNav;
            }
            prev = item.button;
        }

        // Reposition all items now that all of them have been added
        Vector2 sizeDelta = contentRectTransform.sizeDelta;
        sizeDelta.y = itemSize.y * _items.Count + offsetMin.y - offsetMax.y;
        contentRectTransform.sizeDelta = sizeDelta;

        float extraSpace = dropdownRectTransform.rect.height - contentRectTransform.rect.height;
        if (extraSpace > 0)
            dropdownRectTransform.sizeDelta = new Vector2(dropdownRectTransform.sizeDelta.x, dropdownRectTransform.sizeDelta.y - extraSpace);

        // Invert anchoring and position if dropdown is partially or fully outside of canvas rect.
        // Typically this will have the effect of placing the dropdown above the button instead of below,
        // but it works as inversion regardless of initial setup.
        Vector3[] corners = new Vector3[4];
        dropdownRectTransform.GetWorldCorners(corners);

        RectTransform rootCanvasRectTransform = rootCanvas.transform as RectTransform;
        Rect rootCanvasRect = rootCanvasRectTransform.rect;
        for (int axis = 0; axis < 2; axis++)
        {
            bool outside = false;
            for (int i = 0; i < 4; i++)
            {
                Vector3 corner = rootCanvasRectTransform.InverseTransformPoint(corners[i]);
                if (corner[axis] < rootCanvasRect.min[axis] || corner[axis] > rootCanvasRect.max[axis])
                {
                    outside = true;
                    break;
                }
            }
            if (outside)
                RectTransformUtility.FlipLayoutOnAxis(dropdownRectTransform, axis, false, false);
        }

        for (int i = 0; i < _items.Count; i++)
        {
            RectTransform itemRect = _items[i].rectTransform;
            itemRect.anchorMin = new Vector2(itemRect.anchorMin.x, 0);
            itemRect.anchorMax = new Vector2(itemRect.anchorMax.x, 0);
            itemRect.anchoredPosition = new Vector2(itemRect.anchoredPosition.x, offsetMin.y + itemSize.y * (_items.Count - 1 - i) + itemSize.y * itemRect.pivot.y);
            itemRect.sizeDelta = new Vector2(itemRect.sizeDelta.x, itemSize.y);
        }

        // Make drop-down template and item template inactive
        template.gameObject.SetActive(false);
        itemTemplate.gameObject.SetActive(false);

        _blocker = CreateBlocker(rootCanvas);

        // 焦点
        //EventSystem.current.SetSelectedGameObject(gameObject);
        //MoveTextEnd(false);
    }

    public void Hide()
    {
        if (_dropdown != null)
        {
            for (int i = 0; i < _items.Count; i++)
            {
                if (_items[i] != null)
                {
                    //DestroyItem(_items[i]);
                }
            }
            _items.Clear();
            if (_dropdown != null)
                Destroy(_dropdown);
            _dropdown = null;
        }

        if (_blocker != null)
            Destroy(_blocker);
        _blocker = null;
        Select();
    }

    private GameObject CreateBlocker(Canvas rootCanvas)
    {
        // Create blocker GameObject.
        GameObject blocker = new GameObject("Blocker");

        // Setup blocker RectTransform to cover entire root canvas area.
        RectTransform blockerRect = blocker.AddComponent<RectTransform>();
        blockerRect.SetParent(rootCanvas.transform, false);
        blockerRect.anchorMin = Vector3.zero;
        blockerRect.anchorMax = Vector3.one;
        blockerRect.sizeDelta = Vector2.zero;

        // Make blocker be in separate canvas in same layer as dropdown and in layer just below it.
        Canvas blockerCanvas = blocker.AddComponent<Canvas>();
        blockerCanvas.overrideSorting = true;
        Canvas dropdownCanvas = _dropdown.GetComponent<Canvas>();
        blockerCanvas.sortingLayerID = dropdownCanvas.sortingLayerID;
        blockerCanvas.sortingOrder = dropdownCanvas.sortingOrder - 1;

        // Add raycaster since it's needed to block.
        blocker.AddComponent<GraphicRaycaster>();

        // Add image since it's needed to block, but make it clear.
        Image blockerImage = blocker.AddComponent<Image>();
        blockerImage.color = Color.clear;

        // Add button since it's needed to block, and to close the dropdown when blocking area is clicked.
        Button blockerButton = blocker.AddComponent<Button>();
        blockerButton.onClick.AddListener(Hide);

        return blocker;
    }
    
    private DropdownItem AddItem(string data, DropdownItem itemTemplate, List<DropdownItem> items)
    {
        // Add a new item to the dropdown.
        DropdownItem item = Instantiate(itemTemplate);
        item.rectTransform.SetParent(itemTemplate.rectTransform.parent, false);

        item.gameObject.SetActive(true);
        item.gameObject.name = "Item " + items.Count + (!string.IsNullOrEmpty(data) ? ": " + data : "");

        // Set the item's data
        if (item.text)
            item.text.text = data;

        items.Add(item);
        return item;
    }
}
  1. 为了方便创建,进行了简易的编译器扩展

UI结构图
结构图
编译器自定义界面(隐藏了InputField的原始界面,可以自己修改)
编译器自定义界面

using System;
using System.Reflection;
using UnityEditor;
using UnityEditor.UI;
using UnityEngine;
using UnityEngine.UI;

[CustomEditor(typeof(SearchInputField))]
public class SearchInputFieldEditor : InputFieldEditor
{
    SerializedProperty m_Text;
    SerializedProperty m_TextComponent;
    SerializedProperty m_Placeholder;

    SerializedProperty m_Template;
    SerializedProperty m_Options;
    SerializedProperty m_OnMatched;

    protected override void OnEnable()
    {
        //base.OnEnable();

        m_Text = serializedObject.FindProperty("m_Text");
        m_TextComponent = serializedObject.FindProperty("m_TextComponent");
        m_Placeholder = serializedObject.FindProperty("m_Placeholder");
        m_Template = serializedObject.FindProperty("m_Template");
        m_Options = serializedObject.FindProperty("m_Options");
        m_OnMatched = serializedObject.FindProperty("m_OnMatched");
    }

    protected override void OnDisable()
    {
        //base.OnDisable();
    }

    public override void OnInspectorGUI()
    {
        //base.OnInspectorGUI();
        serializedObject.Update();
        
        EditorGUILayout.Space();
        EditorGUILayout.PropertyField(m_Text);

        EditorGUILayout.Space();
        EditorGUILayout.PropertyField(m_TextComponent);
        if (m_TextComponent != null && m_TextComponent.objectReferenceValue != null)
        {
            Text text = m_TextComponent.objectReferenceValue as Text;
            if (text.supportRichText)
            {
                EditorGUILayout.HelpBox("Using Rich Text with input is unsupported.", MessageType.Warning);
            }
        }
        EditorGUILayout.PropertyField(m_Placeholder);

        EditorGUILayout.Space();
        EditorGUILayout.PropertyField(m_Template);
        EditorGUILayout.PropertyField(m_Options, true); 
        EditorGUILayout.PropertyField(m_OnMatched);

        serializedObject.ApplyModifiedProperties();
    }
}

public static class CustomUIControls
{
    # region MenuOptions
    private const string kUILayerName = "UI";

    private const string kStandardSpritePath = "UI/Skin/UISprite.psd";
    private const string kBackgroundSpritePath = "UI/Skin/Background.psd";
    private const string kInputFieldBackgroundPath = "UI/Skin/InputFieldBackground.psd";
    private const string kKnobPath = "UI/Skin/Knob.psd";
    private const string kCheckmarkPath = "UI/Skin/Checkmark.psd";
    private const string kDropdownArrowPath = "UI/Skin/DropdownArrow.psd";
    private const string kMaskPath = "UI/Skin/UIMask.psd";

    private static  DefaultControls.Resources s_StandardResources;
    private static DefaultControls.Resources GetStandardResources()
    {
        if (s_StandardResources.standard == null)
        {
            s_StandardResources.standard = AssetDatabase.GetBuiltinExtraResource<Sprite>(kStandardSpritePath);
            s_StandardResources.background = AssetDatabase.GetBuiltinExtraResource<Sprite>(kBackgroundSpritePath);
            s_StandardResources.inputField = AssetDatabase.GetBuiltinExtraResource<Sprite>(kInputFieldBackgroundPath);
            s_StandardResources.knob = AssetDatabase.GetBuiltinExtraResource<Sprite>(kKnobPath);
            s_StandardResources.checkmark = AssetDatabase.GetBuiltinExtraResource<Sprite>(kCheckmarkPath);
            s_StandardResources.dropdown = AssetDatabase.GetBuiltinExtraResource<Sprite>(kDropdownArrowPath);
            s_StandardResources.mask = AssetDatabase.GetBuiltinExtraResource<Sprite>(kMaskPath);
        }
        return s_StandardResources;
    }

    [MenuItem("GameObject/UI/Custom/Search Input Field", false, 1900)]
    public static void AddSearchInputField(MenuCommand menuCommand)
    {
        GameObject searchInputField = CreateSearchInputField(GetStandardResources());

        Assembly assembly = Assembly.Load("UnityEditor.UI");
        Type type = assembly.GetType("UnityEditor.UI.MenuOptions");
        BindingFlags flag = BindingFlags.Static | BindingFlags.NonPublic;
        MethodInfo method = type.GetMethod("PlaceUIElementRoot", flag);
        method.Invoke(null, new object[] { searchInputField, menuCommand });
    }
    #endregion

    #region DefaultControls
    private const float kWidth = 160f;
    private const float kThickHeight = 30f;
    private const float kThinHeight = 20f;
    private static Vector2 s_ThickElementSize = new Vector2(kWidth, kThickHeight);
    //private static Vector2 s_ThinElementSize = new Vector2(kWidth, kThinHeight);
    //private static Vector2 s_ImageElementSize = new Vector2(100f, 100f);
    private static Color s_DefaultSelectableColor = new Color(1f, 1f, 1f, 1f);
    //private static Color s_PanelColor = new Color(1f, 1f, 1f, 0.392f);
    private static Color s_TextColor = new Color(50f / 255f, 50f / 255f, 50f / 255f, 1f);

    /// <summary>
    /// Create the basic UI search input field.
    /// </summary>
    /// <remarks>
    /// Hierarchy:
    /// (root)
    ///     SearchInputField
    ///         - PlaceHolder
    ///         - Text
    ///         - Template
    ///             - Viewport
    ///                 - Content
    ///                     - Item
    ///                         - Item Background
    ///                         - Item Label
    ///             - Scrollbar
    ///                 - Sliding Area
    ///                     - Handle
    /// <remarks>
    /// <param name="resources">The resources to use for creation.</param>
    /// <returns>The root GameObject of the created element.</returns>
    public static GameObject CreateSearchInputField(DefaultControls.Resources resources)
    {
        GameObject root = CreateUIElementRoot("SearchInputField", s_ThickElementSize);

        // InputField
        GameObject childPlaceholder = CreateUIObject("Placeholder", root);
        GameObject childText = CreateUIObject("Text", root);

        Image image = root.AddComponent<Image>();
        image.sprite = resources.inputField;
        image.type = Image.Type.Sliced;
        image.color = s_DefaultSelectableColor;

        SearchInputField inputField = root.AddComponent<SearchInputField>();
        inputField.targetGraphic = image;
        SetDefaultColorTransitionValues(inputField);

        Text text = childText.AddComponent<Text>();
        text.text = "";
        text.supportRichText = false;
        SetDefaultTextValues(text);

        Text placeholder = childPlaceholder.AddComponent<Text>();
        placeholder.text = "Enter text...";
        placeholder.fontStyle = FontStyle.Italic;
        // Make placeholder color half as opaque as normal text color.
        Color placeholderColor = text.color;
        placeholderColor.a *= 0.5f;
        placeholder.color = placeholderColor;

        RectTransform textRectTransform = childText.GetComponent<RectTransform>();
        textRectTransform.anchorMin = Vector2.zero;
        textRectTransform.anchorMax = Vector2.one;
        textRectTransform.sizeDelta = Vector2.zero;
        textRectTransform.offsetMin = new Vector2(10, 6);
        textRectTransform.offsetMax = new Vector2(-10, -7);

        RectTransform placeholderRectTransform = childPlaceholder.GetComponent<RectTransform>();
        placeholderRectTransform.anchorMin = Vector2.zero;
        placeholderRectTransform.anchorMax = Vector2.one;
        placeholderRectTransform.sizeDelta = Vector2.zero;
        placeholderRectTransform.offsetMin = new Vector2(10, 6);
        placeholderRectTransform.offsetMax = new Vector2(-10, -7);

        inputField.textComponent = text;
        inputField.placeholder = placeholder;

        // Template
        GameObject template = CreateUIObject("Template", root);
        GameObject viewport = CreateUIObject("Viewport", template);
        GameObject content = CreateUIObject("Content", viewport);
        GameObject item = CreateUIObject("Item", content);
        GameObject itemBackground = CreateUIObject("Item Background", item);
        GameObject itemLabel = CreateUIObject("Item Label", item);

        GameObject scrollbar = DefaultControls.CreateScrollbar(resources);
        scrollbar.name = "Scrollbar";
        SetParentAndAlign(scrollbar, template);

        Scrollbar scrollbarScrollbar = scrollbar.GetComponent<Scrollbar>();
        scrollbarScrollbar.SetDirection(Scrollbar.Direction.BottomToTop, true);

        RectTransform vScrollbarRT = scrollbar.GetComponent<RectTransform>();
        vScrollbarRT.anchorMin = Vector2.right;
        vScrollbarRT.anchorMax = Vector2.one;
        vScrollbarRT.pivot = Vector2.one;
        vScrollbarRT.sizeDelta = new Vector2(vScrollbarRT.sizeDelta.x, 0);

        // Setup item UI components.
        Text itemLabelText = itemLabel.AddComponent<Text>();
        SetDefaultTextValues(itemLabelText);
        itemLabelText.alignment = TextAnchor.MiddleLeft;

        Image itemBackgroundImage = itemBackground.AddComponent<Image>();
        itemBackgroundImage.color = new Color32(245, 245, 245, 255);
        
        Button itemButton = item.AddComponent<Button>();
        itemButton.targetGraphic = itemBackgroundImage;

        // Setup template UI components.

        Image templateImage = template.AddComponent<Image>();
        templateImage.sprite = resources.standard;
        templateImage.type = Image.Type.Sliced;

        ScrollRect templateScrollRect = template.AddComponent<ScrollRect>();
        templateScrollRect.content = (RectTransform)content.transform;
        templateScrollRect.viewport = (RectTransform)viewport.transform;
        templateScrollRect.horizontal = false;
        templateScrollRect.movementType = ScrollRect.MovementType.Clamped;
        templateScrollRect.verticalScrollbar = scrollbarScrollbar;
        templateScrollRect.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
        templateScrollRect.verticalScrollbarSpacing = -3;

        Mask scrollRectMask = viewport.AddComponent<Mask>();
        scrollRectMask.showMaskGraphic = false;

        Image viewportImage = viewport.AddComponent<Image>();
        viewportImage.sprite = resources.mask;
        viewportImage.type = Image.Type.Sliced;
        
        // Setting default Item list.
        itemLabelText.text = "Option A";
        inputField.AddOption("Option A");
        inputField.AddOption("Option B");
        inputField.AddOption("Option C");

        // Set up RectTransforms.
        RectTransform templateRT = template.GetComponent<RectTransform>();
        templateRT.anchorMin = new Vector2(0, 0);
        templateRT.anchorMax = new Vector2(1, 0);
        templateRT.pivot = new Vector2(0.5f, 1);
        templateRT.anchoredPosition = new Vector2(0, 2);
        templateRT.sizeDelta = new Vector2(0, 150);

        RectTransform viewportRT = viewport.GetComponent<RectTransform>();
        viewportRT.anchorMin = new Vector2(0, 0);
        viewportRT.anchorMax = new Vector2(1, 1);
        viewportRT.sizeDelta = new Vector2(-18, 0);
        viewportRT.pivot = new Vector2(0, 1);

        RectTransform contentRT = content.GetComponent<RectTransform>();
        contentRT.anchorMin = new Vector2(0f, 1);
        contentRT.anchorMax = new Vector2(1f, 1);
        contentRT.pivot = new Vector2(0.5f, 1);
        contentRT.anchoredPosition = new Vector2(0, 0);
        contentRT.sizeDelta = new Vector2(0, 28);

        RectTransform itemRT = item.GetComponent<RectTransform>();
        itemRT.anchorMin = new Vector2(0, 0.5f);
        itemRT.anchorMax = new Vector2(1, 0.5f);
        itemRT.sizeDelta = new Vector2(0, 20);

        RectTransform itemBackgroundRT = itemBackground.GetComponent<RectTransform>();
        itemBackgroundRT.anchorMin = Vector2.zero;
        itemBackgroundRT.anchorMax = Vector2.one;
        itemBackgroundRT.sizeDelta = Vector2.zero;

        RectTransform itemLabelRT = itemLabel.GetComponent<RectTransform>();
        itemLabelRT.anchorMin = Vector2.zero;
        itemLabelRT.anchorMax = Vector2.one;
        itemLabelRT.offsetMin = new Vector2(20, 1);
        itemLabelRT.offsetMax = new Vector2(-10, -2);

        template.SetActive(false);
        
        inputField.template = templateRT;

        return root;
    }

    private static GameObject CreateUIElementRoot(string name, Vector2 size)
    {
        GameObject child = new GameObject(name);
        RectTransform rectTransform = child.AddComponent<RectTransform>();
        rectTransform.sizeDelta = size;
        return child;
    }

    private static GameObject CreateUIObject(string name, GameObject parent)
    {
        GameObject go = new GameObject(name);
        go.AddComponent<RectTransform>();
        SetParentAndAlign(go, parent);
        return go;
    }

    private static void SetParentAndAlign(GameObject child, GameObject parent)
    {
        if (parent == null)
            return;

        child.transform.SetParent(parent.transform, false);
        SetLayerRecursively(child, parent.layer);
    }

    private static void SetLayerRecursively(GameObject go, int layer)
    {
        go.layer = layer;
        Transform t = go.transform;
        for (int i = 0; i < t.childCount; i++)
            SetLayerRecursively(t.GetChild(i).gameObject, layer);
    }

    private static void SetDefaultColorTransitionValues(Selectable slider)
    {
        ColorBlock colors = slider.colors;
        colors.highlightedColor = new Color(0.882f, 0.882f, 0.882f);
        colors.pressedColor = new Color(0.698f, 0.698f, 0.698f);
        colors.disabledColor = new Color(0.521f, 0.521f, 0.521f);
    }

    private static void SetDefaultTextValues(Text lbl)
    {
        // Set text values we want across UI elements in default controls.
        // Don't set values which are the same as the default values for the Text component,
        // since there's no point in that, and it's good to keep them as consistent as possible.
        lbl.color = s_TextColor;

        // Reset() is not called when playing. We still want the default font to be assigned
        //lbl.AssignDefaultFont();
    }
    #endregion
}
  1. 使用方法
// 组件引用
public SearchInputField searchInputField; 
// 添加联想词组
string[] strs = new string[] { "AAA", "BBB", "CCC" };
searchInputField.ClearOptions();
searchInputField.AddOptions(strs);
// 侦听选择匹配词组的事件
searchInputField.onMatched.AddListener(txt => { Debug.Log(txt); });
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值