Controlling UI elements with scripts and using them in Projects
After exporting UI packages created in the UI editor, you use them in your Projects through scripting. If you're new to scripting in Studio, please take a moment to set up your environment and get familiar with the basics first.
Adding a script to an empty object
-
Create an empty object in Scene Explorer.
-
Attach a script to the empty object by clicking Add script > New Lua script.
-
Fill in a name for the script and you can write code in your specified code editor, Visual Studio Code. This script will serve as a component to help add the UI package and load all UI elements within.
Creating a UI package selector
-
From the project scripts, find the
editor.lua
file that defines the Property window fields. -
Create a UI package selector named UIField in the script by setting its type to UIPackageFile.
local fieldDefs = {
{
name = "UIField",
label = "UI Field",
hint = "UI Field",
description = "UI Field",
type = "UIPackageFile"
},
}
script.DefineFields(fieldDefs) -
Save the script in the code editor. After saving, you'll see the new UI package selector in the Properties window in Studio.
-
Choose the exported UI package. You're now ready to load and use all resources from the selected package by calling FairyGUI API and Resource Manager API.
Loading UI elements from the selected UI package
Once you've selected the UI package using your created selector, you can load all UI elements in your Lua
file that implements runtime logic without specifying the package name. These elements will be displayed in the main panel you create.
To load UI elements from the selected UI package:
- Retrieve the UI package field and access the
YaResourceManager
API. - Trigger resource loading when the game starts, tracking various states as different parts of the resource are loaded.
- Create a main panel from the UI package once all resources are successfully loaded.
- Configure the panel to dynamically adjust its size based on the screen resolution.
- Destroy the main panel and unload the selected UI package.
The following code snippet loads all UI elements from the UI package in the UIField selector.
-- Get the imported UI package field
local UIField = script.fields.UIField
-- Access the YaResourceManager API
local YaResourceManager = YahahaMiddleLayerSlim.Resource.YaResourceManager
local mainPanel
local packageName
-- Load resources when the game starts
script.OnStart(function ()
LoadResource()
end)
-- Function to load resources
function LoadResource()
-- Use the LoadResourceByUIPackageField API to load the specified UIField.
-- The API returns the loading state at each stage:
-- - AssetStatus.ManifestBytesCompleted: Serialized bytes or manifest loaded.
-- - AssetStatus.BaseAssetCompleted: Bytes files loaded.
-- - AssetStatus.AllAssetCompleted: All files loaded.
-- packageName is the name of the current package (it is only returned during BaseAssetCompleted and AllAssetCompleted stages; it is null during ManifestBytesCompleted stage).
YaResourceManager.LoadResourceByUIPackageField(UIField, function(state, name)
-- When all resources are loaded, create the specified panel (i.e., when state == AssetStatus.AllAssetCompleted).
if state == AssetStatus.AllAssetCompleted then
packageName = name
-- Create the main panel
CreateMainPanel()
end
end)
end
function CreateMainPanel()
-- Create the main panel from the Sample Package
mainPanel = UIPackage.CreateObject(packageName, "TestPanel")
-- Set the screen scaling based on your panel resolution
-- GRoot.inst is the built-in root node for FGUI rendering
GRoot.inst:SetContentScaleFactor(2436, 1125)
-- Add the UI panel to the FGUI root node to display it on screen
GRoot.inst:AddChild(mainPanel)
-- Set the panel size to match the screen size
mainPanel.size = GRoot.inst.size
-- Establish a two-way binding relationship between the panel and screen size;
-- when the screen size changes, the panel will adjust accordingly.
mainPanel:AddRelation(GRoot.inst, RelationType.Size)
end
script.OnDispose(function ()
-- Destroy the panel
mainPanel:Dispose()
-- Unload the UIField resource
YaResourceManager.RemoveResourceByUIPackageField(UIField)
end)
Getting UI elements on the canvas
Get the UI elements using their name in the UI package. Make sure the name in the code is identical to that in your UI package.
-- Get the UI element using its name in the UI package.
local button = mainPanel:GetChild("Button")
local graph = mainPanel:GetChild("Rectangle")
local image = mainPanel:GetChild("Image")
local list = mainPanel:GetChild("List")
local loader = mainPanel:GetChild("Loader")
local slider = mainPanel:GetChild("Slider")
local progressBar = mainPanel:GetChild("Progress")
local textField = mainPanel:GetChild("Text")
local textInput = mainPanel:GetChild("InputText")
Binding a click event to a button
local function ButtonOnClickEvent()
-- Write your code here.
print("The button is clicked on.")
end
button.onClick:AddListener0(ButtonOnClickEvent)
Drawing and refreshing a list
local list = mainPanel:GetChild("List")
local function OnRenderList(index, canvas)
end
list.itemRenderer = OnRenderList
-- Provide the number of list items.
list.numItems = 10
-- Render the list using the index of the list and the canvas.
-- Refresh the list.
list.numItems = 10
Drawing and refreshing a virtual list
local list = mainPanel:GetChild("List")
list.defaultItem = "ui://PackageName/ListItemCanvasName"
list:SetVirtual()
local function OnRenderList(index, canvas)
end
list.itemRenderer = OnRenderList
-- Provide the number of list items.
list.numItems = 10
list:RefreshVirtualList()
-- Render the list using the index of the list and the canvas.
-- Refresh the list.
list.numItems = 6
list:RefreshVirtualList()
Using Loader
local loader = mainPanel:GetChild("Loader")
loader.url = "ui://PackageName/CanvasName"
-- Get the canvas that you configured in the loader.
local canvas = loader:GetLoaderComponent()
Using Text
local textField = mainPanel:GetChild("Text")
-- Set the content of the text.
textField.text = "Content"
Using Text Input
local textInput = mainPanel:GetChild("InputText")
textInput.singleLine = true
local function SubmitEvent()
-- Write your code here.
end
-- The OnSubmit works when the player presses the enter button. The SingleLine property must be set to true.
textInput.onSubmit:AddListener0(SubmitEvent)
Using Image
local image = mainPanel:GetChild("Image")
-- Change the position of the Image
image.xy = Vector2.New(0, 0)
-- Change the color of the Image
image.color = UnityEngine.Color(0.8, 0.8, 0.5, 0.5)
Using Slider
local slider = mainPanel:GetChild("Slider")
-- Method to handle when the slider is dragged
local function OnSliderMoveEvent()
print("The value of the slider is: " .. slider.value)
end
-- Listen for slider drag event
slider.onChanged:AddListener(OnSliderMoveEvent)
Using ProgressBar
local progress = mainPanel:GetChild("Progress")
-- Dynamically change the progress value
-- TweenValue(double value, float duration)
progress:TweenValue(100, 6)
Using Graph
local rectangle = mainPanel:GetChild("Rectangle")
-- Rotate the rectangle by 60 degrees
rectangle.rotation = 60