You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? I want the player walkspeed to change when the terrain is changed
-
What is the issue? The message indicates that the correct terrain is detected, but the walkspeed just stays the same at 20.
-
What solutions have you tried so far? I found solutions on develop hub like using Floormaterial, but when I use this it doesnt even register the change in terrain. My script is below. I have changed it many times to incorporate various solutions, so I apologise if it is a bit messy.
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local TERRAIN_SPEEDS = {
["Leafy Grass"] = 10,
["Grass"] = 40,
["Mud"] = 25
}
local DEFAULT_SPEED = 20
local WATER_DEATH_MATERIAL = Enum.Material.Water
local lastMaterialEncountered = {}
local function setPlayerSpeed(player, speed)
local character = player.Character
if character then
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
print("Setting speed for", player.Name, "to", speed) -- Debug message
humanoid.WalkSpeed = speed
end
end
end
local function safeSetPlayerSpeed(player, speed)
local success, errorMessage = pcall(setPlayerSpeed, player, speed)
if not success then
warn("Failed to set player speed for", player.Name, ":", errorMessage)
end
end
local function onTerrainCheck(player)
local character = player.Character
if character then
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local rayOrigin = humanoidRootPart.Position + Vector3.new(0, 2, 0)
local rayDirection = Vector3.new(0, -5, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {character}
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult and raycastResult.Instance:IsA("Terrain") then
local material = raycastResult.Material
local materialName = tostring(material) -- Ensure conversion for table lookup
-- Check if the material has changed since the last check
if lastMaterialEncountered[player.Name] ~= materialName then
local speed = TERRAIN_SPEEDS[materialName] or DEFAULT_SPEED
print(player.Name, "Walking on", materialName, "- Speed is", speed)
lastMaterialEncountered[player.Name] = materialName -- Update the last encountered material
if material == WATER_DEATH_MATERIAL then
pcall(function()
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid.Health = 0
end
end)
else
safeSetPlayerSpeed(player, speed)
end
end
else
print("Raycast did not hit the terrain or the expected material for", player.Name)
end
end
end
end
RunService.Heartbeat:Connect(function()
for _, player in ipairs(Players:GetPlayers()) do
onTerrainCheck(player)
end
end)
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function()
safeSetPlayerSpeed(player, DEFAULT_SPEED)
lastMaterialEncountered[player.Name] = nil
end)
end)