Alternatives to raycasting and runservice.heartbeat

so ive been working on this code that welds a part to you, and then constantly updates its position to under you (the ground below you via a raycast), i understand how RunService.Heartbeat is resource heavy as well as raycasting, would there be any alternatives to these whilst still being functional?

-- local script
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local DisplayKillzone = game.ReplicatedStorage.DisplayKillzone
local player = Players.LocalPlayer
local function CreateKillzone(character: Instance)
	local rayCastParams = RaycastParams.new()
	local filteredParts = {}
	rayCastParams.FilterType = Enum.RaycastFilterType.Exclude

	for _, v in ipairs(character:GetDescendants()) do
		if v:IsA("BasePart") then
			table.insert(filteredParts, v)
		end
	end


	local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
	local killZone = game.ReplicatedStorage.KillZone:Clone()
	table.insert(filteredParts, killZone)
	killZone.CanCollide = false
	killZone.Anchored = false
	killZone.Parent = character

	local weld = Instance.new("WeldConstraint")
	weld.Parent = humanoidRootPart
	weld.Part0 = humanoidRootPart
	weld.Part1 = killZone
	weld.Part1.Position = humanoidRootPart.Position - Vector3.new(0,3,0)
	RunService.Heartbeat:Connect(function()
		local rayCast = workspace:Raycast(humanoidRootPart.Position,Vector3.new(0,-100,0), rayCastParams)
		if rayCast and rayCast.Instance.Name ~= "KillZone" and rayCast.Instance.CanCollide == true then
			rayCastParams.FilterDescendantsInstances = filteredParts
			print(rayCast.Position.Y .." ".. rayCast.Instance.Name)
			weld.Part1.Position = Vector3.new(humanoidRootPart.Position.X,(rayCast.Position.Y),humanoidRootPart.Position.Z)
		end
	end)
end


player.CharacterAdded:Connect(function()
		CreateKillzone(player.Character)
		DisplayKillzone:FireServer() -- replicate across all clients
end)
DisplayKillzone.OnClientEvent:Connect(function(character)
	CreateKillzone(character)
end)

Before I can give my two cents, may I see a video of this code in action? I am curious on why you would need to reposition weld.Part1 position using raycast.

It’s making sure the part is in the ground

here is the video for it

I know these aren’t exactly alternatives, but you could try only raycasting when the player is moving, or having the killzone move with a lower interval for the client than other players. You could also try some physics approach. It’ll likely be janky, but if are out of options then it could be worth a try.

a physics approach would be a REALLY hacky approach to this issue as it is unpredictable and extremely unreliable for this case. and im also confused on how i would measure when the player is moving, do you have any ideas for this? as i have never done something like this.

There are a few ways to detect if the player is moving. I personally check if Humanoid.MoveDirection.Magnitude > 0 to see if the humanoid is moving (does not account for physics), however you could also see if the character is moving in any form by checking if HumanoidRootPart.Velocity.Magnitude > 0.

I’ve also just thought of something: If the player is standing on the ground, then simply get the killzone position by subtracting the roots position from half of the players height (4 studs high I believe). But, if the player is in the air, then use the raycasting method shown here. I’ve never tried this, but it should work.

You dont need to do this, you’re just using up more resources than needed, instead just do this:

rayCastParams.FilterDescendantsInstances = {character}

The property is named FilterDescendantsInstances for a reason, you’re only just adding to what the raycast has to check for.


Just use RenderStepped for any rendering work, and as a optimization, save the current position (Preferrably on the HumanoidRootPart) and check if the player’s current position is different from the saved position, if its the same, return, otherwise update the killzone and save position.

On the Server, all you need to tell it to do is to apply a value to the character in order to activate the killzone on the client, as you will be rendering the result on the client as opposed to the server. If the effect isn’t enabled, dont bother trying to render it.

RenderStepped should also remove the need for the weld, as it would update prior to rendering as opposed to physics.