Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How to fix these 2 problems for my Battlefield script?

I have this script that makes a message that tells that someone entered the battlefield.

Not as in PlayerAdded, as in when someone touches the battlefield

Here is my script:

function m(plr)
debounce = false
m = Instance.new ("Message")
m.Parent = game.Workspace
m.Text =  "A new player has entered the battlefield! Name:"..plr.Parent.Name
wait(3)
m:Destroy()
end

script.Parent.Touched:connect(m)

This works perfectly, but I need these 2 problems fixed for my script:

  1. When 2+ messages are spawned, they don't disappear

  2. If someone just got on, prevent the message with their name from coming again (Until death)

2 answers

The first problem is caused by you not using a local variable.

When you say m = , it refers to some shared m -- one that any different call to this function will use.

That is almost never what you want, and modern coding practices say this is a very bad thing to do.

Make m local:

	....
	local m = Instance.new("Message", game.Workspace)
	-- Parent is second parameter, makes it a little short
	....

TL;DR: When first assigning to all variables, declare them as local (you can search on SH for lots of questions concerning how to use local)




The second thing would be a different sort of debounce. Instead of us using true and false, we'll use a dictionary:

announced[model]

will be true if model has been announced, and otherwise nil. We just need to use this instead of debounce:

announced = {} -- Define our dictionary

function announce(part) -- Use better variable names >:(
	local model = part.Parent
	if model and not announced[model] then
		announced[model] = true
		-- We want to make sure `part.Parent` isn't `nil` or nasty
		-- things happen (in addition to the debounce)
		local m = Instance.new("Message", game.Workspace)
		m.Text = model.Name .. " has entered the battlefield!"
		wait(3)
		m:Destroy()
	end
end

Because of how table indexing works, we can use model (as opposed to model.Name) to capture a reference to that particular model -- when you respawn, you'll get a new one, so it will ignore the old entry.

This is a neat trick that avoids us from having to track the .Died or .CharacterAdded events or anything else -- we get it for free!


(This will accumulate garbage; it will remember every player who has ever touched it in any life, even if they're long gone, so it might be a good idea to clear out values that are no longer in the Workspace, though this shouldn't be necessary)

1 comment

0

There's a terrible comment -- what doesn't work? I had forgotten to include the definition of our dictionary (though that would be clear, and "It says announced wasn't defined" would be a MUCH better comment). Also remember to read and not blindly copy ... for instance, this doesn't have a connection line in it.

To make sure it doesn't go when it already announced is to insert a value into their player and then check it. As for the not stopping, you never set the debounce to false - and never defined debounce as false.

local db = false

function check(plr)
	if plr:FindFirstChild('Touched') then
		return true
	else
		return false
	end
end

script.Parent.Touched:connect(function(hit)
	if db == true then db = false
		local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
		if plr then
			if check(plr) then
				Instance.new('IntValue',plr)
				local m = Instance.new ("Message",workspace)
				m.Text =  "A new player has entered the battlefield! Name:"..plr.Parent.Name
				wait(3)
				m:Destroy()
			end
		end
		db = true
	end
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.