TextMeshPro 특정단어 Click 이벤트
( HyperText / Text Click)
Text의 특정 단어를 클릭하면 처리하는 하이퍼텍스트(클릭시 링크) 하는 기능이 필요해서
사용방법을 간단하게 포스팅한다.
Text에 다음과 같은 형태로 작업하면 된다.
<link="ID">Click Action</link>
반응형
여기서 "ID" 라고하는건 고유하게 식별이 가능하기 위한 텍스트로 가독성있는 단어로 하면 된다.
해당 스크립트를 추가하고 이벤트에 대한 설정을 하면 된다.
< TextMeshProTextLink 스크립트 >
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// Text Link Tag Event Class
/// </summary>
[RequireComponent(typeof(TextMeshProUGUI))]
public class TextMeshProTextLink : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
private bool Validtext = false;
private bool IsClick = false;
[SerializeField]
private TextMeshProUGUI linkText;
public TextMeshProUGUI LinkText
{
get
{
return linkText;
}
set
{
linkText = value;
}
}
private int currenthoverID = -1;
private Dictionary<int, Action> hoverAction = new Dictionary<int, Action>();
private Dictionary<int, Action> leaveAction = new Dictionary<int, Action>();
private Dictionary<int, Action> clickAction = new Dictionary<int, Action>();
public void RegisterHoverOnID(string _id, Action _hoverAction, Action _leaveAction)
{
var index = TMP_TextUtilities.GetSimpleHashCode(_id);
hoverAction[index] = _hoverAction;
leaveAction[index] = _leaveAction;
}
public void RegisterClickAcion(string _id, Action _clickAction) => clickAction[TMP_TextUtilities.GetSimpleHashCode(_id)] = _clickAction;
public void OnPointerEnter(PointerEventData eventData) => Validtext = true;
public void OnPointerExit(PointerEventData eventData) => Validtext = false;
public void OnPointerClick(PointerEventData eventData)
{
int hoverdLinkIndex = TMP_TextUtilities.FindIntersectingLink(linkText, Input.mousePosition, Camera.main);
if (hoverdLinkIndex == -1)
return;
IsClick = true;
}
private void ExecuteID(Dictionary<int, Action> dict, int id)
{
if (dict.TryGetValue(id, out Action action))
action?.Invoke();
}
public void Clear()
{
Validtext = false;
IsClick = false;
currenthoverID = -1;
hoverAction.Clear();
leaveAction.Clear();
clickAction.Clear();
}
void LateUpdate()
{
if (Validtext)
{
int hoverdLinkIndex = TMP_TextUtilities.FindIntersectingLink(linkText, Input.mousePosition, Camera.main);
if (hoverdLinkIndex == -1)
{
if (currenthoverID != -1)
ExecuteID(leaveAction, currenthoverID);
currenthoverID = -1;
return;
}
int hoveredLinkHash = linkText.textInfo.linkInfo[hoverdLinkIndex].hashCode;
if (hoveredLinkHash != currenthoverID)
{
if (currenthoverID != -1)
ExecuteID(leaveAction, currenthoverID);
ExecuteID(hoverAction, hoveredLinkHash);
currenthoverID = hoveredLinkHash;
}
if (IsClick)
ExecuteID(clickAction, hoveredLinkHash);
IsClick = false;
}
}
}
< 테스트 코드 >
내용 | |
목표 | `Simple Click Function Text Code in TextMehsPro` Click 에 마우스를 올리면 컬러변경 (Red <> Blue), 클릭시 Google Home 으로 이동 |
기능은 Click 하는 기능과 Hover / Leave 에 대한 UnityAction 을 등록하는 코드이다.
[SerializeField]
private TextMeshProTextLink information = default;
[Header("Link")]
[SerializeField]
private string linkID = default;
[Header("치환할 단어")]
[SerializeField]
private string replaceWorld = default;
[SerializeField]
private UnityAction linkAction = default;
private void initializeAction()
{
if (IsVailed() == false)
return;
information.RegisterClickAcion(linkID, () => {
Debug.Log($"Text Link Click : {linkID} !!");
linkAction.Invoke();
});
information.RegisterHoverOnID(linkID, () =>
{
UpdateTextColor(Color.red);
},
() =>
{
UpdateTextColor(Color.blue);
});
private bool IsVailed()
{
if (information == null)
return false;
if (information.LinkText == null)
return false;
return true;
}
private void UpdateTextColor(Color _color)
{
if(IsVailed()==false)
return;
string contents = information.LinkText.text;
var result = contents.Replace(replaceWorld,
$"<color=#{ColorUtility.ToHtmlStringRGB(_color)}>{replaceWorld}</color>"
);
information.LinkText.text = result;
}
TextMeshPro -Text Link : [링크]
★☆☆
반응형
댓글