게임 중에 특정 텍스트에 마우스를 올리면 툴팁이 보이는 기능이 있었다.
처음에는 TooltipTrigger를 가진 빈 오브젝트의 위치를 특정 텍스트에 맞춰 옮겨 툴팁을 구현한 줄 알았다.
하지만, 구글링을 하다보니 link 리치 텍스트 태그를 사용하여 특정 텍스트에 툴팁을 적용할 수 있다는 사실을 깨닫게 되었다.
이번 글에서는 link 리치 텍스트 태그에 대해 공부한 내용을 정리해보고자 한다.
리치 텍스트 태그는 TextMeshPro에서 텍스트에 스타일을 입히기 위해 사용하는 마크업 태그이다.
그 중, link 태그는 하이퍼링크처럼 사용하라고 제공된 태그로 스크립트를 통해 link 태그의 ID와 감싸진 Text에 접근하여 다양한 로직을 실행시킬 수 있다.
<link="ID">Text</link>
스크립트에서 link 태그에 접근하는 방법으로는 TMP_TextUtilities 클래스에서 찾을 수 있다.
아래 이미지를 보면 정말 다양한 메서드들이 있지만 나는 FindIntersectingLink와 IsIntersectingRectTransform를 사용하였다.
FindIntersectingLink는 현재 마우스의 위치가 link 태그로 감싸진 텍스트 위에 있다면 몇 번째 link 태그인지 반환한다.
link 위에 마우스가 없다면 -1을 반환한다.
여기서 문제는 FindIntersectingLink는 텍스트 내부의 모든 링크 정보를 순회하고, 문자들의 위치, 크기, visible 여부 등을 계산해서 충돌을 체크한다는 것이다. 이는 상당한 비용이 들어간다.
이를 해결하기 위해, IsIntersectingRectTransform를 사용할 수 있는데, 이 메서드는 단순히 텍스트의 RectTransform 내부에 마우스가 존재하는지 판단하는 메서드이기 때문이다.
매 프레임 실행되야 하기에 최적화를 위해, IsIntersectingRectTransform로 선체크를 한 후에, FindIntersectingLink로 선택된 링크를 받는 방식으로 사용하였다.
※ Camera 매개변수는 3D 환경에 있는 텍스트에 사용할 경우 넣어주어야 한다. 2D에서는 Null을 넣어주어도 된다.
private void LateUpdate()
{
Vector3 mousePos = Input.mousePosition;
// 변경 없으면 아무것도 하지 않음
if (_lastMousePosition == mousePos && _cachedLinkIndex == -1)
return;
_lastMousePosition = mousePos;
// 마우스가 텍스트 영역 안에 없다면
if (TMP_TextUtilities.IsIntersectingRectTransform(_text.rectTransform, mousePos, null) == false)
{
ResetTooltip();
return;
}
// 몇 번째 link태그인지 구하기
int linkIndex = TMP_TextUtilities.FindIntersectingLink(_text, mousePos, null);
// 링크를 벗어난 경우
if (linkIndex != _cachedLinkIndex)
{
ResetTooltip();
// 마우스가 링크 위에 없을 경우
if (linkIndex == -1) return;
_cachedLinkIndex = linkIndex;
// 툴팁 처리
ShowTooltip(linkIndex);
}
}
link 태그로 감싸진 텍스트 위에 마우스가 있다면 ShowTooltip 메서드를 호출하도록 하였다.
ShowTooltip에서는 미리 정해둔 툴팁의 linkName과 link태그의 id를 맞춰 일치하는 TooltipData를 적용해주었다.
link태그의 id를 불러오기 위해 TMP_LinkInfo 구조체의 GetLinkID를 사용하였다.
private void ShowTooltip(int linkIndex)
{
if (_trigger == null) return;
string linkID = _text.textInfo.linkInfo[linkIndex].GetLinkID();
LinkTooltip linkTooltip = _template.linkTooptips.Find(x => x.linkName == linkID);
if (linkTooltip == null) return;
if (linkTooltip.data.IsInitializeData() == false) linkTooltip.data.InitializeData();
_trigger.tooltipStyle = linkTooltip.style;
_trigger.tooltipData = linkTooltip.data;
_trigger.StartHover();
}
미리 지정할 툴팁은 TooltipTemplate에서 TooltipTrigger를 구현할 때 처럼 Tooltip Style을 넣어서 데이터를 수정할 수 있게 구현하였다.
결과
'공부 > 유니티' 카테고리의 다른 글
[Unity] 툴팁 만들기 - part2. 런타임 중에 툴팁에 데이터 넣기 (0) | 2025.05.22 |
---|---|
[Unity] 툴팁 만들기 - part1. 배치된 툴팁 (0) | 2025.05.21 |
[Unity] 백터의 내적과 외적 활용 - 적 탐색편 (0) | 2025.05.08 |
[Unity] Custom Editor - ReorderableList (0) | 2024.06.11 |
[Unity] 유니티 어트리뷰트 만들기 (0) | 2024.02.24 |