FloorMaterial Listener not firing

Hello everyone,
I’m trying to detect when the FloorMaterial Property of a Character’s Humanoid changes. I tried to do so using the Humanoid’s GetPropertyChangedSignal Method like so:

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
    local character = player.Character or player.CharacterAdded:Wait()
    character.Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
        print("FloorMaterial changed to", character.Humanoid.FloorMaterial)
        setValidActions(player)
    end)
end)

However, this only seems to fire when the Player first joins the game, after that the function does not get called.
To my surprise, though, you can see the property change in studio’s server view (when playtesting and then switching from client to server).

Roblox won’t let me upload videos directly, so here is a YT video to clarify:

In the video you can see, that in a localScript everything works just fine, however the ServerScript does only register the FloorMaterial change once

It only works once because Players.PlayerAdded only fires when the player joins the game. The player and the character are two different instances. The character is added every time the player respawns, and is given a new character (body). Below I added a player.CharacterAdded connection that fires every time the character is added, which is what you want.

Lmk if it works and if you have any more questions :smiley:

local Players = game:GetService("Players")

local function _characterAdded(character : Model)
	character.Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
		print("FloorMaterial changed to", character.Humanoid.FloorMaterial)
		setValidActions(player)
	end)
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		_characterAdded(character)
	end)

	if player.Character then
		_characterAdded(player.Character)
	end
end)

Thanks for your reply, unfortunately though, this does not seem to solve my problem. :sad:
PlayerAdded does indeed fire only once for each Player joining, however since I’m then adding another Listener (GetPropertyChangedSignal:Connect(…)) this shouldn’t be a problem. In your code, you essentially did the same, however you outsourced the character.Humanoid:GetPropertyChangedSignal into a separate function _characterAdded

Did you try running the code

Yes, I did

bad30characterlimit

Try this

local Players = game:GetService("Players")

local function playerAdded(player)
	player.CharacterAdded:Connect(function(character)
		character.Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
			print("FloorMaterial changed to", character.Humanoid.FloorMaterial)
			setValidActions(player)
		end)
	end)
end

for _, player in Players:GetPlayers() do
	playerAdded(player)
end

Players.PlayerAdded:Connect(playerAdded)
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid: Humanoid? = character:WaitForChild("Humanoid")

humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
	print("FloorMaterial changed to", humanoid.FloorMaterial)
end)

try running it outside the playeradded/characteradded functions, this worked for me
image

Reread it, and forgot to wait for the humanoid :man_facepalming: Try below

local Players = game:GetService("Players")

local function _characterAdded(player : Player, character : Model)
	local humanoid = character:WaitForChild("Humanoid")
	humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
		print("FloorMaterial changed to", humanoid.FloorMaterial)
		setValidActions(player)
	end)
end

Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		_characterAdded(player, character)
	end)

	if player.Character then
		_characterAdded(player, player.Character)
	end
end)
1 Like

I know it works in local scripts (sorry for not making it clear enough in my post), however I need this to be server-sided for some validation things

1 Like

I tried however no success either.

However, I found this post from 2 years ago from someone who had a similar problem. It turned out to be an engine bug, but Roblox staff said it should be fixed…

in case you’re not afraid of using Heartbeat, you can use this maybe:

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoid: Humanoid? = character:WaitForChild("Humanoid")
		local lastFloorMaterial = humanoid.FloorMaterial
		game:GetService("RunService").Heartbeat:Connect(function()
			local currentFloorMaterial = humanoid.FloorMaterial
			if currentFloorMaterial ~= lastFloorMaterial then
				print("FloorMaterial changed to", currentFloorMaterial)
				lastFloorMaterial = currentFloorMaterial
			end
		end)
	end)
end)
1 Like

LOL

I tried your updated code, it doesn’t seem to work, though.

Is the issue still that it only works the first time the player spawns into the game? And if they reset, it stops working?

once it’s inside a function, you need the function to fire again for the material to change on the server, or at least that’s what I’m assuming from my own tests

1 Like

This works, I will use this as a workaround for now, thanks! :smiley:

1 Like

I’m confused because it looks like it’s working in the video you put. Is the setValidActions function the problem?

it says [client], their script has issues on [server]

1 Like

Exactly! It only works once when the player joins. The player doesn’t even have to reset for it to stop working (As demonstrated in the video).

2 Likes

Actually, in the video, you can see the output of both the LocalScript and the ServerScript. At first the serverScript prints that the material has changed, the following lines in the output were produced only by the local script (note the [SERVER] and [CLIENT] prefixes.)