Parts frozen in time


-- Processes a given model for simulation behavior
local function ProcessModel(model)
	-- Run the function on a separate task thread (non-blocking)
	task.delay(0, function()

		-- Validate input model
		if not model or not model:IsA("Model") or model.Name == "Trees" then
			warn("Invalid model provided: ".. model.Name)
			return
		end

		-- Get the model's PrimaryPart (used as the anchor/reference)
		local primaryPart = model.PrimaryPart

		-- Remove all attributes from the PrimaryPart
		for attributeName in pairs(primaryPart:GetAttributes()) do
			primaryPart:SetAttribute(attributeName, nil)
		end

		-- Function to check if a part is grounded (touching Terrain)
		local function isGrounded(part)
			-- Get a list of parts that the current part is touching
			local touchingParts = part:GetTouchingParts()

			-- Return true if touching terrain
			for _, touchingPart in ipairs(touchingParts) do
				if touchingPart:IsA("Terrain") then
					return true
				end
			end

			return false
		end

		-- Weld two parts together using WeldConstraint
		local function weldParts(part1, part2)
			-- Only proceed if both are BaseParts
			if not part1:IsA("BasePart") or not part2:IsA("BasePart") then
				return
			end

			-- Check if a weld already exists to avoid duplication
			for _, weld in ipairs(part1:GetChildren()) do
				if weld:IsA("WeldConstraint") and 
				   ((weld.Part0 == part1 and weld.Part1 == part2) or 
					(weld.Part0 == part2 and weld.Part1 == part1)) then
					return -- Weld already exists
				end
			end

			-- Create and set up the weld
			local weld = Instance.new("WeldConstraint")
			weld.Part0 = part1
			weld.Part1 = part2
			weld.Parent = part1
		end

		-- Collect all BaseParts in the model
		local allParts = {}
		for _, part in pairs(model:GetDescendants()) do
			if part:IsA("BasePart") then
				table.insert(allParts, part)

				-- Unanchor all parts initially (except the primary part)
				if part ~= primaryPart then
					part.Anchored = false
				end

				-- Connect a Touched event to re-anchor the part if it touches Terrain
				local touchConnection
				touchConnection = part.Touched:Connect(function(hitPart)
					-- If part is removed, disconnect the connection
					if not part:IsDescendantOf(workspace) then
						touchConnection:Disconnect()
						return
					end

					-- Re-anchor part if it touches terrain (and is still grounded)
					if hitPart:IsA("Terrain") then
						if isGrounded(part) then
							part.Anchored = true
						end
					end
				end)

				-- Monitor each part per frame to check if it's still grounded
				local heartbeatConnection
				heartbeatConnection = game:GetService("RunService").Heartbeat:Connect(function()
					if not part:IsDescendantOf(workspace) then
						heartbeatConnection:Disconnect()
						return
					end

					-- If the part was anchored but no longer grounded, unanchor it
					if part.Anchored and part ~= primaryPart then
						if not isGrounded(part) then
							part.Anchored = false
						end
					end
				end)
			end
		end

		-- On startup: anchor any part already touching the ground
		for _, part in ipairs(allParts) do
			if part ~= primaryPart and isGrounded(part) then
				part.Anchored = true
			end
		end

		-- === TOUCHING LOGIC PLACEHOLDER ===
		-- You could add logic here to weld together parts that are touching each other

		-- Function to check if model should be removed (e.g., only primary part is left)
		local function checkForRemoval()
			local remainingParts = 0

			for _, part in pairs(model:GetDescendants()) do
				if part:IsA("BasePart") then
					remainingParts += 1
				end
			end

			-- If only 1 BasePart remains (the primary), destroy the whole model
			if remainingParts <= 1 then
				model:Destroy()
			end
		end

		-- Listen for parts being removed from the model
		model.DescendantRemoving:Connect(function(descendant)
			-- If a BasePart (not the primary) is removed, check if model should be destroyed
			if descendant:IsA("BasePart") and descendant ~= primaryPart then
				task.defer(checkForRemoval) -- delay to let removal finish
			end
		end)

		return true -- indicate success
	end)
end

Function is called every time a pet is placed for the terrain. The video explains the outcomes shown. This rock model in particular is just a min model with a primary and parts underneath it. One issue could be that the parts are deeply intersecting when anchored. But even so this shouldn’t happen

The script is not at all complicated it’s just made of large ish parts. Welding checks and other functions

The video won’t load and I’m given absolutely no context or anything about the situation. Can you please clearly explain your goal, the issue, what’s happening right now, and the solutions you’ve tried so far? This will help me and others to understand how to help you solve your issue.

2 Likes

Oh I’m sorry idk what I was on. Basically when generating all this terrain and stuff. I also place trees rocks and occasionally other structures as well. I abt to incoperate digging into my game rn. Before all the structures were fully anchored. Now im trying to weld them by which ones touch each other. This is for :pick: mining for the game. Next I wanted bricks to fall so if you deleted the blocks underneath the part the top part would fall. I also wanted it that when spawning the structure like trees or rocks or wtv. Parts that are “grounded” or that are touching terrain will be anchored inside the model but will also be still be welded normally.

After all this I still have a listener for parts that are grounded to see if there no longer touching terrain therefore unanchoring them. All of this works fine I suppose. It does add 1k gb of memory but it is what it is ig.

The problem is that there are these weird “thrown” parts like such in the video

Video showing problem ^

Showing mining. This is before we added the process mode function of it matters

1 Like

Ah ok. It’s late for me so my brain is not working so I won’t be able to help you. Try using stuff with workspace:GetPartBoundsInBox if you haven’t already. (If I read it right you might need it)
Anyways best of luck probably take my reply with a grain of salt.

1 Like

Bounds in box for what? to get the parts touching with out using :touchingparts?

Ohhhh I think I get it now.

Why would the grounded part be moved away from terrain though?

Also if you’re already using :touchingparts or whatever then you’re fine.
Anyways peace

1 Like