(FIXED) Scrollable InputField: Cannot seem to update the InputField after setting its Text

TL;DR:
My main gripe with the Scrollable InputField is it doesn’t update immediately when the output messages set to the InputField. I even tried explicitly to rebuild the InputField, but it’s not working.
I expected the Scrollable InputField to immediately display all of the viewable text messages in the InputField, and the user can scroll up and down with the scrollbar to the end in an intuitive way, without having to drag/select the text and move the mouse downwards to refresh the InputField.


I am making a read-only InputField where the player can copy any strings inside to another place, like an output log file. I need to do this because for WebGL builds, you cannot write anything or a text file to the local computer. (Please prove me wrong. I really really appreciate this.)

This is the current setup for the Scrollable InputField:

Panel has Scroll Rect. In the Scroll Rect, the “Content” is pointing towards the Text game object, and the “Viewport” is pointing towards the InputField game object. The Scrollbar is a default bottom to top vertical scrollbar.

InputField has Mask added.

Text has Content Size Fitter, with “Vertical Fit” set to Preferred Size, and “Horizontal Fit” set to Unconstrained. It also has a Layout Element with “Flexible Height” set to 4096. Nothing else is set.

This is what happens when I set the InputField’s Text component with dummy output log messages. Note that the dummy output log messages are printed 4 times in total (because I am lazy). You have to actually drag/select the text inside InputField, and drag to the bottom of the InputField to have all of the text to show up:

That action of dragging/selecting the text to update the InputField is completely buggy and wrong.

And here’s what the log output messages look like. I have separated the output log messages into sections, so you know that I’m just outputting dummy messages 4 times:

public static void PrintLog() {
    GameMetricLogger log = GameMetricLogger.instance;
    if (GameMetricLogger.instance.stringBuilder == null) {
        Debug.LogError("Print(): Game metrics logger cannot output anything. Please double check.");
        log.outputField.text = "No game metrics report generated.";
    }
    else {
        StringBuilder sB = log.stringBuilder;
        sB.Length = 0;
        //---------------------------------------------------------------------------------------------------------
        //---------------------------------------------------------------------------------------------------------
        sB.AppendLine("Game Metrics Report");
        sB.AppendLine("(Please copy and paste this report somewhere else.)");
        sB.AppendLine("Total Game Time Since Report Is Generated: " + log.totalGameTimeSinceEpoch.ToString("0.000") + " seconds");
        sB.AppendLine();
        sB.AppendLine("Player Name: " + log.playerName);
        sB.AppendLine("Level Difficulty: " + GetLevelDifficulty());
        sB.AppendLine("Unit Attribute Equation Used: " + log.difficultyEquations);
        sB.AppendLine();
        sB.AppendLine("Total Time Played: " + log.totalGameTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Death: " + log.numberOfDeaths);
        sB.AppendLine("Total Kills: " + log.numberOfKills);
        sB.AppendLine("Total Attacks: " + log.numberOfAttacks);
        sB.AppendLine("Total Splits: " + log.numberOfSplits);
        sB.AppendLine("Total Merges: " + log.numberOfMerges);
        sB.AppendLine();
        sB.AppendLine("Total Time Accumulated When Attacking: " + log.totalAttackTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Time Accumulated Under Attack: " + log.totalBattleEngagementTime.ToString("0.000") + " seconds");
        sB.AppendLine();
        //---------------------------------------------------------------------------------------------------------
        //---------------------------------------------------------------------------------------------------------
        sB.AppendLine("Game Metrics Report");
        sB.AppendLine("(Please copy and paste this report somewhere else.)");
        sB.AppendLine("Total Game Time Since Report Is Generated: " + log.totalGameTimeSinceEpoch.ToString("0.000") + " seconds");
        sB.AppendLine();
        sB.AppendLine("Player Name: " + log.playerName);
        sB.AppendLine("Level Difficulty: " + GetLevelDifficulty());
        sB.AppendLine("Unit Attribute Equation Used: " + log.difficultyEquations);
        sB.AppendLine();
        sB.AppendLine("Total Time Played: " + log.totalGameTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Death: " + log.numberOfDeaths);
        sB.AppendLine("Total Kills: " + log.numberOfKills);
        sB.AppendLine("Total Attacks: " + log.numberOfAttacks);
        sB.AppendLine("Total Splits: " + log.numberOfSplits);
        sB.AppendLine("Total Merges: " + log.numberOfMerges);
        sB.AppendLine();
        sB.AppendLine("Total Time Accumulated When Attacking: " + log.totalAttackTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Time Accumulated Under Attack: " + log.totalBattleEngagementTime.ToString("0.000") + " seconds");
        sB.AppendLine();
        //---------------------------------------------------------------------------------------------------------
        //---------------------------------------------------------------------------------------------------------
        sB.AppendLine("Game Metrics Report");
        sB.AppendLine("(Please copy and paste this report somewhere else.)");
        sB.AppendLine("Total Game Time Since Report Is Generated: " + log.totalGameTimeSinceEpoch.ToString("0.000") + " seconds");
        sB.AppendLine();
        sB.AppendLine("Player Name: " + log.playerName);
        sB.AppendLine("Level Difficulty: " + GetLevelDifficulty());
        sB.AppendLine("Unit Attribute Equation Used: " + log.difficultyEquations);
        sB.AppendLine();
        sB.AppendLine("Total Time Played: " + log.totalGameTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Death: " + log.numberOfDeaths);
        sB.AppendLine("Total Kills: " + log.numberOfKills);
        sB.AppendLine("Total Attacks: " + log.numberOfAttacks);
        sB.AppendLine("Total Splits: " + log.numberOfSplits);
        sB.AppendLine("Total Merges: " + log.numberOfMerges);
        sB.AppendLine();
        sB.AppendLine("Total Time Accumulated When Attacking: " + log.totalAttackTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Time Accumulated Under Attack: " + log.totalBattleEngagementTime.ToString("0.000") + " seconds");
        sB.AppendLine();
        //---------------------------------------------------------------------------------------------------------
        //---------------------------------------------------------------------------------------------------------
        sB.AppendLine("Game Metrics Report");
        sB.AppendLine("(Please copy and paste this report somewhere else.)");
        sB.AppendLine("Total Game Time Since Report Is Generated: " + log.totalGameTimeSinceEpoch.ToString("0.000") + " seconds");
        sB.AppendLine();
        sB.AppendLine("Player Name: " + log.playerName);
        sB.AppendLine("Level Difficulty: " + GetLevelDifficulty());
        sB.AppendLine("Unit Attribute Equation Used: " + log.difficultyEquations);
        sB.AppendLine();
        sB.AppendLine("Total Time Played: " + log.totalGameTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Death: " + log.numberOfDeaths);
        sB.AppendLine("Total Kills: " + log.numberOfKills);
        sB.AppendLine("Total Attacks: " + log.numberOfAttacks);
        sB.AppendLine("Total Splits: " + log.numberOfSplits);
        sB.AppendLine("Total Merges: " + log.numberOfMerges);
        sB.AppendLine();
        sB.AppendLine("Total Time Accumulated When Attacking: " + log.totalAttackTime.ToString("0.000") + " seconds");
        sB.AppendLine("Total Time Accumulated Under Attack: " + log.totalBattleEngagementTime.ToString("0.000") + " seconds");
        sB.AppendLine();
        //---------------------------------------------------------------------------------------------------------
        //---------------------------------------------------------------------------------------------------------

        log.outputField.text = sB.ToString();
        log.outputField.Rebuild(CanvasUpdate.MaxUpdateValue);
    }
}

How can I fix this? Thanks in advance.

Thanks to @MisterSyntax, this is what I added to fix the InputField:

public void Update() {
    this.outputField.GetComponentInChildren<Text>().text = this.outputField.text.ToString();
}

Because the Text component in the InputField is not updating, or rather, it requires a lot more updates than just 1 update tick, it was not able to stretch its text boundaries vertically. By putting the code above in the Update() function, it refreshes the boundaries, and thus stretch the text boundaries vertically.

And then everything else comes into play nicely.

Thanks again.