Make a part fall slowly until it touches another part

This should be simple, but my part isn’t detecting when it’s touched. Any way to fix this?

It would be better if you can show us your script here along with any possible errors outputted in the Output tab instead of just describing your problem without a clear context.

local onGround
repeat
		wait(0.001)
		newDrop.Position -= Vector3.new(0, 0.1, 0)
until onGround

newDrop.Touched:Connect(function(hit)
     if hit.Parent.Parent == workspace.Plates.Active then
          onGround = true
     end
end)

No errors. It just doesn’t detect most parts it touches.

Why 0.001 seconds? Try to make it update like every 0.1 seconds your server is probably lagging because of this

Instead of using a code to stimulate the slow-motion of the part falling, use a physics constraint like VectorForce instead.

I tried this in studio and it works well, the event is fired.

False. That has no significant impact of the server’s performance, nor it is the root of the issue.

yeah i was gonna say since when did 0.001 lag the server lmao

Testing this now
char limit char limit

In case if you don’t know how it works:

It applies a force towards where the attachment that you must insert into it is facing, then you have to apply a force that is close to but not equal to the weight of the part. The formula of getting the part’s weight would be Part:GetMass() * workspace.Gravity * c, where c is a constant value ranging between 0 and 1, 0 means no slow motion, while 1 makes it stationary.

The VectorForce isn’t moving the part at all. I’ve set the attachment to a new attachment created inside of the newDrop part, and I’ve set the force, but it doesn’t move.

You must’ve set the property of the VectorForce wrong, can you show me the properties of it?

image

You forgot to set the Force property, obviously it didn’t work. Change the Y value using the formula I have given.

My apologies, I thought that was the internal formula for it. I’m stupid XD

It’s still stationary. The part doesn’t move at all, even with that formula.

Show me what values did you substitute in the c variable in the formula, is it 1? You can show me the properties of the VectorForce instance itself again.

The loop is preventing any other events from running because it is yielding.
Also make sure CanTouch is enabled for the part.
Snippet:

local __ONGROUND = false
coroutine.wrap(function()
repeat
		task.wait()
		newDrop.Position -= Vector3.new(0, 0.1, 0)
until __ONGROUND == true
end)()
newDrop.Touched:Connect(function(hit)
     if hit.Parent.Parent == workspace.Plates.Active then
          __ONGROUND = true
     end
end)
2 Likes

There are a few things:

  • The minimum for wait is 0.03, so wait(0.001), wait(0.03), and wait() are all the same. If you want a faster wait you can use task.wait()
  • Your loop yields, which means the code never creates the touched connection which is meant to end it

To fix your code, simply change the order:

local onGround

newDrop.Touched:Connect(function(hit)
     if hit.Parent.Parent == workspace.Plates.Active then
          onGround = true
     end
end)

repeat
		wait(0.001)
		newDrop.Position -= Vector3.new(0, 0.1, 0)
until onGround

I would also recommend using a connection instead of a loop. It’s nice because it doesn’t yield and cause bugs like this:

local SPEED = 0.1/0.03

local RunService = game:GetService("RunService")

local fallingConnection = RunService.Heartbeat:Connect(function(step)
	newDrop.Position -= Vector3.new(0, 1, 0) * SPEED
end)

newDrop.Touched:Connect(function(hit)
     if hit.Parent.Parent == workspace.Plates.Active then
          -- Stops the function from running
          fallingConnection:Disconnect()
     end
end)

It’s also smoother.

Edit:
Whoops, someone already said that. The real problem is that the part is anchored (probably) so to solve the problem either:

  • Use physics instead (easiest) (like @ItzMeZeus_IGotHacked is saying)
  • Use raycasting or get touching parts every time you move the part to check if it hits something (harder)

I didn’t even notice that! That is actually the solution of the post, I apparently made this thread longer.

I already tried this, I just sent an older version of the code. It detects when some parts touch it, but not all of them

1 Like