Hello, developers! I currently in the make of a dialogue system, but seem to have encountered any error every once in a while.
Unable to assign property Text. string expected, got nil - Line 82
I’ve checked through all of my code and can’t seem to find the problem with my code.
--//variables
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RemoteEvents = ReplicatedStorage:WaitForChild("RemoteEvents")
local Frame = script.Parent.Frame
local ChoicesFrame = script.Parent.choices.Frame
local ChatStarted = false
local canContinue = true
local currentChatIndex = 0 --//this is used for which number of messages we're at
local choiceIndex = 0 --//this is used for which index choice the player has chosen
local maxChoices = 0 --//this is used to determine how many choices the player is given (disregarding the "Goodbye!" choice)
local oldChoiceIndex = 0 --//this is used to get the old choice index value
local choiceSelected
local choices
local responses
local currentChoice
local typewriteMod = require(ReplicatedStorage:WaitForChild("typewrite"))
--//functions
local function getTableItems(array)
local totalItems = 0 --//total items in array
for _, element in ipairs(array) do
if typeof(element) == "table" then
totalItems += getTableItems(element)
else
totalItems += 1
end
end
return totalItems
end
local function tweenChoicesFrame(open: boolean)
if open == true then
ChoicesFrame.Parent:TweenPosition(
UDim2.new(
0.125,
0,
0.725,
0
),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Quad,
0.5
)
else
ChoicesFrame.Parent:TweenPosition(
UDim2.new(
0.125,
0,
1.25,
0
),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Quad,
0.5
)
end
end
local function getResponse()
for _, response in ipairs(responses) do
if ChatStarted == false then
break
end
currentChatIndex += 1
if typeof(responses[currentChatIndex]) == "string" then
Frame.speech_.Text = responses[currentChatIndex]
elseif typeof(responses[currentChatIndex]) == "table" then
local multiResps = responses[currentChatIndex]
print(multiResps[oldChoiceIndex])
Frame.speech_.Text = multiResps[oldChoiceIndex]
end
typewriteMod.typewrite(Frame.speech_, 0.025)
repeat wait()
until canContinue == true
end
end
local function getChoice()
for index, choiceT in ipairs(choices) do
if ChatStarted == false then
break
end
currentChoice = choices[currentChatIndex]
local currentIndex = 0 --//used to be added to for the table loop below
maxChoices = getTableItems(currentChoice)
for _, choice in ipairs(currentChoice) do
currentIndex += 1
if maxChoices == 1 then
ChoicesFrame["3"].Visible = false
ChoicesFrame["2"].Text = "Goodbye!"
elseif maxChoices == 2 then
ChoicesFrame["3"].Visible = true
end
ChoicesFrame[currentIndex].Text = choice
oldChoiceIndex = table.find(currentChoice, choiceSelected)
print("old choice index:", oldChoiceIndex)
end
repeat wait()
until canContinue == true
currentChoice = nil
end
end
RemoteEvents.StartChat.OnClientEvent:Connect(function(chatTree, speakerName: string)
local Lresponses = chatTree["resps"]
local Lchoices = chatTree["choices"]
ChatStarted = true
responses = Lresponses
choices = Lchoices
Frame.name_.Text = speakerName .. ":"
Frame.speech_.Text = "..."
Frame:TweenPosition(
UDim2.new(
0.5,
0,
0.909,
0
),
Enum.EasingDirection.InOut,
Enum.EasingStyle.Quad,
0.5
)
wait(1)
while canContinue == true do
canContinue = false
local coroGetResps = coroutine.create(getResponse)
local coroGetChoice = coroutine.create(getChoice)
if choiceSelected == "Goodbye!" then
ChatStarted = false
Frame.speech_.Text = "Goodbye!"
typewriteMod.typewrite(Frame.speech_, 0.025)
break
end
coroutine.resume(coroGetResps)
coroutine.resume(coroGetChoice)
repeat wait()
until typewriteMod.isFinished() == true
if currentChatIndex == getTableItems(responses) - 1 then
ChatStarted = false
Frame.speech_.Text = "Goodbye!"
typewriteMod.typewrite(Frame.speech_, 0.025)
break
end
if typewriteMod.isFinished() == true then
coroutine.wrap(tweenChoicesFrame)(true)
end
repeat wait()
until canContinue == true
end
wait(2)
RemoteEvents.ChatEnded:FireServer()
Frame:TweenPosition(
UDim2.new(
0.5,
0,
1.25,
0
)
)
local dialogueScript = script:Clone()
dialogueScript.Parent = script.Parent
script:Destroy()
end)
for _, choiceBtn in ipairs(ChoicesFrame:GetChildren()) do
if choiceBtn:IsA("TextButton") then
local UIStroke = ChoicesFrame:WaitForChild("UIStroke")
choiceBtn.MouseButton1Click:Connect(function()
if canContinue == false then
canContinue = true
choiceSelected = choiceBtn.Text
coroutine.wrap(tweenChoicesFrame)(false)
end
end)
choiceBtn.MouseEnter:Connect(function()
UIStroke.Parent = choiceBtn
UIStroke.Enabled = true
end)
choiceBtn.MouseLeave:Connect(function()
UIStroke.Parent = ChoicesFrame
UIStroke.Enabled = false
end)
end
end
I can’t seem if I should put this in code review or scripting support…