The User Interface ================== In this section, we will set up the user interface and write a script that updates the user interface based on the ``ChatPlayer`` node set up in the previous section. We'll also need to make a new main scene to handle the connection between the level scene (already created) and the UI. By the end of this section, we should be able to do the following from the user interface: * See a constantly updated control hint message. * See when other ``ChatEntity`` nodes are nearby. * Write, send, and receive messages while in a conversation with another entity. Part 1: The User Interface Scene -------------------------------- Let's start by setting up the user interface scene along with its script. Setting Up the Scene ^^^^^^^^^^^^^^^^^^^^ The user interface scene is provided premade here: :download:`user_interface.tscn`. Everything should be set up except the scripts. Open up *user_interface.tscn*. You should see the following scene (though the background may be a different color): .. image:: ui_screenshot.png :alt: The UI Scene :width: 899px :align: center You will also need the files :download:`dynamic_label.tscn` and :download:`NewMsgEdit.cs`. The first is a label scene that will be added from script during gameplay. The second is a short script that makes it so that the enter key will send a message. Attach the *NewMsgEdit.cs* script now to the ``NewMsgEdit`` node (this node is under the ``MsgGroup`` node). Finally, if you want, you can change the project's default background color to black. This setting can be found in the project settings under Rendering > Environment > Defaults > Default Clear Color. Writing the Script ^^^^^^^^^^^^^^^^^^ Now, we'll add the main script for interacting with the UI. It will be attached to the root node of the scene and will listen for signals from the ``ChatPlayer`` node and update it when necessary. Add a C# script to the ``UserInterface`` node. Save the script as *UserInterface.cs*. Properties """""""""" First, we'll add a property that will reference the ``ChatPlayer`` node attached to the *seraphis.tscn* scene. We won't worry about setting it from inside the UI script and will instead have it set by the main scene (up next). .. code-block:: csharp // A reference to the ChatPlayer node (will be set by dependency injection via Main.cs) public ChatPlayer MyChatPlayer; Next, we'll add properties that will hold references to the various child nodes of the UI scene. This will make them easier to access from the code. (These will have values assigned to them later in the ``_Ready()`` method.) .. code-block:: csharp // Various nodes that will need to be updated during gameplay private Label _controlInfo; private VBoxContainer _entityBox; private ScrollContainer _msgScroll; private VBoxContainer _msgBox; private TextEdit _newMsgEdit; private Button _newMsgSend; We'll also have a property that will reference the *dynamic_label.tscn* scene that we downloaded earlier. This will be used to add labels dynamically for nearby entities and messages. Set the path to point wherever you have this scene saved. .. code-block:: csharp // Scenes that will need to be instanced during gameplay private PackedScene _dynamicLabelScene = GD.Load("res://dynamic_label.tscn"); The last property that we'll have is a flag to indicate whether a new message has just been added to the UI. This will be used to help us keep the messages' scroll container scrolled all the way to the bottom so that the newest messages are always visible. .. code-block:: csharp // Flag for when a message has been added to the message box and so we need to scroll to end private bool _justAddedNewMsg = false; Methods for Initialization """""""""""""""""""""""""" Now on to methods. First we'll override the node's ``_Ready()`` method. In this method, we'll assign nodes to the properties declared earlier and we'll connect up a method to handle what happens when the send button is pressed. We'll also call a helper function ``ConnectPlayerSignals()`` that connects all the relevant signals of ``ChatPlayer`` to methods in this script. .. code-block:: csharp // Called when the node enters the scene tree for the first time. public override void _Ready() { // Get all the various child nodes _controlInfo = GetNodeOrNull