Ive noticed that this code could definetly be optimized better. Additionally, the image takes a while to spawn in. Any tips for what I can do or an alternative method of doing all this?
local plr = game.Players.LocalPlayer
local plrs = game:GetService("Players")
local plrList = plrs:GetPlayers()
local msgRunning = false
local ImageLabel = script.Parent.Parent.SpeakerImage
local ScreenGui = script.Parent.Parent
local getImgFunctionDoneRunning = false
local function getImg()
getImgFunctionDoneRunning = false
local randomizedPlr = math.random(1, #plrList)
local chosenSpeakerId = plrList[randomizedPlr].UserId
local processedImage = plrs:GetUserThumbnailAsync(chosenSpeakerId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
--ImageLabel.Image = processedImage
getImgFunctionDoneRunning = true
return processedImage
end
local function typeMsg(input, intervalSpeed, isSpeakerAPlayer)
local LoadedPlayerImg = getImg()
local CounselorImg = plrs:GetUserThumbnailAsync(0, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
repeat
task.wait()
until getImgFunctionDoneRunning == true
if isSpeakerAPlayer == true then
msgRunning = true
for i = 1, #input do
task.wait(intervalSpeed)
local substring = string.sub(input, 1, i)
script.Parent.Text = substring
if i >= #input then task.wait(2) msgRunning = false end
end
else
ImageLabel.Image = CounselorImg
msgRunning = true
for i = 1, #input do
task.wait(intervalSpeed)
local substring = string.sub(input, 1, i)
script.Parent.Text = substring
if i >= #input then task.wait(2) msgRunning = false end
end
end
end
--Scene One
ScreenGui.Enabled = false
task.wait(5)
ScreenGui.Enabled = true
local msg1 = "Hello there! I am a test NPC for this game."
typeMsg(msg1 .. " You must be "..plr.Name, 0.05, false)
repeat
task.wait()
until msgRunning == false
local msg2 = "I have to go for now. Have a good one, and explore a bit!"
typeMsg(msg2, 0.05, false)
ScreenGui.Enabled = false
task.wait(2)
ScreenGui.Enabled = true
local msg3 = "Hey does anyone wanna tell some stories around the fire?"
typeMsg(msg3, 0.05, true)
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local ScreenGui = script.Parent.Parent
local ImageLabel = ScreenGui:FindFirstChild("SpeakerImage")
local TextLabel = script.Parent
local msgRunning = false
-- Utility to get player headshot
local function getPlayerHeadshot(userId)
return Players:GetUserThumbnailAsync(userId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
end
-- Typing message effect
local function typeMessage(message, interval, isSpeakerPlayer)
msgRunning = true
-- Set speaker image
if isSpeakerPlayer then
local playerList = Players:GetPlayers()
if #playerList > 0 then
local randomPlayer = playerList[math.random(1, #playerList)]
ImageLabel.Image = getPlayerHeadshot(randomPlayer.UserId)
end
else
ImageLabel.Image = getPlayerHeadshot(0) -- default Roblox counselor image
end
-- Typewriter effect
for i = 1, #message do
TextLabel.Text = string.sub(message, 1, i)
task.wait(interval)
end
task.wait(2)
msgRunning = false
end
-- MAIN DIALOG FLOW
ScreenGui.Enabled = false
task.wait(5)
ScreenGui.Enabled = true
typeMessage("Hello there! I am a test NPC for this game. You must be " .. localPlayer.Name, 0.05, false)
repeat task.wait() until not msgRunning
typeMessage("I have to go for now. Have a good one, and explore a bit!", 0.05, false)
ScreenGui.Enabled = false
task.wait(2)
ScreenGui.Enabled = true
typeMessage("Hey does anyone wanna tell some stories around the fire?", 0.05, true)
local plr = game.Players.LocalPlayer
local plrs = game:GetService("Players")
local ScreenGui = script.Parent.Parent
local ImageLabel = ScreenGui.SpeakerImage
local msgRunning = false
local loadedImages = {} -- Table to store the images once loaded
-- Function to pre-load the player's image in parallel
local function loadPlayerImageAsync(userId)
-- This coroutine will load the image asynchronously
local promise = coroutine.create(function()
local image = plrs:GetUserThumbnailAsync(userId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
loadedImages[userId] = image -- Store the image once it's loaded
end)
coroutine.resume(promise)
end
-- Function to type the message
local function typeMsg(input, intervalSpeed, isSpeakerAPlayer)
-- Determine the speaker and load the image in parallel
local speakerImage
-- Preload speaker image asynchronously
local randomizedPlr = plrs:GetPlayers()[math.random(1, #plrs:GetPlayers())] -- Random player selection
if isSpeakerAPlayer then
loadPlayerImageAsync(randomizedPlr.UserId)
speakerImage = nil -- Placeholder, will be updated once loaded
else
loadPlayerImageAsync(0) -- NPC or default image for counselor
speakerImage = nil -- Placeholder, will be updated once loaded
end
-- Start typing the message
msgRunning = true
local currentText = ""
for i = 1, #input do
task.wait(intervalSpeed)
currentText = string.sub(input, 1, i)
script.Parent.Text = currentText
end
-- Wait for the image to be loaded if not already
while speakerImage == nil do
if loadedImages[randomizedPlr.UserId] then
speakerImage = loadedImages[randomizedPlr.UserId]
elseif loadedImages[0] then
speakerImage = loadedImages[0]
end
task.wait(0.1) -- Check every 100ms for the image
end
-- Set the image once it's loaded
ImageLabel.Image = speakerImage
-- End of message
task.wait(2) -- Wait 2 seconds before completing
msgRunning = false
end
-- Scene One
ScreenGui.Enabled = false
task.wait(5)
ScreenGui.Enabled = true
local msg1 = "Hello there! I am a test NPC for this game."
typeMsg(msg1 .. " You must be " .. plr.Name, 0.05, false)
-- Wait for the message to finish
repeat
task.wait()
until not msgRunning
local msg2 = "I have to go for now. Have a good one, and explore a bit!"
typeMsg(msg2, 0.05, false)
ScreenGui.Enabled = false
task.wait(2)
ScreenGui.Enabled = true
local msg3 = "Hey, does anyone wanna tell some stories around the fire?"
typeMsg(msg3, 0.05, true)