# Custom theme

You can of course create your own Dialogue UI for your game. All you need to do is creating a UI Controller class which receives all relevant method calls from the DialogueController to control your dialogue UI.

To do this, create an empty class and implement the <mark style="background-color:orange;">**IDialogueUIControl**</mark> interface.

It is also recommended to have a look at the existing Theme scripts.

Here's a very simple barebone custom dialogue class which you can use and create your own theme based on this.

```csharp
using UnityEngine;
using UnityEngine.UI;
using TMPro;

using Databrain.Dialogue;


public class MyDialogueUI: MonoBehaviour, IDialogueUIControl
{ 
     // Define your dialogue references such as
     // choices button, dialogue text (TextMeshUI) etc.
     
     public TextMeshProUGUI dialogueText;
     public GameObject choiceButtonPrefab;
     public GameObject optionButtonsContainer;
     
     
     private DialogueController dialogueController;
     
     /// <summary>
     /// Called by the dialogue controller in the scene, which passes a reference to the dialogue controller to your dialogue ui script.
     /// </summary>   
     public void SetDialogueController(DialogueController dialogueController)
     {
          this.dialogueController = dialogueController;
     }

     /// <summary>
     /// Called the first time a dialogue starts
     /// </summary>
     public void OnDialogueStart()
     {
          // show the dialogue UI.
          
          
          // Clear old choice buttons
          for (int j = 0; j < existingChoiceButtons.Count; j++)
          {
               if (existingChoiceButtons[j] != null)
               {
                    Destroy(existingChoiceButtons[j].gameObject);
               }
          }
     }

     /// <summary>
     /// Called every time a new dialogue text is requested
     /// </summary>
     /// <param name="dialogueEventData"></param>
     public void ShowNextDialogueText(DialogueEventData dialogueEventData)
     {
          // Update dialogue text. Get the localized text by passing in the selected language from the dialogue controller
          dialogueText.text = dialogueEventData.dialogueText.GetLocalizedText(dialogueController.GetSelectedLanguage());
     }
     
     /// <summary>
     /// Called when choices are requested
     /// </summary>
     /// <param name="dialogueEventData"></param>
     public void ShowChoices(DialogueEventData  dialogueEventData)
     {
          // Build choices buttons
          
          // Clear old buttons first
          for (int j = 0; j < existingChoiceButtons.Count; j++)
          {
               if (existingChoiceButtons[j] != null)
               {
                    Destroy(existingChoiceButtons[j].gameObject);
               }
          }
          
          for (int i = 0; i < dialogueEventData.choices.Count;  i++)
          {
               // Skip choices which are not connected in the dialouge graph
               if (dialogueEventData.choices[i] == null)
               {
                    continue;
               }
                    
               // Instantiate the choice button prefab
               var _choiceInstance = Instantiate(choiceButtonPrefab);
               // Get the TextMeshProUGUI component from the button and assign the localized text
               _choiceInstance .GetComponentInChildren<TextMeshProUGUI>().text = dialogueEventData.choices[i].GetLocalizedText(dialogueController.GetSelectedLanguage());
               
               // Get the Button component and assign an action to the OnClick event.
               var _button = _choiceInstance .GetComponent<Button>();
               _button.onClick.AddListener(() => 
               {
                    // Select choice with index + 1 because 0 = default choice when timers up
                    dialogueController.SelectChoice(_index + 1);
               });
               
               // Add the choice button instance to the options UI container
               _choiceInstance.transform.SetParent(optionButtonsContainer.transform, false);
               
               // Add the button instance to the list so we can destroy them later
               existingChoiceButtons.Add(_choiceInstance.gameObject);
          }
     }
     
     /// <summary>
     /// Constantly called by DialogueController to update the timer UI
     /// </summary>
     /// <param name="_remainingTime"></param>
     /// <param name="_totalTime"></param>
     public void UpdateTimer(float _remainingTime, float _totalTime){}
 
     /// <summary>
     /// Called when dialogue is finished, by the OnExitDialogue node.
     /// </summary>
     public void OnDialogueExit()
     {
          // Hide dialouge UI
     }


}
```

The best way to use this script would be on the root object of your Dialouge UI. This root GameObject can then be assigned to the Dialouge Theme field on the DialougeController component in the scene.

<div align="left"><figure><img src="/files/LD0tM2kyvTmzFfQ6r6fd" alt=""><figcaption></figcaption></figure></div>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://giantgrey.gitbook.io/databrain/add-ons/dialogue/custom-theme.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
