How to move a player back on to an object if they fall

I have floating circular islands in my game and I do not wish to spend a few hours putting invisible parts around the edge to prevent players from falling, instead I wish the player to be able to fall, but when they do, they get placed back on the island from the location in which they fell from. Unfortunately, I am unable to think of a practical way of doing so, how could I do this?

You could put an invisible part in the void and put a script that teleports them OnTouched

1 Like

Yeah but how would the script know where to put him, at that point just let them fall and get respawned. I think the easiest way to do it would be to add invisible checkpoints, and when the player touches the invisible part, teleports to the last checkpoint.

1 Like

put a part in the void and out a script that tps

I did that, but I don’t how to find where the player was before they fell to move them there.

oh someone siad the same mb didnt see that

Once every second or so, raycast downwards from the player’s current position just far enough that it’ll hit the ground they’re standing on. Use this to keep track of the “latest good position”, and move them there if they fall.

1 Like

Alright, thank you. I guess I’m learning Raycasting today…

How big are the islands? If they are fairly small then you could put a teleport Part under each circle and then use a teleport to the center of the island.
If the island is large and you want them back at the edge where they dropped then certainly use @ThanksRoBama’s solution.

There is one possible issue with this. Say by chance it saves the player’s position right as they are about to touch the part, they can get stuck in an infinite loop. I’m not entirely sure if this is even a possibility or not though.

1 Like

I appreciate your help, but I already have a working method, curtsy of @ThanksRoBama.

I have a server-script that enters players into a table when they join and a separate function, in the same script, that loops through all the players every 3 seconds and saves their position in the table. Like this:

-- Vars --
local _players = game:GetService("Players")
local _map = workspace:WaitForChild("Map")
local _playersInfo = {}
-- Functions --
function _getPlayersLocation()
	while wait(3) do
		for i, plr in pairs(_players:GetPlayers()) do
			local character = plr.Character
			local rayOrigin = character.PrimaryPart.Position + Vector3.new(0,100,0)
			local rayDirection = Vector3.new(0, -(rayOrigin.Y), 0)

			local raycastParams = RaycastParams.new()
			raycastParams.FilterDescendantsInstances = {character:GetChildren()}
			raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
			local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)

			if raycastResult then
				local hitPart = raycastResult.Instance
				_playersInfo[plr.Name .. "Info"].SafeLocation = Vector3.new(raycastResult.Position.X, raycastResult.Position.Y, raycastResult.Position.Z)
			end
		end
	end
end
function _fallBarrierHit(hit)
	local plr = _players:GetPlayerFromCharacter(hit.Parent)
	if (plr) then
		plr.Character.Humanoid.WalkSpeed = 0
		plr.Character:MoveTo(_playersInfo[plr.Name .. "Info"].SafeLocation)
		task.wait(0.5)
		plr.Character.Humanoid.WalkSpeed = 16
	end
end
function _playerAdded(plr)
	_playersInfo[plr.Name .. "Info"] = {["Us"] = plr.Name, ["ID"] = plr.UserId, ["SafeLocation"] = _map.Buildings.SpawnHouse.SpawnLocation.Position}
end
function _playerRemoved(plr)
	_playersInfo[plr.Name .. "Info"] = nil
end
-- Events --
_players.PlayerAdded:Connect(_playerAdded)
_players.PlayerRemoving:Connect(_playerRemoved)
_map.Barriers:FindFirstChild("FallBarrier").Touched:Connect(_fallBarrierHit)
_getPlayersLocation()

(In the chance someone else wishes to replicate this system)

1 Like