UI error, "not valid member of StarterGui"

Server scripts can control everything even overriding locking calls to it.
Got to jump around a bit for this one.

local part = workspace:WaitForChild("Part")
local players = game:GetService("Players")

local function Touched(hit)
	local Character = hit.Parent
	local Humanoid = Character and Character:FindFirstChildWhichIsA("Humanoid")
	if Humanoid and Humanoid.Health > 0 then
		local Player = players:GetPlayerFromCharacter(Character)
		if Player then
			local PlayerGui = Player:WaitForChild("PlayerGui")
			local Jumpscare = PlayerGui:FindFirstChild("Jumpscare")
			if Jumpscare then
				Jumpscare.Enabled = true
			end
		end
	end
end

part.Touched:Connect(Touched)

As in this case … now that the server has turned on enabled the client can’t change it.
The server has override control on it now until it restores it to the way it was.

why not just fire a remote event to the client and the local script plays the jumpscare

In this case it can do a touch.

I read an insightful explanation regarding this a couple of years ago that sums up why it is generally recommended to have the client handle UI-related changes:

because personal things needs personal permissions, such as client stuff, for example, server cannot access the Mouse Position of the client, only the client can

I actually agree with you … I’m just tring to stick with his script.

1 Like

I understand this but, in this case it can do a touch…

because touch is watching for the Parts in ur character if it touches the part u put the function in, it means the server sees the part, and the character at the same time, but server cannot see ur screen

its like u can see if someone punched another person, but u cant know what exactly that person felt

Here, @samagonous try this!
Beginner Tutorial #2: How To Make A Jumpscare!
Hope it helps!

I understand what you are saying … This is clearly a jumpscare popup gui that will be over in a bit. Something that a script like I posted could do simply, start to end totally securly and hidden to hackers. Do it anyway you like … there are always a few ways to do anything. Here I just go with what they gave me to work with.

if ure tryna avoid hackers deleting the jumpscare from their playergui so the localscript wont be able to scare them when u fire an remote event, im pretty sure they can also inject their own local script to delete everything the server tries to add to their playergui, for example

local ScreenGui = blabla -- the screengui u plan to put the jumpscare

ScreenGui.ChildAdded:Connect(function(child)
child:Destroy()
end)

but anyway, perhaps the reason for ur post that server cant find the Jumpscare to clone is maybe wrong spelling?

can u show the jumpscare instance in the startergui?

since jumpscare is in screen gui it will get replicated to all clients by default under player gui

replace

game.StarterGui.Jumpscare

with

PlayerGui.Jumpscare

also make sure that it exist and if it still didnot work try PlayerGui:WaitForChild()

This is false. Exploiters (with a little bit of knowledge) create UI instances inside of CoreGUI, which cannot be accessed.

i think u replied to the wrong message, i was just tryna tell him that using serverscript to put the jumpscare directly into the player’s playergui IS NOT going to help him avoid hackers from avoiding the jumpscare, cuz hackers can also put their own local script that automatically deletes anything the server tries to insert into their player gui

Oops, I got confused, I though you we’re trying to give him some sort of anti-cheat.

You can’t access the PlayerGUI from a server script, so even if you wanted to, you couldn’t.

1 Like

i just noticed, you put

local Jumpscare = game.StarterGui.Jumpscare

Jumpscare:Clone()

im 100% sure, but i think you cant clone that way, the variable for the main thing and the variable for the cloned one should be seperated, like

local Jumpscare = game.StarterGui.Jumpscare

local ClonedOne = Jumpscare:Clone()

yea, i was telling him that, but i think he was just being told to do that and that he cant say otherwise

So after looking at this code, I decided to revamp the whole thing for ya!
I’ll go step-by-step on how to set this up

1: Create a folder in replicated storage called “Sounds” and in that folder create another folder called “JumpscareSounds” (Put your desired jumpscare sounds In JumpscareSounds)

2: Create a folder in replicated storage called “Events” and in that folder create another folder called “JumpscareEvents”

3: Create a folder in replicated storage called “ScreenGuis” and parent your desired ScreenGui into it. Make sure IgnoreGuilnset is turned on, Enabled is turned off, and the ScreenGui’s name is Jumpscare1.

4: Create a remote event in replicated storage called “JumpscareEvent1” and parent it into “JumpscareEvents”

5: In workspace, (not assuming you dont have a part the player will step on) make a part, anchor it, and put a server script inside of it. In that script copy and paste this code into it

local debounce = false
local DebounceLength = 4 -- How long it takes until the part can detect when a player dies again (try to match this up with the respawn time).
-- (4 goes with the default respawn time btw)

local event = game.ReplicatedStorage.Events.JumpscareEvents.JumpscareEvent1
local players = game:GetService("Players")

players.PlayerAdded:Connect(function(Player)
	Player.CharacterAdded:Connect(function(Character)


		local function Touched()
			print("Function Activated")
			event:FireClient(Player)			
			end
		

script.Parent.Touched:Connect(function()
			Character.Humanoid.HealthChanged:Connect(function(health)
				if health <= 0 and not debounce then
					debounce = true
				Touched()
				task.wait(DebounceLength)
				print("Debounce ended")
				debounce = false
						end
					end)
				end)
			end)
		end)

5: Create a client script in StarterGui, name this whatever you want. In this script copy and paste this code into it.

local Player = game.Players.LocalPlayer
local Character = Player.Character

local event = game.ReplicatedStorage.Events.JumpscareEvents.JumpscareEvent1
local sound = game.ReplicatedStorage.Sounds.JumpscareSounds.JumpscareSoundHere


event.OnClientEvent:Connect(function()

	if Player.PlayerGui:FindFirstChild("Jumpscare1") then
	else
		local Jumpscare = game.ReplicatedStorage.ScreenGuis.Jumpscare1
		local JumpscareClone = Jumpscare:Clone()

		JumpscareClone.Parent = Player.PlayerGui

		JumpscareClone.Enabled = true
		sound:Play()

		wait(2)

		JumpscareClone.Enabled = false

		Player.PlayerGui:FindFirstChild("Jumpscare1"):Destroy()
		print("Destroyed")
	end
end)

If u encounter any issues with this please reply and I’ll try to help you out. (no credit is needed btw)