Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if I clicked on a certain part of text

Tags:

c#

text

unity3d

I'm using Unity to create an Android/IOS application.

In a page containing a paragraph, I want to know if I click on the last sentence of the text. ("Click here for more details" for example). After clicking on this sentence I want to open a new page.

I know I can put 2 text elements and add this sentence to the second element and the reset to the first element and add onClick event on the second element.

This is a solution for the problem, but in my case, it can't solve the problem because I am getting text dynamically and its size will change from time to time, so the second text element will not start on the same line after the first element ends.

I need a solution that is done in code.

I saw the same question but it is for HTML and JavaScript, not for Unity.

I will post one of the answer's code snippet which has the same behaviour of what I want.

const clickables = document.querySelectorAll('.clickable')
clickables.forEach(el => new Clickable(el))

function Clickable (el) {
  const _handleClick = ({target}) => console.log(target.innerHTML)
  const texts = el.textContent.split(/\s/)
  
  el.innerHTML = ''
  
  texts.forEach(t => {
    const span = document.createElement('span')
    span.innerHTML = `${t} `
    span.addEventListener('click', _handleClick)
    el.appendChild(span)
  })
}
<h1 class="clickable">Some text</h1>

<h2 class="clickable">Some! more! text2</h1>
like image 896
Bilal Sehwail Avatar asked Aug 28 '19 11:08

Bilal Sehwail


2 Answers

This video describes a similar concept, only that it detects clicks and hovering over specific characters. https://www.youtube.com/watch?v=wg9WAwd8TKM

To make it work for your idea you can just chack the index of the character that was pressed and then check if it's in certain range from the end of the text.

Hope it helps!

like image 125
mihoci10 Avatar answered Oct 19 '22 11:10

mihoci10


It is possible using the TextMeshPro or TextMeshProUGUI intstead of Text. Then you can do a lot of fancy stuff using the TMP_TextUtilities.

Actually there are a lot more very good reasons why it is worth to switch over to using TMP instead of Text - so far I haven't found any good one for preferring Text over TMP.

The linked TMP_TextUtilities tutorial shows a lot more fancy use cases.

public class Example : MonoBehaviour
{
    public TextMeshProUGUI text;

    public string LastClickedWord;

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            var wordIndex = TMP_TextUtilities.FindIntersectingWord(text, Input.mousePosition, null);

            if (wordIndex != -1)
            {
                LastClickedWord = text.textInfo.wordInfo[wordIndex].GetWord();

                Debug.Log("Clicked on " + LastClickedWord);
            }
        }
    }
}

enter image description here

Simply replace the Text component by a TextMeshProUGUI component on the object and in your scripts. The usage for setting the text is exactly the same.

I want to know if I click on the last sentence of the text. ("Click here for more details"

Instead of FindIntersectingWord you can also use FindIntersectingLine and then check the index to only trigger the event for the last one.

if(lineIndex == text.lineCount - 1)

Note that lines here means actual displayed lines - not necessarily linebreaks

Or you could e.g. count and define the amount of words in the last sentence and use

if(wordIndex > text.textInfo.wordCount - LastSentenceLength)

Or .. you could also directly use a Link then you can use FindIntersectingLink and also check if you hit the last one.


Note: make sure to pass in the same Camera as used for the Canvas. I used null because I used a ScreenSpace-Overlay canvas without a certain Camera referenced. In case you are using e.g. WorldSpace you have to

  • reference the Camera in the Canvas &rightarrow; Event Camera
  • pass the same Camera to FindIntersectingXXX
like image 7
derHugo Avatar answered Oct 19 '22 13:10

derHugo