0
\$\begingroup\$

I had a suspicion I would come across this problem. I know how to write to the file and read from it, but the following snippet isn't allowing me to input it into a text component.

public class EventHandler : MonoBehaviour
{
    string _text;
    Text text;
    private void Awake() 
    {
        text = FindObjectOfType<Text>();
    }
    public string Read(string path)
    {
        _text = "";
        StreamReader reader = new StreamReader(path);
        while (!reader.EndOfStream)
        {
            _text += reader.ReadLine();
        }
        reader.Close();
        return _text;
    }
    public void chapter_one()
    {
        text.text = Read("Assets/Chapters/chapter_one.txt");
    }
}

I'm sure you guys can explain why this isn't working. I already got the reference to the Text component as well.

Edit

No errors, file exists, its filled, color is white on black background, chapter_one is the file name and yes chapter_one is called, and I put Debug.Log right in the while loop and out_side of it and I received those logs. My only thoughts are that the string is not getting returned for god knows what reason, or the text component isn't appending the text.

\$\endgroup\$
9
  • \$\begingroup\$ What do you mean by "this isn't working" ? Have you got any error ? Does the file exist ? Is it empty ? Maybe the font color is not visible ? Are you sure chapter_one is called ? Have you tried to put Debug.Logs to find where does the problem come from ? We need more details ! \$\endgroup\$
    – Hellium
    Feb 7, 2017 at 8:10
  • \$\begingroup\$ In the Read function, I would have initialized _text to the empty string, and in the loop, I would have put : _text += reader.ReadLine();, else, you override the content of _text each iteration. \$\endgroup\$
    – Hellium
    Feb 7, 2017 at 10:21
  • \$\begingroup\$ That didn't change anything, its still not printing to the screen. \$\endgroup\$
    – Sora
    Feb 7, 2017 at 20:27
  • \$\begingroup\$ Could it be that I shouldn't use StreamReader? \$\endgroup\$
    – Sora
    Feb 8, 2017 at 1:51
  • \$\begingroup\$ @Gnemlock, yes it is outputting to Debug.Log. I declared _text as a global variable such like string _text at the beginning of my class. In the Read method, I actually set it to empty string which I will update my question to reflect. The problem seems to be that text.text which is what is grabbing my scene's Text Component, is not receiving _text. \$\endgroup\$
    – Sora
    Feb 8, 2017 at 3:12

2 Answers 2

1
\$\begingroup\$

Testing your solution, I find that the script works. You confirm that the text is being set from your StreamReader, but not transferring to your Text component. I can only find two reasons why this might be happening, and both generally fall under how you actually set up your initial Text component.


FindObjectOfType<t>() will only work if you can guarantee that you only have one instance of that t Type, or otherwise, do not care about what instance you will retrieve.

As per official documentation, FindObjectOfType<>() will return the first active object of that Type that has been loaded in to the scene. In my experience, you can not always reliably assume what instance will return, unless you only have a single instance of that Object in your scene.

That said, there is a much easier way to do this. If your script is attached to the same GameObject that holds your intended Object, use GetComponent<Component>, instead. That way, we look for the Component inside the specific GameObject. We can have a lot more control over referencing the right Object, in this way.

An easier method is to simply link the reference via the Inspector. You can do this by making your Text reference public, or by using either the [SerializeField] or [ShowInInspector] tags. The below script will look for a Text component local to the host GameObject, providing it has not already been linked via the Inspector.

public class EventHandler : MonoBehaviour
{
    [SerializeField]Text text;
    // ...

    private void Awake()
    {
        if(text == null)
        {
            text = (Text)GetComponent<Text>();
        }
    }
}

To be visually displayed, Text must be attached to a Canvas

Text will not display if it does not have a Canvas to display to. Canvas is a separate Component, and is used to display UI. The Text GameObject must be attached to the Canvas GameObject, via the Hierarchy. They can simply be attached to the same GameObject, if preferred.

UI Elements will not display if they are not "attached" to a Canvas component via the Hierarchy.

\$\endgroup\$
0
\$\begingroup\$

After an extensive amount of research over the last two day, the help of all you wonderful people, and a little bit of ingenuity and sacrifice I managed to create a solution. As some reference, it turns out that chapter_one was not being called properly, however, even when it was being called properly it wasn't working. So, I ended up using File.ReadAllText(path) to get the text in my .txt. This is when I found out chapter_one wasn't being called correctly. I ended up doing a lot of migrating of various things away from my EventHandler and using multiple scripts to achieve what I was doing with just my EventHandler. The following code being placed on the Text Component in the scene achieved what I set out to do in the first place:

public class Chapter_one : MonoBehaviour
{
    string _text;

    private void Awake()
    {
        chapter_one();
    }
    public void Read(string path)
    {
        _text = File.ReadAllText(path);
    }
    public void chapter_one()
    {
        Read("Assets/Chapters/chapter_one.txt");
        gameObject.GetComponent<Text>().text = _text;
    }
}

Such simple things like this situation, where all that needed to be done was change methods or changing the style of retrieving a particular thing makes things so annoying. Especially when it takes days to figure out the most simplest of problems.

\$\endgroup\$
2
  • \$\begingroup\$ It only just occurred to me that your not actually calling chapter_one() in your provided example (in the actual question). Perhaps it would help to show us how you were calling this method? Simply calling it from an Awake() method, I have no trouble. It would probably help to know why you were having the particularly odd issue, rather than knowing how you could get around it. \$\endgroup\$
    – Gnemlock
    Feb 8, 2017 at 6:36
  • \$\begingroup\$ Well, the problem was that I had a GameObject that has the EventHandler script on it, this GameObject didn't persist through my scenes, instead there was a new one in every scene(Which I have thus changed). Since that was the case and the chapter_one method was called at scene change, it never went through. At the moment, the problem is fixed and probably in a more organized and stable way than keeping everything on the EventHandler script. I realize I could switch the method and all it's counterparts back to EventHandler now that it persists, but I think it's better this way. \$\endgroup\$
    – Sora
    Feb 8, 2017 at 7:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .