How to change the color of a particle to match the color of the part the player is walking on

Hello Developers!
I’ve actually tried coding this on my own, but it did not work. So I decided to ask the community for help.
So there’s a footstep particle script located inside the player’s character. The particle appears when the player walks. But the problem is that I don’t know how to change the particle color depending on the color of the part the player is walking on.

This is the particle script:

--Variable --
local player = game:GetService("Players").LocalPlayer

player.CharacterAdded:Connect(function(char)
local humanoid = char:WaitForChild("Humanoid")
local leftFoot
local rightFoot
	
	-- Rig Check --
	if (humanoid.RigType == Enum.HumanoidRigType.R6) then
		leftFoot = char:WaitForChild("Left Leg")
		rightFoot = char:WaitForChild("Right Leg")
	end
	--Particle Create --
	local particle = workspace.ImportantParticle.ParticleEmitter

--Values --
	local On = false
	
	-- Cloning the particle --
	local pClone = particle:Clone()
	pClone.Parent = leftFoot
	local rpClone = particle:Clone()
	rpClone.Parent = rightFoot

	pClone.Enabled = false
	rpClone.Enabled = false
	
	-- Humanoid Movement
	while true do
		local val = humanoid.MoveDirection

		if ((humanoid.FloorMaterial ~= Enum.Material.Air) and (val.X ~= 0 or val.Y ~= 0 or val.Z ~= 0)) then
			if (On == false) then
				On = true

				pClone.Enabled = true
				rpClone.Enabled = true
			end
		else
			if (On) then
				On = false

				if (pClone ~= nil and rpClone ~= nil) then
					pClone.Enabled = false
					rpClone.Enabled = false
				end
			end
		end
		wait()
	end
end)

I’m pretty sure your supposed to use raycast, but I’m not really familiar with it.

Any kind of help would be appreciated.

1 Like

You would be correct. Raycasting is probably the best option for this.

Example

local origin = leftFoot.Position --Where the ray will begin from
local direction = Vector3.new(0,-1,0) --World Down
local distance = 5 --Studs

local CastParams = RaycastParams.new()
CastParams.FilterType = Enum.RaycastFilterType.Blacklist
CastParams.IgnoreWater = false
CastParams.FilterDescendantsInstances = {myChar} --Put any instance you want to ignore into this table
local castResult = workspace:Raycast(origin, (direction*distance), CastParams) --Perform the raycast
if(castResult)then
	local color = castResult.Instance.Color --Get color value of part hit
	pClone.Color = ColorSequence.new(color)
	rpClone.Color = ColorSequence.new(color)
end

Something’s not really working correctly…
sadasdadadsa

local event = game.ReplicatedStorage.FootstepParticle
event.OnServerEvent:Connect(function(plr)
	local char = plr.Character
	local humanoid = char:WaitForChild("Humanoid")
	local leftFoot
	local rightFoot

	-- Rig Check --
	if (humanoid.RigType == Enum.HumanoidRigType.R6) then
		leftFoot = char:WaitForChild("Left Leg")
		rightFoot = char:WaitForChild("Right Leg")
	end
	--Particle Create --
	local particle = script.ParticleEmitter
	--Values --
	local On = false
	

	-- Cloning the particle --
	local pClone = particle:Clone()
	pClone.Parent = leftFoot
	local rpClone = particle:Clone()
	rpClone.Parent = rightFoot

	pClone.Enabled = false
	rpClone.Enabled = false
	
	local direction = Vector3.new(0,-1,0) --World Down
	local distance = 5 --Studs

	local CastParams = RaycastParams.new()
	CastParams.FilterType = Enum.RaycastFilterType.Blacklist
	CastParams.IgnoreWater = false
	CastParams.FilterDescendantsInstances = {char} --Put any instance you want to ignore into this table
	local castResult = workspace:Raycast(leftFoot, (direction*distance), CastParams) --Perform the raycast
	if(castResult)then
		local color = castResult.Instance.Color --Get color value of part hit
		pClone.Color = ColorSequence.new(color)
		rpClone.Color = ColorSequence.new(color)
	end

	-- Humanoid Movement
	while true do
		local val = humanoid.MoveDirection

		if ((humanoid.FloorMaterial ~= Enum.Material.Air) and (val.X ~= 0 or val.Y ~= 0 or val.Z ~= 0)) then
			if (On == false) then
				On = true

				pClone.Enabled = true
				rpClone.Enabled = true
			end
		else
			if (On) then
				On = false

				if (pClone ~= nil and rpClone ~= nil) then
					pClone.Enabled = false
					rpClone.Enabled = false
				end
			end
		end
		task.wait()
	end
end)

I’m really sorry if the script is really messy, just had to rush everything.

What was the error? (more chars)

I’m afraid I don’t get what you mean by “more chars”

I see it. In the raycast line. You can’t just put “leftFoot” that has to be a position value.

I had to put that because the reply requires a certain amount of chars.

https://gyazo.com/6ea06b75de355d27051aef956f7ae843

I see. That’s because its terrain I believe. That makes things more complicated. I’m not entirely sure we can pick up the color from raycasting terrain. But let me do a test or two here and I’ll post back. Might have to keep a record of colors to use for certain materials.

I’m confused, the entire map is made out of parts, not terrains.

Oh well. I did figure out how to get the material color of the terrain. But if its a part then check the color value set on the part.

Here how to get the material color of the terrain or part:

	if(castResult)then
		local color
		if(castResult.Instance.Name == "Terrain")then
			--Get Terrain Material Color
			local material = castResult.Material
			color = game.Workspace.Terrain:GetMaterialColor(material)
		else
			--Get Part Color
			color = castResult.Instance.Color
		end
		pClone.Color = ColorSequence.new(color)
		rpClone.Color = ColorSequence.new(color)
	end

I tried to fix it, but to no avail.

Well the code, works. So there must be something wrong with the part color of your ground part.

Do you think it’s because I used :FireServer()?

Idk. This should be done on the client side though. Especially since its a client effect and we are using the position of the clients foot.

Make sure you remove the local prefix of the color variable in the terrain color section. That was a mistake, I’ve corrected that in the code I posted.

if(castResult.Instance.Name == "Terrain")then
			--Get Terrain Material Color
			local material = castResult.Material
			--local color = game.Workspace.Terrain:GetMaterialColor(material)
			color = game.Workspace.Terrain:GetMaterialColor(material)
		else

I’m now very sure that the problem is caused by the parts in the map. Thanks for the help though, I really appreciated it.

1 Like

I think it’s more likely related to your use of the instance method :FireServer() to transmit data to the server. RemoteEvent instances are restricted/limited in the types of values/data they can exchange between the server & the client.