IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> UNITY3D UGUI TEXT 文本字间隔( 支持RICHTEXT、WARP换行与PREFEREDWIDTH) -> 正文阅读

[游戏开发]UNITY3D UGUI TEXT 文本字间隔( 支持RICHTEXT、WARP换行与PREFEREDWIDTH)

UNITY3D UGUI 字间隔

项目有遇到Text字间隔的问题 可惜ugui原生不支持 参考网络上的脚本做了一版

效果

思路

1.依赖内置的cachedTextGenerator,通过其生成的每行数据取得对应的Vertex初始点并在生成顶点时对每个有效字体的六个顶点进行偏移操作.
2.对于富文本组件需要在生成Vertex节点时使用正则表达式提取忽略的Vertex初始点.
3.ContentSizeFitter组件需要获取PreferedWidth,TextGenerator.生成数据的最大行数算出额外Width与基础Width叠加

脚本

可以直接放到项目里使用

1.由于覆写Text 使用时请添加UIT_TextExtend而不是Text

using UnityEngine.UI;
using UnityEngine;
using System.Collections.Generic;
using System.Text.RegularExpressions;

[AddComponentMenu("UI/Text_Extend",0)]
public class UIT_TextExtend : Text
{
    public int m_characterSpacing;
	//正则表达式参数
    private const string m_RichTextRegexPatterns = @"<b>|</b>|<i>|</i>|<size=.*?>|</size>|<Size=.*?>|</Size>|<color=.*?>|</color>|<Color=.*?>|</Color>|<material=.*?>|</material>";
   
   //ContentSizeFitter的PreferdWidth获取
    public override float preferredWidth
    {
        get
        {
        	//获取初始宽度
            float preferredWidth= cachedTextGenerator.GetPreferredWidth(text, GetGenerationSettings( Vector2.zero));
            
            //根据生成的有效初始顶点数据获得最大行数的初始顶点数量
            List<List<int>> linesVertexStartIndexes = GetLinesVertexStartIndexes();
            int maxLineCount = 0;
            for (int i=0;i<linesVertexStartIndexes.Count;i++)
                maxLineCount = Mathf.Max(maxLineCount, linesVertexStartIndexes[i].Count);
                
            return preferredWidth + m_characterSpacing * (maxLineCount - 1);
        }
    } 
	
	//定点生成覆写
    //当前使用的字数像素偏移方案为(字数*偏移值) 请根据需求自行配置
    protected override void OnPopulateMesh(VertexHelper toFill)
    {
        base.OnPopulateMesh(toFill);
        if (m_characterSpacing == 0)
            return;
        List<UIVertex> vertexes = new List<UIVertex>();
        toFill.GetUIVertexStream(vertexes);

        List<List<int>> linesVertexStartIndexes = GetLinesVertexStartIndexes();
        float alignmentFactor = GetAlignmentFactor();

        for (int i = 0; i < linesVertexStartIndexes.Count; i++)
        {
        	//行偏移(左中右) 
            float lineOffset = (linesVertexStartIndexes[i].Count - 1) * m_characterSpacing * alignmentFactor;
            for (int j = 0; j < linesVertexStartIndexes[i].Count; j++)
            {
                int vertexStartIndex = linesVertexStartIndexes[i][j];
                Vector3 offset = Vector3.right * ((m_characterSpacing * j) - lineOffset);
                //对每个有效字体的六个顶点偏移
                AddVertexOffset(vertexes, vertexStartIndex + 0, offset);
                AddVertexOffset(vertexes, vertexStartIndex + 1, offset);
                AddVertexOffset(vertexes, vertexStartIndex + 2, offset);
                AddVertexOffset(vertexes, vertexStartIndex + 3, offset);
                AddVertexOffset(vertexes, vertexStartIndex + 4, offset);
                AddVertexOffset(vertexes, vertexStartIndex + 5, offset);
            }
        }

        toFill.Clear();
        toFill.AddUIVertexTriangleStream(vertexes);
    }
	//对顶点进行偏移
    void AddVertexOffset(List<UIVertex> vertexes,int index,Vector3 offset)
    {
        UIVertex vertex = vertexes[index];
        vertex.position += offset;
        vertexes[index] = vertex;
    }
	//获取有效的初始顶点
    List<List<int>> GetLinesVertexStartIndexes()
    {
        List<List<int>> linesVertexIndexes = new List<List<int>>();
        IList<UILineInfo> lineInfos = cachedTextGenerator.lines;
        for(int i=0;i<lineInfos.Count;i++)
        {
            List<int> lineVertexStartIndex = new List<int>();
            int lineStart = lineInfos[i].startCharIdx;
            int lineLength = (i < lineInfos.Count - 1) ? lineInfos[i + 1].startCharIdx - lineInfos[i].startCharIdx:text.Length - lineInfos[i].startCharIdx;
            
			//Rich Text根据正则表达式获取需要忽略的初始顶点
            List<int> ignoreIndexes = new List<int>();
            if (supportRichText)
            {
                string line = text.Substring(lineStart, lineLength);
                foreach (Match matchTag in Regex.Matches(line, m_RichTextRegexPatterns))
                {
                    for(int j=0;j<matchTag.Length;j++)
                        ignoreIndexes.Add(matchTag.Index + j);
                }
            }

            for (int j = 0; j < lineLength; j++)
                if (!ignoreIndexes.Contains(j))
                    lineVertexStartIndex.Add((lineStart+j)*6);

            linesVertexIndexes.Add(lineVertexStartIndex);
        }
        return linesVertexIndexes;
    }
	
	//获取行偏移比例参数
    float GetAlignmentFactor()
    {
        switch (alignment)
        {
            default:
                Debug.LogError("Invalid Convertions Here!");
                return 0;
            case TextAnchor.UpperLeft:
            case TextAnchor.MiddleLeft:
            case TextAnchor.LowerLeft:
                return 0;
            case TextAnchor.UpperCenter:
            case TextAnchor.MiddleCenter:
            case TextAnchor.LowerCenter:
                return .5f;
            case TextAnchor.UpperRight:
            case TextAnchor.MiddleRight:
            case TextAnchor.LowerRight:
                return 1f;
        }

    }
}

2.编辑器脚本(便于编辑器配置数据,放到Editor文件夹下)

[CustomEditor(typeof(UIT_TextExtend)),CanEditMultipleObjects]
public class EUITextExtend : UnityEditor.UI.TextEditor
{
    UIT_TextExtend m_target = null;
    public override void OnInspectorGUI()
    {
        m_target = target as UIT_TextExtend;

        EditorGUILayout.BeginHorizontal();
        int spacing = EditorGUILayout.IntField("Character Spacing:", m_target.m_characterSpacing);
        if (spacing != m_target.m_characterSpacing)
        {
            Undo.RecordObject(m_target,"Character Spacing");
            m_target.m_characterSpacing = spacing;
            m_target.SetAllDirty();
        }
        EditorGUILayout.EndHorizontal();

        base.OnInspectorGUI();
    }
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 11:32:18  更:2021-08-03 11:32:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 13:05:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码