Invalid argument #2 (Vector3 expected, got CFrame)

im making a VR script for grabbing and holding items.

keep getting the error “invalid argument #2 (Vector3 expected, got CFrame)”

ServerScript:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")

-- RemoteEvent for handling grab/release requests
local grabRemote = Instance.new("RemoteEvent")
grabRemote.Name = "GrabRemote"
grabRemote.Parent = ReplicatedStorage

-- Keeps track of the grabbed objects
local grabbedObjects = {}

-- Handles grab/release requests from clients
grabRemote.OnServerEvent:Connect(function(player, action, object, hand, position, rotation)
	if action == "Grab" and object:IsA("BasePart") then
		object:SetNetworkOwner(player)
		object.Anchored = false -- Ensure it remains unanchored
		grabbedObjects[object] = true
		print(player.Name .. " grabbed object:", object.Name)
	elseif action == "Release" and object:IsA("BasePart") then
		object.Anchored = false
		object:SetNetworkOwner(nil)
		grabbedObjects[object] = nil
		print(player.Name .. " released object:", object.Name)
	elseif action == "Update" and object:IsA("BasePart") and grabbedObjects[object] then
		-- Update the object's CFrame based on position and rotation
		object.CFrame = CFrame.new(position) * CFrame.Angles(math.rad(rotation.X), math.rad(rotation.Y), math.rad(rotation.Z))
	end
end)

LocalScript in StarterPlayerScripts

-- LocalScript: StarterPlayerScripts/VRGrabScript
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local grabbing = false
local grabbedObject = nil
local grabDistance = 3 -- Adjust based on how far you want the user to reach
local currentHand = nil

-- RemoteEvent for requesting grab/release
local grabRemote = ReplicatedStorage:WaitForChild("GrabRemote")

-- Function to handle grabbing objects
local function grabObject(hand)
	if grabbing then
		return
	end

	currentHand = hand
	local handCFrame = UserInputService:GetUserCFrame(hand)
	local cameraCFrame = Workspace.CurrentCamera.CFrame
	local handWorldCFrame = cameraCFrame * handCFrame
	local handWorldPosition = handWorldCFrame.Position

	for _, part in pairs(Workspace.CanGrab:GetChildren()) do
		if part:IsA("BasePart") then
			local distance = (part.Position - handWorldPosition).Magnitude
			if distance <= grabDistance then
				grabbing = true
				grabbedObject = part
				grabRemote:FireServer("Grab", part, hand, handWorldPosition, handWorldCFrame) -- Pass handWorldCFrame to server
				print("Request to grab object:", part.Name)
				break
			end
		end
	end
end

-- Function to handle releasing objects
local function releaseObject()
	if not grabbing then
		return
	end

	grabbing = false
	grabRemote:FireServer("Release", grabbedObject)
	grabbedObject = nil
	currentHand = nil
	print("Request to release object")
end

-- Input listener for VR controller
UserInputService.InputBegan:Connect(function(input, processed)
	if processed then return end

	if input.UserInputType == Enum.UserInputType.Gamepad1 then
		if input.KeyCode == Enum.KeyCode.ButtonR2 then
			grabObject(Enum.UserCFrame.RightHand)
		elseif input.KeyCode == Enum.KeyCode.ButtonL2 then
			grabObject(Enum.UserCFrame.LeftHand)
		end
	end
end)

UserInputService.InputEnded:Connect(function(input, processed)
	if processed then return end

	if input.UserInputType == Enum.UserInputType.Gamepad1 then
		if input.KeyCode == Enum.KeyCode.ButtonR2 and currentHand == Enum.UserCFrame.RightHand then
			releaseObject()
		elseif input.KeyCode == Enum.KeyCode.ButtonL2 and currentHand == Enum.UserCFrame.LeftHand then
			releaseObject()
		end
	end
end)

-- Continuously update the position and rotation of the grabbed object
RunService.RenderStepped:Connect(function()
	if grabbing and grabbedObject then
		local handCFrame = UserInputService:GetUserCFrame(currentHand)
		local cameraCFrame = Workspace.CurrentCamera.CFrame
		local handWorldCFrame = cameraCFrame * handCFrame
		local handWorldPosition = handWorldCFrame.Position
		local relativeRotation = (cameraCFrame - handWorldCFrame).LookVector

		-- Convert relative rotation to Euler angles
		local rotationX = math.deg(math.atan2(-relativeRotation.Y, -relativeRotation.Z))
		local rotationY = math.deg(math.atan2(relativeRotation.X, math.sqrt(relativeRotation.Y^2 + relativeRotation.Z^2)))
		local rotationZ = 0 -- We assume no roll for simplicity

		-- Convert handWorldPosition to Vector3
		handWorldPosition = Vector3.new(handWorldPosition.X, handWorldPosition.Y, handWorldPosition.Z)

		grabRemote:FireServer("Update", grabbedObject, handWorldPosition, Vector3.new(rotationX, rotationY, rotationZ))
	end
end)

1 Like

You can get the position of the CFrame using

cFrame.Position

You can also cast a Vector3 to a CFrame

CFrame.new(vector3)

The full error message will tell you what line of code is causing the error, try adding the above to whatever Vector3 you are passing through

2 Likes

Appreciate the response, I’ll be testing that tomorrow. I’m tired so I seem to have slipped by that, but I’ll grant you the solution as that is without a doubt correct.

Appreciate it!

1 Like

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