How to check if multiple parts are floating?

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

I want to check if multiple parts are floating when the parts below are unanchored

  1. What is the issue? Include screenshots / videos if possible!

I dont know how that would be possible, i imagine that a raycast or a hitbox with GetTouchingParts() would work but i dont think it would be optimal

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I did check in the forums, i found the IsGrounded() function, but i dont really know how that would work since i tested it with print(script.Parent:IsGrounded()) and it printed false, and i really have no idea what to try, i just want some light to see what i can try that works

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Context: It is a hotel natural survival game, and my fear is that part of the hotel will float if the bottom part is destroyed, i have a way to weld all the parts using qPerfectWeld and a way for the disasters to destroy parts.

I would try using a hitbox that goes to every part and checks if it is floating, but i think it would only work on single bricks floating and i tried to use IsGrounded() but it didnt help much when i tested.

Im working on the disasters first and the last thing i will do is the hotel but i am afraid that multiple parts are going to float and i dont see a way to fix that

I want to know if there is anything better than what i just tried or if i did something wrong.

-- This is an example Lua code block

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

I was thinking of a way but i will only be able to test it in a few days, since i will not be home, i will use qPerfectWeld and leave it unanchored and i will always teleport the base to the same position, acting like it is anchored

I found a way to do it:
I used the qPerfectionWeld, i changed “Part0” to my part of choice (Base) and when i want a block to fall i use :BreakJoints() and it will disconnect from the base

The fire disaster i used in the video:

CheckToStart = script.Parent
Copy = script.Parent

function UpdateFire()
	if part.Color == Color3.fromRGB(255, 85, 0) then --change to fire out
		part.Color = Color3.fromRGB(17,17,17)
		part.Material = Enum.Material.Basalt
		part:BreakJoints()
		script:Destroy()
	elseif part.Color == Color3.fromRGB(167,114,0) then -- change to fire 3
		part.Color = Color3.fromRGB(255,85,0)
	elseif part.Color == Color3.fromRGB(255,255,0) then -- change to fire 2
		part.Color = Color3.fromRGB(167,114,0)
	else -- change to fire1
		part.Color = Color3.fromRGB(255,255,0)
		part.Material = Enum.Material.Neon
	end
end
function FireSpread(list)
	--print(list)
	--print("SPREAD FIREEE!")
	for i,v in pairs(list) do
		part = script.Parent.Parent
		--print(v:GetChildren())
		if v:GetChildren() == {} then
			if v.Parent == workspace and v.Name ~= "Baseplate" and
				v~= part and v.Name ~= "HitBox" and v.Name ~= "Handle" then
				--print(v)
				local CLONE = Copy:Clone()
				CLONE.Parent = v
				--print(v)
			end
			--print("no children")
		elseif v:FindFirstChild("StartTrue") then
			--print("Alredy On Fire")
		else
		
			if v.Parent:FindFirstChild("Humanoid") == nil and v.Name ~= "Baseplate" and
				v~= part and v.Name ~= "HitBox" and v.Name ~= "Handle" then
				--print(v)
				local CLONE = Copy:Clone()
				CLONE.Parent = v
				--print(v)
			end
		end
		
	end
end


local results
if CheckToStart.Name == "StartTrue" then
	--print("STARTBURN")
	
	part = script.Parent.Parent
	Hitbox = script:WaitForChild("HitBox")
	Hitbox.Size = Vector3.new((part.Size.X*1.01),(part.Size.Y*1.01),(part.Size.Z*1.01))
	Hitbox.Position = Vector3.new(part.position.x,part.position.y,part.position.z)
	Hitbox.Rotation = Vector3.new(part.Rotation.X,part.Rotation.Y,part.Rotation.Z)
	
	
	
	--game:GetService("RunService").Heartbeat:Connect(GetTouchingParts)
	delay(1,UpdateFire)
	delay(15,UpdateFire)
	delay(23,UpdateFire)
	delay(27,UpdateFire)
	delay(5, function()
		GetTouchingParts()
		FireSpread(results)
	end)
	delay(15, function()
		GetTouchingParts()
		FireSpread(results)
	end)
	delay(23, function()
		GetTouchingParts()
		FireSpread(results)
	end)
	--delay(27,FireSpread)
end

function GetTouchingParts(HitBox)
	part = script.Parent.Parent
	Hitbox.Size = Vector3.new((part.Size.X*1.01),(part.Size.Y*1.01),(part.Size.Z*1.01))
	Hitbox.Position = Vector3.new(part.position.x,part.position.y,part.position.z)
	Hitbox.Rotation = Vector3.new(part.Rotation.X,part.Rotation.Y,part.Rotation.Z)
	--Hitbox = script:WaitForChild("Part")
	local connection = Hitbox.Touched:Connect(function() end)
	results = Hitbox:GetTouchingParts()
	connection:Disconnect()
	--print(#results,results)
	return results
end

Time = 2
while wait(Time) do
	--print("Test")
	if CheckToStart.Name == "StartTrue" then
		--print("Test2")
		--print(GetTouchingParts())
		GetTouchingParts(Hitbox)
		if results ~= nil then
			Time +=6
			FireSpread(results)
			--print("SPREAD")
			--print(Time)
			--delay(5, function()
			--	FireSpread(results)
			--end)
			--delay(15, function()
			--	FireSpread(results)
			--end)
			--delay(23, function()
			--	FireSpread(results)
			--end)
		end
	end
end



qPerfectionWeld:

-- Created by Quenty (@Quenty, follow me on twitter).
-- Should work with only ONE copy, seamlessly with weapons, trains, et cetera.
-- Parts should be ANCHORED before use. It will, however, store relatives values and so when tools are reparented, it'll fix them.

--[[ INSTRUCTIONS
- Place in the model
- Make sure model is anchored
- That's it. It will weld the model and all children. 

THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 
THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 
THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 
THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 
THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 
THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 
THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 
THIS SCRIPT SHOULD BE USED ONLY BY ITSELF. THE MODEL SHOULD BE ANCHORED. 

This script is designed to be used is a regular script. In a local script it will weld, but it will not attempt to handle ancestory changes. 
]]

--[[ DOCUMENTATION
- Will work in tools. If ran more than once it will not create more than one weld.  This is especially useful for tools that are dropped and then picked up again.
- Will work in PBS servers
- Will work as long as it starts out with the part anchored
- Stores the relative CFrame as a CFrame value
- Takes careful measure to reduce lag by not having a joint set off or affected by the parts offset from origin
- Utilizes a recursive algorith to find all parts in the model
- Will reweld on script reparent if the script is initially parented to a tool.
- Welds as fast as possible
]]

-- qPerfectionWeld.lua
-- Created 10/6/2014
-- Author: Quenty
-- Version 1.0.3

-- Updated 10/14/2014 - Updated to 1.0.1
--- Bug fix with existing ROBLOX welds ? Repro by asimo3089

-- Updated 10/14/2014 - Updated to 1.0.2
--- Fixed bug fix. 

-- Updated 10/14/2014 - Updated to 1.0.3
--- Now handles joints semi-acceptably. May be rather hacky with some joints. :/

local NEVER_BREAK_JOINTS = false -- If you set this to true it will never break joints (this can create some welding issues, but can save stuff like hinges).


local function CallOnChildren(Instance, FunctionToCall)
	-- Calls a function on each of the children of a certain object, using recursion.  

	FunctionToCall(Instance)
	--print(Instance)
	for _, Child in next, Instance:GetChildren() do
		CallOnChildren(Child, FunctionToCall)
		--print(Child)
	end
end

local function GetNearestParent(Instance, ClassName)
	-- Returns the nearest parent of a certain class, or returns nil
	--print(Instance)
	local Ancestor = Instance
	repeat
		Ancestor = Ancestor.Parent
		if Ancestor == nil then
			return nil
		end
	until Ancestor:IsA(ClassName)

	return Ancestor
end

local function GetBricks(StartInstance)
	--print(StartInstance)
	local List = {}

	-- if StartInstance:IsA("BasePart") then
	-- 	List[#List+1] = StartInstance
	-- end

	CallOnChildren(StartInstance, function(Item)
		if Item:IsA("BasePart") then
			List[#List+1] = Item;
			--print(List,Item)
		end
	end)

	return List
end

local function Modify(Instance, Values)
	-- Modifies an Instance by using a table.  

	assert(type(Values) == "table", "Values is not a table");

	for Index, Value in next, Values do
		if type(Index) == "number" then
			Value.Parent = Instance
		else
			Instance[Index] = Value
		end
	end
	return Instance
end

local function Make(ClassType, Properties)
	-- Using a syntax hack to create a nice way to Make new items.  

	return Modify(Instance.new(ClassType), Properties)
end

local Surfaces = {"TopSurface", "BottomSurface", "LeftSurface", "RightSurface", "FrontSurface", "BackSurface"}
local HingSurfaces = {"Hinge", "Motor", "SteppingMotor"}

local function HasWheelJoint(Part)
	for _, SurfaceName in pairs(Surfaces) do
		for _, HingSurfaceName in pairs(HingSurfaces) do
			if Part[SurfaceName].Name == HingSurfaceName then
				return true
			end
		end
	end
	
	return false
end

local function ShouldBreakJoints(Part)
	--- We do not want to break joints of wheels/hinges. This takes the utmost care to not do this. There are
	--  definitely some edge cases. 

	if NEVER_BREAK_JOINTS then
		return false
	end
	
	if HasWheelJoint(Part) then
		return false
	end
	
	local Connected = Part:GetConnectedParts()
	
	if #Connected == 1 then
		return false
	end
	
	for _, Item in pairs(Connected) do
		if HasWheelJoint(Item) then
			return false
		elseif not Item:IsDescendantOf(script.Parent) then
			return false
		end
	end
	
	return true
end
local BASE = script.Parent:FindFirstChild("BASE")
print(BASE)
local function WeldTogether(Part0, Part1, JointType, WeldParent)
	--print(Part0, Part1, JointType, WeldParent)
	
	--- Weld's 2 parts together
	-- @param Part0 The first part
	-- @param Part1 The second part (Dependent part most of the time).
	-- @param [JointType] The type of joint. Defaults to weld.
	-- @param [WeldParent] Parent of the weld, Defaults to Part0 (so GC is better).
	-- @return The weld created.

	JointType = JointType or "Weld"
	local RelativeValue = Part1:FindFirstChild("qRelativeCFrameWeldValue")
	
	
	
	local NewWeld = Part1:FindFirstChild("qCFrameWeldThingy") or Instance.new(JointType)
	Modify(NewWeld, {
		Name = "qCFrameWeldThingy";
		Part0  = BASE;
		Part1  = Part1;
		C0     = CFrame.new();--Part0.CFrame:inverse();
		C1     = RelativeValue and RelativeValue.Value or Part1.CFrame:toObjectSpace(BASE.CFrame); --Part1.CFrame:inverse() * Part0.CFrame;-- Part1.CFrame:inverse();
		Parent = Part1;
	})

	if not RelativeValue then
		RelativeValue = Make("CFrameValue", {
			Parent     = Part1;
			Name       = "qRelativeCFrameWeldValue";
			Archivable = true;
			Value      = NewWeld.C1;
		})
	end

	return NewWeld
end

local function WeldParts(Parts, MainPart, JointType, DoNotUnanchor)
	print(Parts, MainPart, JointType, DoNotUnanchor)
	-- @param Parts The Parts to weld. Should be anchored to prevent really horrible results.
	-- @param MainPart The part to weld the model to (can be in the model).
	-- @param [JointType] The type of joint. Defaults to weld. 
	-- @parm DoNotUnanchor Boolean, if true, will not unachor the model after cmopletion.
	
	for _, Part in pairs(Parts) do
		if ShouldBreakJoints(Part) then
			Part:BreakJoints()
		end
	end
	
	for _, Part in pairs(Parts) do
		if Part ~= BASE then
			WeldTogether(BASE, Part, JointType, BASE)
			--print(MainPart, Part, JointType, MainPart)
		end
	end

	if not DoNotUnanchor then
		for _, Part in pairs(Parts) do
			Part.Anchored = false
		end
		--BASE.Anchored = false
	end
end

local function PerfectionWeld()	
	local Tool = GetNearestParent(script, "Tool")

	local Parts = GetBricks(script.Parent)
	local PrimaryPart = Tool and Tool:FindFirstChild("Handle") and Tool.Handle:IsA("BasePart") and Tool.Handle or script.Parent:IsA("Model") and script.Parent.PrimaryPart or Parts[1]

	if PrimaryPart then
		WeldParts(Parts, PrimaryPart, "Weld", false)
	else
		warn("qWeld - Unable to weld part")
	end
	
	return Tool
end

local Tool = PerfectionWeld()


if Tool and script.ClassName == "Script" then
	--- Don't bother with local scripts

	script.Parent.AncestryChanged:connect(function()
		PerfectionWeld()
	end)
end

-- Created by Quenty (@Quenty, follow me on twitter).

The video showing the results:
Video

Nevermind, i thought i did fix it
It did not work
ill show a video of it and what is happening

Floating parts

The parts are being unanchored but the parts above are not falling with the other parts

OK now i think i did fix it:

All of the parts were anchored to a single BASE part, and i accidently made that part anchored, so all i needed to do was unanchor that part and it all works

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