One Way Platforms

How would I go about making a one-way platform. I’ve tried making a toggle system but I want something a bit more concrete. Any Ideas?

2 Likes

Please be more specific. Do you mean like a floating platform that only allows traveling one way? I’m asking because there are numerous ways of making platform setups that force players to go in only one direction.

One way is to make a platform that floats from one spot to another as long as a player character stands on it, and floats back after a bit of not being stood on.

Another way is to make a trigger platform that makes the platform before it disappear as soon as it’s touched.

Im trying to make a platform like in smash bros where u can go through it or drop down from it

You could maintain a list of such platforms in a local script, track which platform the player is standing on, and make the appropriate platforms not collideable while they either are not above them or for short time after they press a certain input.

RunService, ContextActionService, tables, GetDescendants(), DescendantAdded, DescendantRemoved and so on should help you accomplish this.

Below is an example piece from this game in the game.StarterPlayer.StarterPlayerScripts.Water.CameraInWaterDetector script for efficiently maintaining a list of water bodies and comparing the camera’s CFrame against each one to see which one it is in every frame.

-- Detects which water body the Camera is in and set it as the CurrentBody's value.
-- 
-- By ForbiddenJ

RunService = game:GetService("RunService")

WaterLib = require(game.ReplicatedStorage.WaterLib)

Camera = workspace.CurrentCamera

local mod = {}

mod.CurrentBody = script.CurrentBody

RegisteredWaterBodies = {}

function TryRegisterWaterBody(water)
	if WaterLib.IsWater(water) then
		-- No checks as DescendantAdded will not be called twice for the same object before DescendantRemoving
		RegisteredWaterBodies[#RegisteredWaterBodies + 1] = water
	end
end
function TryUnregisterWaterBody(water)
	if WaterLib.IsWater(water) then
		for i, item in pairs(RegisteredWaterBodies) do
			if water == item then
				table.remove(RegisteredWaterBodies, i)
				break
			end
		end
	end
end

for i, item in pairs(workspace:GetDescendants()) do
	TryRegisterWaterBody(item)
end
workspace.DescendantAdded:Connect(TryRegisterWaterBody)
workspace.DescendantRemoving:Connect(TryUnregisterWaterBody)

RunService.RenderStepped:Connect(function(deltaTime)
	local resultWater = nil
	for i, water in ipairs(RegisteredWaterBodies) do
		-- Thanks to the post at
		-- https://devforum.roblox.com/t/check-if-a-point-is-inside-a-possibly-rotated-part/8073/2?u=forbiddenj
		local point = water.CFrame:PointToObjectSpace(Camera.CFrame.Position)
		if math.abs(point.X) < water.Size.X / 2 and math.abs(point.Y) < water.Size.Y / 2 and math.abs(point.Z) < water.Size.Z / 2 then
		    resultWater = water
			break
		end
	end
	mod.CurrentBody.Value = resultWater
end)

return mod
2 Likes

How do i handle situations where i wanna drop down as an action, should i raycast or what?

You can either go the hard but elegant way of raycasting, or the easy but cluncky way of using hit() functions. Both willl work, personally i recommend the first.

1 Like

I went with a simpler solution but thanks for all the answers you guys gave me

local Detector = script.Parent
local Platform = Detector.Parent

Detector.Touched:Connect(function(object)
	if object.Name == "Head" then 
		print(true)
		Platform.CanCollide = true	
	end
end)

Detector.TouchEnded:Connect(function(object)
	if object.Name == "Head" then 
		print(false) 
		Platform.CanCollide = false
	end
end)
2 Likes

It’s great to know that your question got solved, don’t forget to mark ForbiddenJ’s answer as a solution!

I’ve got a bit of an issue with my method, since its being done over the server there’s a lot of lag and it doesn’t always keep up with the actual collision, especially when i jump on it quickly. Do u know how to fix this

1 Like

You could do it client-side.
Setting a part uncollideable on the client will allow your character to pass through it. It won’t affect others.
Not sure if it’s the best way but it could work.