Keep unanchored objects from falling

having multiple problems with my bowling lane which is getting really frustrating to figure out which i could use some help on,

the bowling lane just doesn’t seem to pick up all the pins when i want it to, and the physics seem to be really weird when the animation for the pinsetter places the pins down so that the player can roll again. it seems that it just collides through the floor and then goes back up, but even if i got it right, the pins seem to just randomly tilt to an angle and slowly fall on their side. on the other hand, the sweeper that should clean out all the pins don’t even clearly do what it needs to do as the sweeper just straight up goes through the pins like the pins never existed.

i’m aware that the animation collisions are quite whack, and i have researched around and about for that subject however i am not bothering with making my own physics system as i think that’s just seriously too much for this kind of thing i want. for the pins just slowly tilting until their demise to their side, i tried to lock them in parts as shown below, but it didn’t make any difference.

as for the pins that just don’t get picked up, i’m not sure what’s causing that. the code below is basically the entire system for how i do the bowling lane. i thought i had done the math logic right since i’m checking for both, WHETHER the bowling pin has fallen to its side, and that the bowling pin is still around in the spot that it should be.

local tweenService = game:GetService("TweenService")
local replicatedStorage = game:GetService("ReplicatedStorage")

local bowlingLane = script.Parent
local bowlingpins = bowlingLane["bowling pins"]
local scanner = bowlingLane.Scanner
local sweeper = bowlingLane.sweeper
local scooper = bowlingLane.scooper -- thing that picks up ur pins

local sweeperKeyFrames = sweeper.Keyframes

local alreadycleaning = false
local turn = 1
local totalCount = 0

--211.601, -0.775, 7.593

local function countPinsKnocked()
	-- passed first test, are the pins standing?
	local passedFirstTest = {}
	local count = 0
	
	local pinsStillStanding = workspace:FindPartsInRegion3(Region3.new( Vector3.new(
		scooper.check.Position.x - scooper.check.Size.x/2,
		scooper.check.Position.y - scooper.check.Size.y/2,
		scooper.check.Position.z - scooper.check.Size.z/2
		),
		Vector3.new(
			scooper.check.Position.x + scooper.check.Size.x/2,
			scooper.check.Position.y + scooper.check.Size.y/2,
			scooper.check.Position.z + scooper.check.Size.z/2) ) )
	
	-- how many pins still stand
	for _, pin in pairs(pinsStillStanding) do
		-- prevent error from index number with 'typeof'
		if typeof(pin) ~= "number" then
			if pin:IsA("MeshPart") and string.sub(pin.Name, 1, 3) == "pin" then
				table.insert(passedFirstTest, pin)
			end
		end
	end
	
	-- since we know that it didnt pass that sinngle check, we can now see if any pins are standing in their correct desired position.
	for i, pin in pairs(passedFirstTest) do
		if pin:FindFirstChild("stand") then
			local stand = workspace:FindPartsInRegion3(Region3.new( Vector3.new( 
				pin:FindFirstChild("stand").Position.x - pin:FindFirstChild("stand").Size.x/2,
				pin:FindFirstChild("stand").Position.y - pin:FindFirstChild("stand").Size.y/2,
				pin:FindFirstChild("stand").Position.z - pin:FindFirstChild("stand").Size.z/2
				),
				Vector3.new(
					pin:FindFirstChild("stand").Position.x + pin:FindFirstChild("stand").Size.x/2,
					pin:FindFirstChild("stand").Position.y + pin:FindFirstChild("stand").Size.y/2,
					pin:FindFirstChild("stand").Position.z + pin:FindFirstChild("stand").Size.z/2) ) )
			
			for _, pin in ipairs(stand) do
				-- prevent error from index number with 'typeof'
				if typeof(pin) ~= "number" then
					if pin:IsA("MeshPart") and string.sub(pin.Name, 1, 3) == "pin" and string.sub(pin.Name, 5, 6) == i then
						-- the pin is still standing
						table.remove(passedFirstTest, table.find(passedFirstTest, pin))
						count += 1
					end
				end
			end
		end
	end
	
	count = 10 - #passedFirstTest
	totalCount = count
	return passedFirstTest
end

for _, v in bowlingLane.ANCHORS:GetChildren() do
	for _, w in v:GetChildren() do
		w.CanCollide = false
		w.Transparency = 1
	end
end

scanner.Touched:Connect(function(hit)
	if hit.Name == "BowlingBall" and not alreadycleaning then
		bowlingpins = bowlingLane["bowling pins"]
		local clone = nil
		local amountKnocked = nil
		alreadycleaning = true
		wait(0.5)
		tweenService:Create(sweeper.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {CFrame = CFrame.new(sweeperKeyFrames.Frame1.Position) }):Play()
		
		wait(2)
		-- start cleaning and counting
		if turn == 2 or totalCount == 10 then
			tweenService:Create(scooper.PrimaryPart, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.In, 0, true), {CFrame = CFrame.new(scooper.Keyframes.Frame2.Position)}):Play()
			wait(0.5)
			clone = game:GetService("ReplicatedStorage")["bowling pins"]:Clone()
			clone.Parent = bowlingLane
			for _, v in clone:GetChildren() do
				v.Anchored = true
				v.Position = Vector3.new(v.Position.X, 3.3, v.Position.Z)
				tweenService:Create(v, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {Position = Vector3.new(v.Position.X, 2, v.Position.Z)}):Play()
			end
		else
			tweenService:Create(scooper.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, true), {CFrame = CFrame.new(scooper.Keyframes.Frame1.Position)}):Play()
			wait(1)

			amountKnocked = countPinsKnocked()
			for i, v in amountKnocked do
				v.Anchored = true
				tweenService:Create(v, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {Position = Vector3.new(v.Position.X, 2, v.Position.Z)}):Play()
			end

			wait(1)
		end
		tweenService:Create(sweeper.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), {CFrame = CFrame.new(sweeperKeyFrames.Frame2.Position) }):Play()
		
		wait(1)
		
		tweenService:Create(sweeper.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), {CFrame = CFrame.new(sweeperKeyFrames.Frame1.Position) }):Play()

		wait(1)
		
		for _, v in bowlingLane.ANCHORS:GetChildren() do
			for _, w in v:GetChildren() do
				w.CanCollide = true
			end
		end
		
		tweenService:Create(scooper.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, true), {CFrame = CFrame.new(scooper.Keyframes.Frame1.Position)}):Play()
		
		if turn == 2 or totalCount == 10 then
			bowlingpins:Destroy()
			
			if clone then
				for _, v in clone:GetChildren() do
					local tween = tweenService:Create(v, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {Position = Vector3.new(v.Position.X, -1.697, v.Position.Z)})
					tween:Play()
					tween.Completed:Connect(function()
						wait(0.5)
						v.Anchored = false
					end)
				end
			end
			
			totalCount = 0
			turn = 1
		else
			for i, v in amountKnocked do
				local tween = tweenService:Create(v, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {Position = Vector3.new(v.Position.X, -1.697, v.Position.Z)})
				tween:Play()
				tween.Completed:Connect(function()
					wait(0.5)
					v.Anchored = false
				end)
			end

			turn = 2
		end
		
		wait(1)
		tweenService:Create(sweeper.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {CFrame = CFrame.new(sweeperKeyFrames.Frame3.Position) }):Play()
		alreadycleaning = false
		
		spawn(function()
			wait(1)
			for _, v in bowlingLane.ANCHORS:GetChildren() do
				for _, w in v:GetChildren() do
					w.CanCollide = false
				end
			end
		end)
	end
end)

sweeper.Union:GetPivot()

if anyone can, could anyone please help me on this? i’m really starting to give up on this and the amount of headaches i’ve got trying to fix this is immense.

As I can see on the video the problem might be the fact that an anchored part tries to push unanchored parts. This is not possible inside of the Roblox engine (at least according to my research). Anchored parts can’t push unachored parts like that. To fix that make it so an unanchored part pushes other unanchored parts. You can try doing that by welding to the anchored part a new unanchored part.

see, i have a PrimaryPart already created on the sweeper (if thats what you’re referencing) and that is anchored, while the entire union is actually unanchored.


I see. I will come back later to this problem to try to solve it.

1 Like

I don’t really know how bowling works. Is the sweeper thing meant to knock over all the ones that are still on the thing?
If I remember correctly, tweens don’t yield for physics; would it be possible to use LinearVelocity or AlignPosition instead, since these are designed to work alongside physics? Try testing these, here’s the documentation for it if you’re still stuck:

Also, I’m assuming that everything has CanCollide enabled?
For the pin pick-up system, is it meant to pick them up only if it’s fallen over? What’s the stuff about being in the same area?
Sorry, I don’t know that much about bowling. If you could explain some of this to me, it could be quite helpful.
And please, take a break. If you’re getting a lot of headaches from this, take a break for a bit and come back later.

2 Likes

i’ve tried AlignPosition before on another different bowling lane model, but that ended up forcing all of the pins in one position or i may have likely not used it right (this was like a month ago). but i have thought about LinearVelocity, i read the description on the documentary but it made no sense to me (for me being dumb lol) and i ended up skipping it. ill consider trying that out

theres some videos online that explain how a bowling lane works, here is one linked: How a Bowling Alley Works - YouTube this is from a really long time, but its short and really good for even modern times today.

1 Like

Thanks, will watch this video. I need to go for a bit but I’ll be back later.
EDIT: I won’t be back until tomorrow. Sorry.

I want to add something to what @ValtryekRBLX said:
Collission Test.rbxl (42.8 KB)
I probably found why it doesn’t work. I did a quick test. There are 3 parts in this place: red PartX (unanchored part to push), green PartY (unanchored part, which should push PartX) and blue PartZ (anchored part welded with PartY). After 2 seconds of running the game the position of PartZ is tweened to try making PartY push PartX but it doesn’t work. PartY and PartZ go through PartX.

1 Like

huh that’s odd, i took a look at the other bowling model i made and i only have one single part, so no model nor primaryparts, nothing that sweeps the entire board decently, but sometimes can miss a pin randomly. in which, could help prove what you said here.

this video shows the way i didn’t use alignposition and it MOSTLY works but it can miss some pins (also further helps with the things that i said, one pin is missed at the end): dev forum??? - YouTube

this video shows the way i did alignposition just ended up not working out:

could someone please help me with this? i couldn’t get much responses and i would really appreciate if i could get some support…

COULD I PLEASE get any help? i have not gotten any responses and i would really appreciate if i can get some assistance with this problem, i have no other solutions i can think of.

nearly 14 days later, i have tried to work with linearvelocity and to what i’ve noticed, i found out that tweens don’t exactly respect/recognize the collisions, can anyone please give me any help? i’m sitting here in shambles.

ok, after dirty fixes, all i want to know is how to make it so that the bowling pins don’t fall over after getting unanchored as shown in the video. please, i’ve gotten absolutely no assistance.

So I would’ve made a folder of the pins, just a copy and call it like lane 1 or smth and let it sit in rep storage, when the tween or stuff ended we copy the folder inside rep storage and place it in workspace. Yeah, that’s how I would do it. lmk if it works

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