I need help with making this script work!

Hi, so I was trying to make a gui that when I type a command (-changetext)(text to change to) it would change the text but I keep getting this error: 15:23:25.213 PlayerGui is not a valid member of Players "Players" - Server - ChangeTextScript:7
Basically i wanna make it so my gui will change text when I say a command there’s two codes but i’ll send the one that has error:

local player = game:GetService("Players")
local changeTextEvent = Instance.new("RemoteEvent")
changeTextEvent.Name = "ChangeTextEvent"
changeTextEvent.Parent = game.ReplicatedStorage

local function changeText(newText)
	local screenGui = player.PlayerGui:WaitForChild("MyScreenGui"):Clone()
	local textObject = screenGui.MessageLabel

	textObject.Text = newText

	changeTextEvent:FireAllClients(newText)
end

game.Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		if string.sub(message, 1, 11) == "-changetext" then
			local newText = string.sub(message, 13)
			changeText(newText)
		end
	end)
end)

btw this is a script not local so ye
Pls help me ty

@CookieTechAi Good day! Can you assist this user, be sure to redirect them to me if you’re solutions don’t work after too long.

Hello there! The error message you are getting suggests that player.PlayerGui is not a valid member of Players. This is because player is a Players object, not a specific player. To fix this, you can update your changeText function to accept a player parameter instead of using the player variable from your main code:

local changeTextEvent = Instance.new("RemoteEvent")
changeTextEvent.Name = "ChangeTextEvent"
changeTextEvent.Parent = game.ReplicatedStorage

local function changeText(player, newText)
	local screenGui = player:WaitForChild("PlayerGui"):WaitForChild("MyScreenGui"):Clone()
	local textObject = screenGui.MessageLabel

	textObject.Text = newText

	changeTextEvent:FireAllClients(newText)
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local screenGui = script.Parent:WaitForChild("ScreenGui"):Clone()
		screenGui.Parent = player:WaitForChild("PlayerGui")
	end)
	
	player.Chatted:Connect(function(message)
		if string.sub(message, 1, 11) == "-changetext" then
			local newText = string.sub(message, 13)
			changeText(player, newText)
		end
	end)
end)

Notice that in the updated changeText function, we are now using the accepted player parameter to get the player’s PlayerGui. In addition, I also updated the code to add the MyScreenGui to the player’s PlayerGui when they join the game. Let me know if this helps!

Ok let me try it thx (20 chaaracter)

Now it’s just not working in general and idk if debugging would help anything its it because i have the gui made?

Where exactly is this script placed, take a screenshot from explorer?

Sorry for late response studio had updated :frowning: well its placed in serverscriptservice here is the picture:

I can’t remember but it could be that the server isn’t able to see player.PlayerGui is this true @CookieTechAi?

Yes, that is correct. ServerScriptService scripts running on the server cannot access the PlayerGui objects of individual players.

Instead, you can create a LocalScript in the StarterGui to listen to the RemoteEvent and update the UI. Here’s an example:

-- ServerScriptService script
local players = game:GetService("Players")
local changeTextEvent = Instance.new("RemoteEvent")
changeTextEvent.Name = "ChangeTextEvent"
changeTextEvent.Parent = game.ReplicatedStorage

local function changeText(player, newText)
	-- You don't need to clone the ScreenGui each time
	local screenGui = player:WaitForChild("PlayerGui"):WaitForChild("MyScreenGui")
	local textObject = screenGui.MessageLabel

	textObject.Text = newText

	changeTextEvent:FireAllClients(newText)
end

players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(message)
		if string.sub(message, 1, 11) == "-changetext" then
			local newText = string.sub(message, 13)
			changeText(player, newText)
		end
	end)
end)
-- LocalScript in StarterGui
local changeTextEvent = game.ReplicatedStorage.ChangeTextEvent

changeTextEvent.OnClientEvent:Connect(function(newText)
	local screenGui = game.Players.LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("MyScreenGui")
	local textObject = screenGui.MessageLabel

	textObject.Text = newText
end)

Note that you should have a ScreenGui instance named “MyScreenGui” in the StarterGui and a TextLabel inside it with the Name property set to “MessageLabel”.

Ok ill try these two

Great, let me know if you encounter any issues!

OMG TY BOTH but @CookieTechAi does it save when no one in server

Unfortunately, since the script relies on the ScreenGui objects of each player, the text will not be saved if there are no players in the server.

If you need to persist the text even when there are no players, you would need to save it to some sort of data store (such as DataStoreService or DataPersistenceService) or to a file using the DataStore2 module.

How could I do the datastore thing

Sure, here’s an example of how to use DataStoreService to save and load text:

local MyDataStore = game:GetService("DataStoreService"):GetDataStore("MyDataStoreName")
local DEFAULT_TEXT = "Hello, world!" -- Change this to your default message

local function loadText(player)
    local success, value = pcall(function()
        return MyDataStore:GetAsync(tostring(player.UserId))
    end)

    if success then
        return value or DEFAULT_TEXT
    else
        warn("Failed to load text for player " .. player.Name .. ": " .. tostring(value))
        return DEFAULT_TEXT
    end
end

local function saveText(player, newText)
    local success, value = pcall(function()
        MyDataStore:SetAsync(tostring(player.UserId), newText)
    end)

    if not success then
        warn("Failed to save text for player " .. player.Name .. ": " .. tostring(value))
    end
end

local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)
    local screenGui = Instance.new("ScreenGui")
    screenGui.Name = "MyScreenGui"
    screenGui.Parent = player.PlayerGui
    
    local messageLabel = Instance.new("TextLabel")
    messageLabel.Name = "MessageLabel"
    messageLabel.Position = UDim2.new(0.5, 0, 0.5, 0)
    messageLabel.Size = UDim2.new(0, 200, 0, 50)
    messageLabel.AnchorPoint = Vector2.new(0.5, 0.5)
    messageLabel.BackgroundTransparency = 1
    messageLabel.Font = Enum.Font.SourceSans
    messageLabel.TextColor3 = Color3.new(1, 1, 1)
    messageLabel.TextSize = 20
    messageLabel.Parent = screenGui
    
    local newText = loadText(player)
    messageLabel.Text = newText

    player.Chatted:Connect(function(message)
        if string.sub(message, 1, 11) == "-changetext" then
            newText = string.sub(message, 13)
            messageLabel.Text = newText
            saveText(player, newText)
        end
    end)
end)

players.PlayerRemoving:Connect(function(player)
    saveText(player, player.PlayerGui.MyScreenGui.MessageLabel.Text)
end)

This script loads the text for each player from MyDataStore, saves it when a player changes it, and saves it again when the player leaves the server to ensure that it is persisted even when there are no players in the server.

Note that you must replace “MyDataStoreName” with a unique identifier for your data store. Also, if you’re testing the script locally, you should use the DataStore2 module instead of DataStoreService since the latter does not work on the Roblox Studio client.

ok where do i place this

You can place this script in ServerScriptService.

Ok now i will test and let you know if any errors k

Sure, take your time. Don’t hesitate to ask if you have any questions or encounter any issues.

What should I naame the script