Need a more stable way to make a piston for obby

Hi,

I am making a piston to push people, problem is im using touched events and PrismaticConstraint which is kind of unstable, sometimes it goes past the touched events and breaks. What is a more stable way to do this?

local Debris = game:GetService("Debris")
local SoundService = game:GetService("SoundService")

local Master = SoundService.Master

local Piston = {}
Piston.Tag = "Piston"

local DEFAULT_COOLDOWN = 3
local DEFAULT_DELAY = 0.75

function Piston.Function(instance)
	if not instance:IsA("Part") then
		return
	end
	
	instance = instance :: BasePart
	
	local start = instance:FindFirstChild("Start") :: BasePart
	local finish = instance:FindFirstChild("Finish") :: BasePart
	local forward = true
	
	local forwardSpeed = 100 -- no attribute, all pistons have same speed.
	local cooldown = instance:GetAttribute("Cooldown") or DEFAULT_COOLDOWN
	local delay = instance:GetAttribute("Delay") or DEFAULT_DELAY
	
	-- sounds
	local pistonForward = Master.Background.PistonForward
	local pistonBack = Master.Background.PistonBack
	
	if not finish or not start then
		return
	end
	
	local attach0 = Instance.new("Attachment")
	attach0.CFrame = CFrame.new()
	attach0.Parent = instance

	local attach1 = Instance.new("Attachment")
	attach1.CFrame = finish.CFrame
	attach1.Parent = workspace.Terrain
	
	local pris = Instance.new("PrismaticConstraint")
	pris.ActuatorType = Enum.ActuatorType.Motor
	pris.MotorMaxForce = math.huge
	pris.Attachment0 = attach1
	pris.Attachment1 = attach0
	pris.Parent = instance
	
	pris.Velocity = 0
	attach1.CFrame = finish.CFrame

	-- start
	task.spawn(function()
		while instance do
			task.wait(cooldown)
			
			pris.Velocity = forwardSpeed
			
			local sound1 = pistonForward:Clone()
			sound1.Parent = instance
			sound1:Play()
			
			task.wait(delay)
			
			pris.Velocity = -forwardSpeed
			
			local sound2 = pistonBack:Clone()
			sound2.Parent = instance
			sound2:Play()
			
			Debris:AddItem(sound2, 1.5)
			Debris:AddItem(sound1, 1.5)
		end
	end)
	
	finish.Touched:Connect(function(otherPart: BasePart) 
		if forward then
			return
		end
		
		pris.Velocity = 0
		attach1.CFrame = finish.CFrame
		
		forward = true
	end)
	
	start.Touched:Connect(function(otherPart: BasePart) 
		if not forward then
			return
		end
		
		pris.Velocity = 0
		attach1.CFrame = start.CFrame
		
		forward = false
	end)
end

return Piston

Do the pistons slow down or something when they are pushing the player?
Why do you need to detect when the player is being pushed?

I’m not detecting when the player is being pushed, i’m detecting when the piston touches the finish part or start part which is supposed to stop the piston in its tracks


I was able to play around a lot with PrismaticConstraint. I don’t think you need a “Finish” part at all. If you simply set the Upper and Lower limits in Servo mode and LimitsEnabled=true, it will stop as soon as it hits those limits.
Additionally, you can time how long it will take to reach those limits (estimation) by doing task.wait(Distance/Speed) or task.delay(Distance/Speed, function() end). You can get those variables from the PrismaticConstraint.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.