欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > unity 输入框 自己定义光标显示逻辑

unity 输入框 自己定义光标显示逻辑

2025/11/7 23:22:01 来源:https://blog.csdn.net/wanzhihui0000/article/details/148533237  浏览:    关键词:unity 输入框 自己定义光标显示逻辑

       实现一个输入框 光标一直闪烁的功能,

        public GameObject Cursor; //模拟光标
        private RectTransform cursorRectTrans;

        private float m_CaretBlinkRate = 0.85f;
        protected bool m_CaretVisible;
        private Coroutine m_BlinkCoroutine = null;
        private float m_BlinkStartTime = 0.0f;

       public void Awake()
       {

                  inputField = GetComponent<InputField>();

                 m_CaretBlinkRate = inputField.caretBlinkRate;

       }

        void OnEnable()
        {
            bool currentVisibility = inputField.isFocused && inputField.isActiveAndEnabled;
            if (!currentVisibility)
            {
                isRealCursorVisible = currentVisibility;
                SetCaretVisible();
            }
        }


        void SetCaretVisible()
        {
            m_CaretVisible = true;
            m_BlinkStartTime = Time.unscaledTime;
            SetCaretActive();
        }

        /// <summary>
        /// 自定义光标
        /// </summary>
        void SetCaretActive()
        {
            if (m_CaretBlinkRate > 0.0f)
            {
                if(m_BlinkCoroutine != null)
                {
                    StopCoroutine(m_BlinkCoroutine);
                }

                m_BlinkCoroutine = StartCoroutine(CaretBlink());
            }
            else
            {
                m_CaretVisible = true;
            }
        }

        void StopBlinkCoroutine()
        {
            if (m_BlinkCoroutine != null)
            {
                m_CaretVisible = false;
                Cursor.gameObject.SetActive(false);
                StopCoroutine(m_BlinkCoroutine);
                m_BlinkCoroutine = null;
            }
        }
        IEnumerator CaretBlink()
        {
            // Always ensure caret is initially visible since it can otherwise be confusing for a moment.
            m_CaretVisible = true;
            yield return null;

            while (!inputField.isFocused && m_CaretBlinkRate > 0)
            {
                // the blink rate is expressed as a frequency
                float blinkPeriod = 1f / m_CaretBlinkRate;

                // the caret should be ON if we are in the first half of the blink period
                bool blinkState = (Time.unscaledTime - m_BlinkStartTime) % blinkPeriod < blinkPeriod / 2;
                if (m_CaretVisible != blinkState)
                {
                    m_CaretVisible = blinkState;
                }

                // Then wait again.
                yield return null;
            }
            m_BlinkCoroutine = null;
        }
        void Update()
        {
            //Debug.Log("当前光标位置:" + inputField.caretPosition);

            // 检测系统光标显隐变化 [1,5](@ref)
            bool currentVisibility = inputField.isFocused && inputField.isActiveAndEnabled;
            if (currentVisibility != isRealCursorVisible)
            {
                isRealCursorVisible = currentVisibility;
                if (!isRealCursorVisible)
                    SetCaretVisible();
                else
                    StopBlinkCoroutine();
            }

            if (!isRealCursorVisible && !inputField.isFocused)
            {
                Cursor.gameObject.SetActive(m_CaretVisible);
                UpdateCustomCursorPosition();
            }
            else
            {
                Cursor.gameObject.SetActive(false);
            }
        }

        void UpdateCustomCursorPosition()
        {
            // 获取文本组件及光标索引 [6,7](@ref)
            TextGenerator gen = inputField.textComponent.cachedTextGenerator;
            int caretPos = inputField.caretPosition;

            // 计算光标在文本中的局部坐标
            Vector2 cursorLocalPos;
            if (caretPos > 0 && caretPos <= gen.characterCountVisible)
            {
                UICharInfo charInfo = gen.characters[caretPos - 1];
                cursorLocalPos = new Vector2(charInfo.cursorPos.x, 0);
            }
            else
            {
                if(gen.characterCountVisible > 0)
                {
                    UICharInfo charInfo = gen.characters[gen.characterCountVisible - 1];
                    cursorLocalPos = new Vector2(charInfo.cursorPos.x + charInfo.charWidth,charInfo.cursorPos.y - (inputField.textComponent.fontSize * 0.5f + 5));
                    // 转换为屏幕坐标 [4](@ref)
                    Vector2 screenPos = inputField.textComponent.transform.TransformPoint(cursorLocalPos);
                    cursorRectTrans.transform.position = screenPos;
                }
                else
                {
                    cursorLocalPos = Vector2.zero; // 处理边界情况
                    cursorRectTrans.anchoredPosition = cursorLocalPos;
                }
            }


        }

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词