게임 개발/Unity

[유니티 C#] 특정 텍스트 눌러서 팝업 띄우기

Heesuk Lee 2022. 8. 29. 22:21

오랜만에 재밌는 주제로 돌아왔습니다.

 

게임을 하다보면 스킬을 확인해야하는 경우가 많은데요

그 중 하나의 방법으로 스킬설명의 특정 텍스트를 터치하면 추가 스킬 설명이 되는 경우가 있습니다.

 

그것에 대한 고민을 하다가 정답은 아닐 수 도있지만 나름의 방법을 찾아서 짧게나마 공유하고자 합니다.

 

* URL 하이퍼링크 같은 기능을 개조해서 사용했습니다.

 

최종 구현된 모습입니다. 보시다시피 원하는 텍스트에만 터치기능을 제공합니다.

여기를 눌러보세요를 누르면 팝업을 띄울 수 있다.

 

 

하이라키 구조는 지킬필요는 없다 개인의 선호가 드극드극한 구조ㅎㅎ

 

왼쪽 이미지의 하이라키 구조는 크게 신경쓸 필요없이 TMP를 사용했다는것에 주의 해주시면 됩니다.

오른쪽 이미지에서는 텍스트 string에 <link>에 주의해주시면됩니다.

원래는 <link=https://무언가의주소.com> 이런식으로 richtext가 작성되어있고 해당 텍스트를 누르면 무언가의 주소 홈페이지를 여는 기능이지만

일부 개조하여 link={여기}에 스킬 id 혹은 팝업으로 한번더 디테일하게 보여줄 정보의 Id값을 팝업콜백으로 전달해주도록 구현했습니다.

 

그렇게되면 '여기를 눌러주세요'를 눌렀을때 link에 해당하는 id값을 전달받은 팝업이 출력되는 구조입니다.

 

 

TMP_Text컴포넌트와 함께 필요한 스크립트입니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using TMPro;
using System;

// 터치관련 인터페이스 상속 - IPointerDownHandler, IPointerUpHandler
public class TextTest : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
	// 해당 기능을 실현시키기 위해서는 TextMeshPro를 사용해야한다.
    private TextMeshProUGUI m_TextMeshPro = null;
	
    // 현재 main camera, canvas가 필요하다.
    private Camera m_Camera = null;
    private Canvas m_Canvas = null;
	
    // 터치 다운시 콜백
    private Action<string, Vector2> downCallback = null;
	// 터치 업시 콜백
    private Action upCallback = null;
	
    // 초기화 - 생성시 기본적을 필요한 멤버변수 초기화
    private void Start()
    {
    	// 카메라 초기화
        m_Camera = Camera.main;
		// 캔버스 초기화
        m_Canvas = gameObject.GetComponentInParent<Canvas>();
        if (m_Canvas.renderMode == RenderMode.ScreenSpaceOverlay)
            m_Camera = null;
        else
            m_Camera = m_Canvas.worldCamera;
		
        // TextMeshPro 초기화
        m_TextMeshPro = gameObject.GetComponent<TextMeshProUGUI>();
        m_TextMeshPro.ForceMeshUpdate();
    }
	
    
    public void Init(Action<string, Vector2> _downCallback, Action _upCallback)
    {
    	// 콜백 초기화 - 기능적으로 구현할때 신경써줘야하는 부분
        this.downCallback = _downCallback;
        this.upCallback = _upCallback;
    }

    public void OnPointerDown(PointerEventData eventData)
    {
    	// 터치가 됐을때 - URL 하이퍼링크 기능을 개조해서 사용했습니다.
        int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);

        if (linkIndex != -1)
        {
            TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
            // 링크 index가 존재할때 터치 기능 - 보통 스킬 정보를 보내줘야하므로 임의로 작성한 ID값과 터치한 위치 전달
            this.downCallback(linkInfo.GetLinkID(), Input.mousePosition);
        }
    }

    public void OnPointerUp(PointerEventData eventData)
    {
    	// 별다른 기능없이 팝업 제거 콜백 호출
        this.upCallback();
    }
}



 

위에 TextTest의 부모 혹은 팝업을 띄워줘야할 오브젝트의 스크립트입니다. 기능은 TextTest의 초기화 부분 및 콜백을 담당합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestPanel : MonoBehaviour
{
	// 해당 텍스트 컴포넌트
    [SerializeField]
    private TextTest textTest = null;
    // 팝업 오브젝트
    [SerializeField]
    private ToolTipTest toolTipTest = null;
    
    private void Start()
    {
    	// 해당 텍스트 초기화 - 눌렀을때와 땠을때 콜백 추가
        this.textTest.Init(this.ShowTooltip, this.hideTooltip);
    }

    private void ShowTooltip(string _id, Vector2 _position)
    {
    	// 해당 텍스트를 눌렀을때 콜백 - 받아온 id 값을 전달
        this.toolTipTest.ShowTooltip(_id, _position);
    }
    private void hideTooltip()
    {
    	// 해당 텍스트를 누르는것을 땠을때 콜백 - 팝업 제거
        this.toolTipTest.HideTooltip();
    }
}

 

 

급해서 디테일하게 준비는 못했지만 아직 아이디어정도의 기능이고 정식으로 사용되기보다는

흥미로워서 요령으로 만들어진 코드이므로 제대로 사용하려면 R&D가 더 필요하겠지만

급한대로 사용할법한 방법이라고 생각합니다 하하

 

나중에 더 나은 방법이 나오거나 공부를 더해서 좀더 깔끔한 코드로 돌아오겠습니다.

반응형