首页 > 其他分享 >ugui学习 - 自己实现InputField鼠标点击调整光标位置,拖拽修改选中区域

ugui学习 - 自己实现InputField鼠标点击调整光标位置,拖拽修改选中区域

时间:2023-07-31 23:33:50浏览次数:44  
标签:InputField return textGen int Text eventData ugui line 光标

效果

 

代码

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class MyInputField_CaretDragOp : MyInputField_TextSelect, IDragHandler, IPointerDownHandler
{

    public void OnPointerDown(PointerEventData eventData)
    {
        if (!isActiveAndEnabled) return;
        if (eventData.button != PointerEventData.InputButton.Left) return;
        if (null == m_Text) return;

        Vector2 localPosInText; //相对Text的local坐标, 以Text的pivot为原点
        RectTransformUtility.ScreenPointToLocalPointInRectangle(m_Text.rectTransform, eventData.position, eventData.pressEventCamera, out localPosInText);
        m_CaretPos = m_SelectPos = GetCharIndexFromPosition(localPosInText);
        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); //下一帧统一更新光标
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (!isActiveAndEnabled) return;
        if (eventData.button != PointerEventData.InputButton.Left) return;
        if (null == m_Text) return;

        Vector2 localPosInText; //相对Text的local坐标, 以Text的pivot为原点
        RectTransformUtility.ScreenPointToLocalPointInRectangle(m_Text.rectTransform, eventData.position, eventData.pressEventCamera, out localPosInText);
        m_SelectPos = GetCharIndexFromPosition(localPosInText);
        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); //下一帧统一更新光标

        eventData.Use();
    }

    /// <summary>
    /// 该行最后一个字符的索引
    /// </summary>
    private static int GetLineEndCharIndex(TextGenerator textGen, int line)
    {
        line = Mathf.Max(line, 0);
        int nextLine = line + 1;
        if (nextLine < textGen.lines.Count)
            return textGen.lines[nextLine].startCharIdx - 1; //下一行结束字符的前一个字符

        return textGen.characterCountVisible;
    }

    private int GetCharLineFromPosition(TextGenerator textGen, Vector2 localPos)
    {
        float localPosY = localPos.y * m_Text.pixelsPerUnit;
        float lastLineBottomY = 0.0f;

        for (int i = 0; i < textGen.lineCount; ++i)
        {
            var tLineInfo = textGen.lines[i];
            float lineTopY = tLineInfo.topY;
            float lineBottomY = lineTopY - tLineInfo.height; //往下为减

            if (localPosY > lineTopY)
            {
                float halfLeading = (lineTopY - lastLineBottomY) * 0.5f; //行间距
                if (localPosY > (lineTopY - halfLeading)) //超过行间距一半, 算上一行
                    return i - 1;
                else
                    return i;
            }

            if (localPosY > lineBottomY)
                return i;

            lastLineBottomY = lineBottomY;
        }

        return textGen.lineCount; //没找到, 用最后一行
    }

    protected int GetCharIndexFromPosition(Vector2 localPos)
    {
        TextGenerator textGen = m_Text.cachedTextGenerator;

        if (0 == textGen.lineCount)
            return 0;

        int line = GetCharLineFromPosition(textGen, localPos);
        if (line < 0)
            return 0;

        if (line >= textGen.lineCount)
            return textGen.characterCountVisible;

        int startCharIndex = textGen.lines[line].startCharIdx;
        int endCharIndex = GetLineEndCharIndex(textGen, line);

        //在找到的行的字符间找
        for (int i = startCharIndex; i < endCharIndex; i++)
        {
            if (i >= textGen.characterCountVisible)
                break;

            UICharInfo charInfo = textGen.characters[i];
            Vector2 charPos = charInfo.cursorPos / m_Text.pixelsPerUnit;

            //以字符宽度一半为前后字符的分界
            if (localPos.x <= (charPos.x + charInfo.charWidth * 0.5f / m_Text.pixelsPerUnit))
                return i;
        }

        return endCharIndex;
    }

}

 

标签:InputField,return,textGen,int,Text,eventData,ugui,line,光标
From: https://www.cnblogs.com/sailJs/p/17588457.html

相关文章

  • ugui学习 - 自己实现InputField的文本选中
    效果 代码把光标闪烁拿掉了usingUnityEngine;usingUnityEngine.UI;[DisallowMultipleComponent][RequireComponent(typeof(CanvasRenderer))][RequireComponent(typeof(RectTransform))]publicclassMyInputField_TextSelect:MonoBehaviour,ICanvasElement{......
  • Unity UGUI的Shadow(阴影)组件的介绍及使用
    UnityUGUI的Shadow(阴影)组件的介绍及使用1.什么是Shadow(阴影)组件?Shadow(阴影)组件是UnityUGUI中的一个特效组件,用于在UI元素上添加阴影效果。通过调整阴影的颜色、偏移、模糊等属性,可以使UI元素看起来更加立体和有层次感。2.Shadow(阴影)组件的工作原理Shadow(阴影)组件......
  • Unity UGUI的Outline(描边)组件的介绍及使用
    UnityUGUI的Outline(描边)组件的介绍及使用1.什么是Outline(描边)组件?Outline(描边)组件是UnityUGUI中的一种特效组件,用于给UI元素添加描边效果。通过设置描边的颜色、宽度和模糊程度,可以使UI元素在视觉上更加突出。2.Outline(描边)组件的工作原理Outline(描边)组件通过在U......
  • Unity UGUI的Outline(描边)组件的介绍及使用
    UnityUGUI的Outline(描边)组件的介绍及使用1.什么是Outline(描边)组件?Outline(描边)组件是UnityUGUI中的一种特效组件,用于给UI元素添加描边效果。通过设置描边的颜色、宽度和模糊程度,可以使UI元素在视觉上更加突出。2.Outline(描边)组件的工作原理Outline(描边)组件通过在......
  • ugui学习 - 自己实现InputField光标的显示,闪烁,左右移动
    最终效果 代码usingSystem.Collections;usingUnityEngine;usingUnityEngine.UI;[DisallowMultipleComponent][RequireComponent(typeof(CanvasRenderer))][RequireComponent(typeof(RectTransform))]publicclassMyInputField_Caret:MonoBehaviour,ICanvasEle......
  • Unity UGUI的Physics2DRaycaster (2D物理射线检测)组件的介绍及使用
    UnityUGUI的Physics2DRaycaster(2D物理射线检测)组件的介绍及使用一、什么是Physics2DRaycaster组件?Physics2DRaycaster是Unity中的一个UGUI组件,用于在2D场景中进行物理射线检测。它可以检测鼠标或触摸事件在UI元素上的碰撞,并将事件传递给相应的UI元素。二、Physics2DRaycaste......
  • Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用
    UnityUGUI的PhysicsRaycaster(物理射线检测)组件的介绍及使用1.什么是PhysicsRaycaster组件?PhysicsRaycaster是UnityUGUI中的一个组件,用于在UI元素上进行物理射线检测。它可以检测鼠标或触摸事件是否发生在UI元素上,并将事件传递给相应的UI元素。2.PhysicsRaycaster的工作......
  • ugui源码阅读 - Graphic渲染原理
    3d部分使用MeshRenderer来渲染,ugui的使用CanvasRenderer来进行渲染。把顶点,材质,贴图设置给CanvasRenderer,就能渲染出来了。 下面的代码,我们直接使用CanvasRenderer来进行渲染,等同于Graphic渲染部分的核心代码。usingUnityEngine;usingUnityEngine.UI;[RequireComponent(......
  • Unity UGUI的EventSystem(事件系统)组件的介绍及使用
    UnityUGUI的EventSystem(事件系统)组件的介绍及使用1.什么是EventSystem组件?EventSystem是UnityUGUI中的一个重要组件,用于处理用户输入事件,如点击、拖拽、滚动等。它负责将用户输入事件传递给合适的UI元素,并触发相应的事件回调函数。2.EventSystem组件的工作原理EventSystem......
  • Unity UGUI的EventSystem(事件系统)组件的介绍及使用
    UnityUGUI的EventSystem(事件系统)组件的介绍及使用1.什么是EventSystem组件?EventSystem是UnityUGUI中的一个重要组件,用于处理用户输入事件,如点击、拖拽、滚动等。它负责将用户输入事件传递给合适的UI元素,并触发相应的事件回调函数。2.EventSystem组件的工作原理EventSystem......