Player starts hovering above ground after placing down a part

  1. What do you want to achieve?
    Hi, I’m making a system to pick up and place cakes. I’m testing with a model with 2 parts and a set primary part, a model with 2 parts without a set primary part, a model with 1 union and a set primary part and a part that is not a child of any model.
  2. What is the issue?
    After picking up and placing the part/model, the player starts hovering above the ground.
    robloxapp-20240708-0951227.wmv (3.7 MB)
    (Sorry for low quality)
  3. What solutions have you tried so far?
    I searched on the dev forum, but I haven’t found any solution.

Here is the code:

--!strict
-- I like when I have to define the types of variables
local LocalPlayer : Player = game:GetService("Players").LocalPlayer
local RE : RemoteEvent = game:GetService("ReplicatedStorage"):WaitForChild("Events"):WaitForChild("PlacementSystem")
local mouse : Mouse = LocalPlayer:GetMouse()
local character : Model = script.Parent
local middleOfCharacter : BasePart = character:FindFirstChildWhichIsA("Humanoid").RootPart :: BasePart -- Here I got warning that Humanoid could be nil, but that's off topic.
local RunService : RunService = game:GetService("RunService")
local movePart : RBXScriptConnection
local x : number = 0
local object : BasePart | nil
local rotation : Vector3
local ObjectParentModel : any

local function getMouseTarget() : BasePart | nil
	local cursorPosition : Vector2 = game:GetService("UserInputService"):GetMouseLocation()
	local oray : Ray = game.workspace.CurrentCamera:ViewportPointToRay(cursorPosition.X, cursorPosition.Y, 0)
	local ray : Ray = Ray.new(game.Workspace.CurrentCamera.CFrame.p,(oray.Direction * 1000))

	local object : BasePart = workspace:FindPartOnRayWithIgnoreList(ray, {character})

	if (middleOfCharacter.Position - object.Position).Magnitude > 50 or object.Anchored then 
		return nil 
	end

	return object
end

mouse.Button1Down:Connect(function()
	if x == 0 then
		object = getMouseTarget()
		if not object then return end
		ObjectParentModel = nil
		rotation = object.Rotation

		repeat
			if ObjectParentModel then
				ObjectParentModel = ObjectParentModel.Parent
			else
				ObjectParentModel = object.Parent
			end
		until ObjectParentModel:IsA("Model") or ObjectParentModel:IsA("Workspace")
		
		if ObjectParentModel:IsA("Workspace") then ObjectParentModel = nil end
        -- Sets O.P.M. to nil, because later the script would set every basepart in the workspace to not collide, not touch and not querry.
		
		mouse.TargetFilter = ObjectParentModel or object

		if ObjectParentModel and ObjectParentModel.PrimaryPart ~= nil then -- If the object is in model and that model got set primary part
			for _, child : Instance in ipairs(ObjectParentModel:GetDescendants()) do
				if child:IsA("BasePart") then
					child.CanCollide = false
					child.CanTouch = false
					child.CanQuery = false
				end
			end
			if ObjectParentModel.PrimaryPart:IsA("Part") then -- If primary part is a part
				if ObjectParentModel.PrimaryPart.Shape == Enum.PartType.Cylinder then  -- If primary part is a cylinder
					movePart = RunService.Heartbeat:Connect(function(deltaTime) 
						ObjectParentModel:PivotTo(CFrame.new(
							math.floor(mouse.Hit.Position.X),
							mouse.Hit.Position.Y + ObjectParentModel.PrimaryPart.Size.X/2,
							math.floor(mouse.Hit.Position.Z)
							) * CFrame.fromEulerAnglesXYZ(
								math.rad(rotation.X),
								math.rad(rotation.Y),
								math.rad(rotation.Z)
							)
						)
					end)
				elseif ObjectParentModel.PrimaryPart.Shape == Enum.PartType.Block then  -- If primary part is a block
					movePart = RunService.Heartbeat:Connect(function(deltaTime) 
						ObjectParentModel:PivotTo(CFrame.new(
							math.floor(mouse.Hit.Position.X),
							mouse.Hit.Position.Y + ObjectParentModel.PrimaryPart.Size.Y/2,
							math.floor(mouse.Hit.Position.Z)
							) * CFrame.fromEulerAnglesXYZ(
								math.rad(rotation.X),
								math.rad(rotation.Y),
								math.rad(rotation.Z)
							)
						)
					end)
				end
			else  -- If primary part is a union
				movePart = RunService.Heartbeat:Connect(function(deltaTime) 
					ObjectParentModel:PivotTo(CFrame.new(
						math.floor(mouse.Hit.Position.X),
						mouse.Hit.Position.Y + object.Size.X/2,
						math.floor(mouse.Hit.Position.Z)
						) * CFrame.fromEulerAnglesXYZ(
							math.rad(rotation.X),
							math.rad(rotation.Y),
							math.rad(rotation.Z)
						)
					)
				end)
			end
		else -- for a part without a model as a parent and for models without a set primary part (but welded together with WeldCoinstrain)
			if ObjectParentModel then
				for _, child : Instance in ipairs(ObjectParentModel:GetDescendants()) do
					if child:IsA("BasePart") then
						child.CanCollide = false
						child.CanTouch = false
						child.CanQuery = false
					end
				end
			end
			
			movePart = RunService.Heartbeat:Connect(function(deltaTime) 
				object.CFrame = (CFrame.new(
					math.floor(mouse.Hit.Position.X),
					mouse.Hit.Position.Y + object.Size.X/2,
					math.floor(mouse.Hit.Position.Z)
					) * CFrame.fromEulerAnglesXYZ(
						math.rad(rotation.X),
						math.rad(rotation.Y),
						math.rad(rotation.Z)
					)
				)
			end)
		end
		x = 1
	elseif x == 1 then
		if not object then return end
		if (mouse.Hit.Position - middleOfCharacter.Position).Magnitude > 50 then return end

		movePart:Disconnect() -- Stop moving the block
		mouse.TargetFilter = nil
		repeat
			if ObjectParentModel then
				ObjectParentModel = ObjectParentModel.Parent
			else
				ObjectParentModel = object.Parent
			end
		until ObjectParentModel:IsA("Model") or ObjectParentModel:IsA("Workspace")
		
		if ObjectParentModel then
			for _, child : any in ipairs(ObjectParentModel:GetDescendants()) do
				if child:IsA("BasePart") then
					child.CanCollide = true
					child.CanTouch = true
					child.CanQuery = true
				end
			end
		end
		ObjectParentModel = nil
		RE:FireServer(mouse.Hit.Position, object, rotation) -- Server script is simple just set that object to that position with that rotation
		x = 0
	end
end)
1 Like

Hi again!
After 3 days I found out why it’s happening. In elseif statement x == 1 I have a repeat statement and an if statement. I forgot to add if ObjectParentModel is a Workspace then ObjectParentModel is nil. That made EVERY BASEPART including character accessories to CanCollide to true. So my shoes were collidable and I walked funny.

1 Like