Move:14: invalid argument #2 (Vector3 expected, got CFrame)

Hi,

I am trying to make a part move system like robloxs default move system but I am having a problem calculating the cframe average of multiple parts. When I try to calculate multiple cframe it prints out a error:

Move:14: invalid argument #2 (Vector3 expected, got CFrame) 

Here’s the script:

local UserInputService = game:GetService("UserInputService")
local SoundService = game:GetService("SoundService")
local CollectionService = game:GetService("CollectionService")

local Enabled = false
local Move = script.Move

local Player = game.Players.LocalPlayer

-- auxiliary
function AvgCFrame(CFrameTable:{ [a]: CFrame })
	local sum = CFrame.new()
	for _,cf in pairs(CFrameTable) do
		sum = sum + cf -- line 14 is here i think
	end
	
	return sum / #CFrameTable
end

function AvgVector(VectorTable:{ [a]: Vector3 })
	local sum = Vector3.new()
	for _,v3 in pairs(VectorTable) do
		sum = sum + v3
	end

	return sum / #VectorTable
end

-- main funcs
function MoveEnabled(Input)
	if Input.KeyCode == Enum.KeyCode.F and not script.Enable.IsPlaying then
		Enabled = not Enabled
		if not Enabled then
			Move.Parent = script
			return
		end
		
		local Selected = CollectionService:GetTagged("Selected")
		if #Selected == 0 then
			warn("No selected objects")
			return 
		end
		
		Move.Parent = workspace.Terrain
		
		local Parts = {}
		local Models = {}
		
		for _, Part in pairs(Selected) do
			if Part:IsA("Model") then
				table.insert(Models,Part.WorldPivot)
			end
			
			if Part:IsA("Part") then
				table.insert(Parts,Part.CFrame)
			end
		end
		
		if #Parts == 1 then
			local Origin = Parts[1]
			Move:PivotTo(Origin)
		end
		
		if #Parts > 1 then
			print(Parts)
			local MoveCFrame = AvgCFrame(Parts)
			Move:PivotTo(MoveCFrame)
		end
		
		if #Models == 1 then
			local WPVT = Models[1]
			Move.WorldPivot = WPVT
		end
		
		if #Models > 1 then
			local AvgWPVT = AvgCFrame(Models)
			Move.WorldPivot = AvgWPVT
		end
		
		SoundService:PlayLocalSound(script.Enable)
	end
end

function InstanceRemoved()
	Move.Parent = script   
end

CollectionService:GetInstanceRemovedSignal("Selected"):Connect(InstanceRemoved)
UserInputService.InputBegan:Connect(MoveEnabled)


Here’s footage showing how it only works on one part and breaks when theres multiple parts

You can’t add CFrames too each other. You can just average the components and turn them back into a CFrame, but I’m not sure if that’s actually an “average” CFrame.

When you combine 2 CFrames, you don’t add them, you multiply them.

sum = sum * cf -- line 14 is here i think
1 Like

Are you sure? It works when I use it for Vector3 tables.

that seemed to fix that issue but I got another problem:

Move:18: attempt to perform arithmetic (div) on CFrame and table

its because im doing sum / #CFrameTable but idk how to fix it

When you use the + operation you must provide a Vector3. Instead I’d recommend using *.

Change This

To

function AvgCFrame(CFrameTable:{ [a]: CFrame })
	local sum = CFrame.new()
	for _,cf in pairs(CFrameTable) do
		sum = sum * cf -- fixed
	end
	
	return (sum.Position / #CFrameTable) 
		* CFrame.Angles(
			sum:ToEulerAnglesXYZ()
		) -- this too
end
1 Like

You cannot divide CFrames. You can lerp them instead in line 14 instead of dividing it in the return.

sum = sum:lerp(cf, 1/#CFrameTable)
2 Likes

It prints a error: Move:18: invalid argument #2 (Vector3 expected, got CFrame)

	return (sum.Position / #CFrameTable) 
		* CFrame.Angles(
			sum:ToEulerAnglesXYZ() -- this might be the issue
		)