Hello!! (˶ᵔ ᵕ ᵔ˶)
This time I’m sharing a simple but flexible quest system for HGK. It’s flexible because it’s reusable, each quest can have any number of tasks and a custom required amount for completion. The design is simple, but it works great for lots of small horror games.
I’ve included a step-by-step video tutorial showing how I built it, plus the script you can use in your project.
Video
Script
local UIField = script.fields.UIField
local TaskTextList = script.fields.TaskTextList
local TaskCountList = script.fields.TaskCountList
local TaskProgressObj = script.fields.TaskProgressObj
local QuestCompleteObj = script.fields.QuestCompleteObj
local TaskCompleteList = script.fields.TaskCompleteList
local YaResourceManager = YahahaMiddleLayerSlim.Resource.YaResourceManager
local mainPanel
local packageName
local UITextComp
local UICountComp
local taskProgress = {}
local self = script.gameObject
script.OnStart(function ()
LoadResource()
end)
function LoadResource()
YaResourceManager.LoadResourceByUIPackageField(UIField, function(state, name)
if state == AssetStatus.AllAssetCompleted then
packageName = name
CreateMainPanel()
end
end)
end
function CreateMainPanel()
mainPanel = UIPackage.CreateObject(packageName, "TaskUI")
GRoot.inst:SetContentScaleFactor(2436, 1125)
GRoot.inst:AddChild(mainPanel)
mainPanel.size = GRoot.inst.size
mainPanel:AddRelation(GRoot.inst, RelationType.Size)
UITextComp = {
mainPanel:GetChild("Task1Text"),
mainPanel:GetChild("Task2Text"),
mainPanel:GetChild("Task3Text"),
}
UICountComp = {
mainPanel:GetChild("Task1Count"),
mainPanel:GetChild("Task2Count"),
mainPanel:GetChild("Task3Count"),
}
for i = 1, #TaskTextList do
taskProgress[i] = 0
end
UpdateTaskUI()
end
function UpdateTaskUI()
for i = 1, #UITextComp do
if TaskTextList[i] then
UITextComp[i].visible = true
UICountComp[i].visible = true
UITextComp[i].text = TaskTextList[i]
UICountComp[i].text = tostring(taskProgress[i] or 0) .. "/" .. tostring(TaskCountList[i] or 0)
else
UITextComp[i].visible = false
UICountComp[i].visible = false
UITextComp[i].text = ""
end
end
local allComplete = true
for i = 1, #TaskCountList do
local current = taskProgress[i] or 0
local required = TaskCountList[i] or 0
if required == 0 then
elseif current >= required then
if TaskCompleteList[i] then
TaskCompleteList[i]:SetActive(true)
end
taskProgress[i] = required
else
allComplete = false
end
end
if allComplete and QuestCompleteObj then
print("Quest Complete!")
QuestCompleteObj:SetActive(true)
OnDispose()
end
end
script.OnUpdate(function ()
for i, obj in ipairs(TaskProgressObj) do
if obj.activeInHierarchy then
taskProgress[i] = (taskProgress[i] or 0) + 1
UpdateTaskUI()
obj:SetActive(false)
end
end
end)
function OnDispose()
if mainPanel then
mainPanel:Dispose()
end
self:SetActive(false)
YaResourceManager.RemoveResourceByUIPackageField(UIField)
end
Editor
local fieldDefs = {
{
name = "UIField",
label = "UI Field",
hint = "UI Field",
description = "UI Field",
type = "UIPackageFile"
},
{
name = "TaskTextList",
type = {
type = "list",
items = {
name = "TaskText",
type = "string"
}
}
},
{
name = "TaskCountList",
type = {
type = "list",
items = {
name = "TaskCount",
type = "integer"
}
}
},
{
name = "TaskProgressObj",
type = {
type = "list",
items = {
name = "TaskProgress",
type = "GameObject",
}
}
},
{
name = "TaskCompleteList",
type = {
type = "list",
items = {
name = "TaskComplete",
type = "GameObject",
}
}
},
{ name ="QuestCompleteObj", type = "GameObject" }
}
script.DefineFields(fieldDefs)