Easy Custom Dialogue System in horror game kit ✧。٩(ˊᗜˋ )و✧*。

Easy Logic #1
Yahaha comes with many built-in components that make game creation easier than ever. But sometimes, we want more flexibility with our own custom logic. Coding can feel overwhelming with so many scripting terms, but luckily, we can still build solid systems using Yahaha’s built-in features—no deep coding knowledge needed.
This is the start of my series, Easy Logic in Yahaha Studio: Horror Game Kit, where I show how I create custom logic the easy way! (˶ˆᗜˆ˵)

The Video

We’re kicking off this series with a custom dialogue system! I’ve made a video tutorial to walk you through it step by step—since it’s much easier to show than explain with just text. Here, I’ll also provide some extra explanations to make it even more beginner-friendly, along with the script below. ദ്ദി(˵ •̀ ᴗ - ˵ ) ✧

How this method work
One of the biggest challenges when creating custom logic is getting different logics in the scene to communicate and share data. Normally, that requires digging deep into the scripting library, which can be complex and make your code unnecessarily long.
This method helps avoid all that! It works by using extra built-in components to support your logic. Since Yahaha’s components are designed to work together, we can take advantage of that.
For this dialogue system, I use an additional game object with an EventTrigger component. It’s set to trigger when the object is activated (set to true). From our script, we can easily toggle it with a single line of code—and the EventTrigger can then execute multiple events you’ve assigned to it!

Basic of coding
Yahaha uses Lua, a language designed to be simple. However, to make it easier for beginners to follow along, I’ll include some key things to know for this tutorial. ᕙ( •̀ ᗜ •́ )ᕗ

  1. Variable type
    Variables are the things you want to store or manipulate in your script—like text, numbers, or other data. Common types include strings, integers, and floats. In Lua, you don’t need to specify the type directly. Instead, the type is determined by how you write the value. For example, to create a string, you just wrap the text in quotation marks (" ").
    You can find more details here : Field types | YAHAHA Developer

  2. Function
    When creating a script, we start with OnStart (called when the script starts) and OnUpdate (called every frame). We can also create our own functions, but we need to call them in order to use them. In this tutorial, I have a function called EndDialogHandler that is called within the OnUpdate function. The purpose of this function is to execute a specific part of the code logic when needed.

  3. Referencing/Instancing
    Referencing is very important—it allows us to access and modify values. In this tutorial, I get a reference from the .Editor script using script.fields.VariableName, and I also reference UI components by their names. Once we have those references, we can modify them however we like.

Code

local fieldDefs = {
    {
        name = "UIField",
        label = "UI Field",
        hint = "UI Field",
        description = "UI Field",
        type = "UIPackageFile"
    },
    {
        name = "EndTrigger",
        type = "GameObject"
    },
    {
        name = "CharacterName",
        type = "string"
    },
    {
        name = "DialogList",
        type = {
            type = "list",
            items = {
                name = "Dialog",
                type = "string",
            }
        }
        
    }
}
script.DefineFields(fieldDefs)
local UIField = script.fields.UIField
local EndTrigger = script.fields.EndTrigger
local CharacterName = script.fields.CharacterName
local DialogList = script.fields.DialogList

local YaResourceManager = YahahaMiddleLayerSlim.Resource.YaResourceManager 

local mainPanel
local packageName

local dialogText
local currentDialog = 1

script.OnStart(function ()
    LoadResource()
end)

-- Function to load resources
function LoadResource()
    YaResourceManager.LoadResourceByUIPackageField(UIField, function(state, name)
        if state == AssetStatus.AllAssetCompleted then
            packageName = name

            -- Create the main panel
            CreateMainPanel()
        end
    end)
end

function CreateMainPanel()
    mainPanel = UIPackage.CreateObject(packageName, "DialogBox")
    GRoot.inst:SetContentScaleFactor(2436, 1125)
    GRoot.inst:AddChild(mainPanel)
    mainPanel.size = GRoot.inst.size
    mainPanel:AddRelation(GRoot.inst, RelationType.Size)
    dialogText = mainPanel:GetChild("DialogText")
    dialogText.text = CharacterName .. " : " .. DialogList[currentDialog]
end

local Input = UnityEngine.Input
local KeyCode = UnityEngine.KeyCode

script.OnUpdate(function ()
    if Input.GetKeyDown(KeyCode.Z) then
        currentDialog = currentDialog + 1
        if currentDialog > #DialogList then
            HandleEndDialog()
        else 
            dialogText.text = CharacterName .. " : " .. DialogList[currentDialog]
        end
    end
end)

function HandleEndDialog()
    mainPanel:Dispose()
    YaResourceManager.RemoveResourceByUIPackageField(UIField)
    EndTrigger:SetActive(true)
end