You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何实现行号Text与InputField文本同步滚动?

Unity代码编辑器行号同步滚动解决方案

嘿,我刚好在Unity里做过类似的代码编辑器行号功能,给你梳理下具体的实现思路和解决方法:

关于InputField的滚动相关变量与函数

Unity的InputField本身并没有直接暴露滚动距离的公共变量,但如果你的InputField是多行带滚动条(Multi Line with Scrollbar)模式,它会自动嵌套在一个ScrollRect组件中。你可以通过这个ScrollRect来获取和控制滚动状态:

  • ScrollRect.verticalNormalizedPosition:这是归一化的滚动位置(值范围0到1,1表示滚动到顶部,0表示底部),是同步滚动的核心变量。
  • ScrollRect.content.anchoredPosition:可以获取内容区域的实际滚动偏移量(单位是像素)。
  • 你可以监听ScrollRect.onValueChanged事件,在滚动发生时触发同步逻辑,不需要每帧轮询,效率更高。

行号与InputField的关联实现

当然需要建立关联,而且要从行号内容更新和滚动位置同步两个维度来处理:

1. 布局准备

  • 把行号的Text对象放在和InputField同一个ScrollRect的Viewport中,和InputField并排布局(比如用Horizontal Layout Group,固定行号Text的宽度,让InputField占剩余宽度)。
  • 确保行号Text和InputField内部的Text组件使用相同的字体、行高和字号,这样行号才能和代码行精准对齐。

2. 核心同步代码

写一个简单的脚本,挂载到场景中的任意GameObject(比如ScrollRect本身),关联好对应的组件:

using UnityEngine;
using UnityEngine.UI;
using System.Text;

public class LineNumberSync : MonoBehaviour
{
    [Header("关联组件")]
    public InputField codeInputField;
    public Text lineNumberText;
    
    private ScrollRect _scrollRect;
    private Text _inputTextComponent;

    void Awake()
    {
        // 获取InputField所在的ScrollRect
        _scrollRect = codeInputField.GetComponentInParent<ScrollRect>();
        // 获取InputField内部负责显示文本的Text组件
        _inputTextComponent = codeInputField.textComponent;
        
        // 监听滚动变化和文本内容变化
        _scrollRect.onValueChanged.AddListener(SyncLineNumberPosition);
        codeInputField.onValueChanged.AddListener(UpdateLineNumberContent);
        
        // 初始化行号
        UpdateLineNumberContent(codeInputField.text);
    }

    // 更新行号的内容(根据文本行数生成对应数字)
    void UpdateLineNumberContent(string newText)
    {
        // 处理换行符,兼容不同格式的换行
        string[] lines = newText.Split(new char[] {'\n', '\r'}, System.StringSplitOptions.RemoveEmptyEntries);
        StringBuilder lineNumberBuilder = new StringBuilder();
        
        for (int i = 1; i <= lines.Length; i++)
        {
            lineNumberBuilder.AppendLine(i.ToString());
        }
        
        lineNumberText.text = lineNumberBuilder.ToString().TrimEnd('\n');
        // 内容更新后同步一次滚动位置
        SyncLineNumberPosition(_scrollRect.normalizedPosition);
    }

    // 同步行号的滚动位置
    void SyncLineNumberPosition(Vector2 normalizedScrollPos)
    {
        // 计算输入框文本的总高度和视口高度
        float totalTextHeight = _inputTextComponent.preferredHeight;
        float viewportHeight = _scrollRect.viewport.rect.height;
        
        // 计算行号文本需要偏移的垂直距离
        float verticalOffset = (totalTextHeight - viewportHeight) * (1 - normalizedScrollPos.y);
        // 保持行号的X位置不变,只修改Y偏移
        lineNumberText.rectTransform.anchoredPosition = new Vector2(
            lineNumberText.rectTransform.anchoredPosition.x, 
            verticalOffset
        );
    }
}

3. 关键注意事项

  • 确保InputField内部的Text组件的Vertical Overflow设置为Overflow,这样文本内容超出视口后才能被ScrollRect滚动。
  • 如果你的InputField是手动嵌套在ScrollRect中的(不是用Unity自带的Multi Line Scroll模式),要确保ScrollRect.content指向包含InputField的容器,同时InputField的高度设置为Preferred Size或者足够大。
  • 对于大文本,建议限制最大行数或者做性能优化(比如只显示视口内的行号),避免行号Text的内容过长导致卡顿。

内容的提问来源于stack exchange,提问作者cegredev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:20:15