using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
class UnderlineProperty
{
public Color _color;
public Vector3 _position;
public float _width;
public float _height;
public Vector2 _privot;
}
///
/// 添加下划线
///
public class LinkText : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
private Text _text;
private int _curCharacterCount = 0;
private List _lines = new List();
private System.Action _clickEvent = null; //下划线点击事件
private bool _isInitUnderline = false;
private int text_length;
void Start()
{
_text = transform.GetComponent();
text_length = CalculateLengthOfText(_text.text, _text);
}
void Update()
{
//做初始化
if (_text.cachedTextGenerator.lineCount > 0 && !_isInitUnderline)
{
_isInitUnderline = true;
_curCharacterCount = _text.cachedTextGenerator.characterCount;
List list = GetUnderlinePropertys();
CreateUnderLines(list);
int avg = text_length / _lines.Count;
for (int i = 0; i < _lines.Count; i++)
{
_lines[i].rectTransform.sizeDelta = new Vector2(avg, _lines[i].rectTransform.sizeDelta.y);
}
}
//刷新
if (_isInitUnderline && _curCharacterCount != _text.cachedTextGenerator.characterCount)
{
_curCharacterCount = _text.cachedTextGenerator.characterCount;
List list = GetUnderlinePropertys();
CreateUnderLines(list);
int avg = text_length / _lines.Count;
for (int i = 0; i < _lines.Count; i++)
{
_lines[i].rectTransform.sizeDelta = new Vector2(avg, _lines[i].rectTransform.sizeDelta.y);
}
}
}
List GetUnderlinePropertys()
{
List list = new List();
for (int i = 0; i < _text.cachedTextGenerator.lineCount; i++)
{
var curPos = _text.cachedTextGenerator.characters[_text.cachedTextGenerator.lines[i].startCharIdx].cursorPos;
UnderlineProperty property = new UnderlineProperty
{
_color = _text.color,
_height = _text.fontSize / 10 == 0 ? 1 : _text.fontSize / 10,
_width = GetWidth(_text.cachedTextGenerator.lines[i].startCharIdx, _text.cachedTextGenerator.characters),
_position = new Vector3(curPos.x, curPos.y - _text.cachedTextGenerator.lines[i].height, 0),
_privot = GetTextAnchorPivot(_text.alignment)
};
list.Add(property);
}
return list;
}
float GetWidth(int idx, IList info)
{
float width = 0;
float start = info[idx].cursorPos.x;
for (int i = idx; i < info.Count - 1; i++)
{
if (info[i].cursorPos.x > info[i + 1].cursorPos.x)
{
width = info[i].cursorPos.x - start;
break;
}
if (info.Count - 1 == i + 1)
width = info[i + 1].cursorPos.x - start;
}
return width;
}
Vector2 GetTextAnchorPivot(TextAnchor anchor)
{
switch (anchor)
{
case TextAnchor.LowerLeft: return new Vector2(0, 0);
case TextAnchor.LowerCenter: return new Vector2(0.5f, 0);
case TextAnchor.LowerRight: return new Vector2(1, 0);
case TextAnchor.MiddleLeft: return new Vector2(0, 0.5f);
case TextAnchor.MiddleCenter: return new Vector2(0.5f, 0.5f);
case TextAnchor.MiddleRight: return new Vector2(1, 0.5f);
case TextAnchor.UpperLeft: return new Vector2(0, 1);
case TextAnchor.UpperCenter: return new Vector2(0.5f, 1);
case TextAnchor.UpperRight: return new Vector2(1, 1);
default: return Vector2.zero;
}
}
void CreateUnderLines(List list)
{
for (int i = 0; i < transform.childCount; i++)
Destroy(transform.GetChild(i).gameObject);
_lines.Clear();
for (int i = 0; i < list.Count; i++)
{
//初始化
GameObject obj = new GameObject();
obj.transform.SetParent(transform, false);
obj.name = "underline" + i;
_lines.Add(obj.AddComponent());
_lines[i].rectTransform.pivot = list[i]._privot;
//颜色和大小
var tex = new Texture2D((int)list[i]._width, (int)list[i]._height, TextureFormat.ARGB32, false);
Color[] colors = tex.GetPixels();
for (int j = 0; j < colors.Length; j++)
colors[j] = list[i]._color;
tex.SetPixels(colors);
tex.Apply();
_lines[i].sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
_lines[i].SetNativeSize();
_lines[i].rectTransform.sizeDelta = new Vector2(_lines[i].rectTransform.sizeDelta.x, _lines[i].rectTransform.sizeDelta.y);
//坐标
float x = list[i]._position.x;
if (_text.alignment == TextAnchor.MiddleCenter || _text.alignment == TextAnchor.UpperCenter || _text.alignment == TextAnchor.LowerCenter)
x = 0;
if (_text.alignment == TextAnchor.MiddleRight || _text.alignment == TextAnchor.UpperRight || _text.alignment == TextAnchor.LowerRight)
x += list[i]._width;
_lines[i].rectTransform.anchoredPosition = new Vector2(x, list[i]._position.y);
}
}
/*实现下划线同步点击效果*/
public void OnPointerDown(PointerEventData eventData)
{
for (int i = 0; i < _lines.Count; i++)
{
Color[] colors = _lines[i].sprite.texture.GetPixels();
for (int j = 0; j < colors.Length; j++)
colors[j] = new Color(colors[j].r, colors[j].g, colors[j].b, colors[j].a * 0.70f);
_lines[i].sprite.texture.SetPixels(colors);
_lines[i].sprite.texture.Apply();
}
}
public void OnPointerUp(PointerEventData eventData)
{
for (int i = 0; i < _lines.Count; i++)
{
Color[] colors = _lines[i].sprite.texture.GetPixels();
for (int j = 0; j < colors.Length; j++)
colors[j] = new Color(colors[j].r, colors[j].g, colors[j].b, colors[j].a / 0.70f);
_lines[i].sprite.texture.SetPixels(colors);
_lines[i].sprite.texture.Apply();
}
}
int CalculateLengthOfText(string message, Text tex)
{
int totalLength = 0;
Font myFont = tex.font; //chatText is my Text component
myFont.RequestCharactersInTexture(message, tex.fontSize, tex.fontStyle);
CharacterInfo characterInfo = new CharacterInfo();
char[] arr = message.ToCharArray();
foreach (char c in arr)
{
myFont.GetCharacterInfo(c, out characterInfo, tex.fontSize);
totalLength += characterInfo.advance;
}
return totalLength;
}
}