Getting a model to follow onto mouse while the button is being held down

Basically, when a player clicks on a part, it’s suppose to create a model, that follows the mouse. Atm, when you let go on the mouse button it deletes the item (in the future I’m gonna make it check if the mouse is hovering over the pizza part and then weld it to said pizza) but I’m having trouble just getting the item to stay following the mouse. Getting this error
[Unable to cast Vector2 to CoordinateFrame]
on this line

Clone:SetPrimaryPartCFrame(CursorPosition)

I know CursorPosition is a Vector2, but I don’t know how to convert it to a CFrame

UserInputService.InputBegan:Connect(function(input, GPE)
	if GPE then return end
	
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		local CursorPosition = UserInputService:GetMouseLocation()
		
		local Raycast = workspace.CurrentCamera:ScreenPointToRay(CursorPosition.x, CursorPosition.y, 1)
		local NewRay = Ray.new(Raycast.Origin, Raycast.Direction * 999)
		local Part = workspace:FindPartOnRayWithIgnoreList(NewRay, {Conveyor})
		if not Part then return end
		
		local Model = PizzaChef:FindFirstChild(Part.Name)
		if not Model then return end
			
		local Clone = Model:Clone()
		Clone.Parent = PizzaHolder
		
		Clone:SetPrimaryPartCFrame(CursorPosition)
		
		CurrentTopping = Clone
	end
end)

UserInputService.InputEnded:Connect(function(input, GPE)
	if GPE then return end
	
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if not CurrentTopping then return end
		
		CurrentTopping:Destroy()
		CurrentTopping = nil
	end
end)

I want to avoid using ‘Mouse’ as the dev hub states I should use UserInputService :man_shrugging:

Instead of the position of the mouse in the 2D space, there is a neat property of the mouse which is mouse.Hit.
This property is the cframe of the mouse in the 3D world.
Which is perfect for what you’re doing, so instead of CursorPosition

Clone:SetPrimaryPartCFrame(mouse.Hit)

Also I don’t see a problem with using the mouse events like mouse.Move and mouse.Button1Down instead of the UserInputService, I honestly never had an issue with them being innacurate but maybe I’m wrong.

I’m not using mouse tho. I’m purely using InputBegan and InputEnded

Well, there is really no other way to get the position of the mouse in 3D, there might be a mathy way that I’m not aware of but I doubt it. Just use the mouse to get the mouse.Hit and nothing else, I don’t see that to be a problem

I am currently writing an article that involves a lot of stuff with the mouse and its property, maybe it will help you when I’m done

Well how can I get a model to just lock onto the mouse then??

I think this part

local Raycast = workspace.CurrentCamera:ScreenPointToRay(CursorPosition.x, CursorPosition.y, 1)
local NewRay = Ray.new(Raycast.Origin, Raycast.Direction * 999)
local Part = workspace:FindPartOnRayWithIgnoreList(NewRay, {Conveyor})

actually has an answer, technically here we have a ray that starts from the 3D conversion of the 2D position you gave in the direction of the camera, we can maybe use that I’m not totally sure.
Try

local Raycast = workspace.CurrentCamera:ScreenPointToRay(CursorPosition.x, CursorPosition.y, 1)
local NewRay = Ray.new(Raycast.Origin, Raycast.Direction * 999)
local Part, Position = workspace:FindPartOnRayWithIgnoreList(NewRay, {Conveyor})
print(Position) --maybe position is actually the position of the mouse, although since it has the direction of the camera it might not work

If this doesn’t work, honestly you have to use the mouse, there is no way to skip it. I don’t get why you don’t wanna use it.

1 Like

You can still leverage user inputservice to indicate when the mousebutton1 goes down and when it goes up. Bind these actions to functions that use the data from mouse.Hit or mouse.Target to position your model.

How can I get it to stay on the mouse tho? It just stays in one spot

It doesn’t stay on the mouse because it’s in the direction of the camera, so you really can’t do it

Decided to just use Mouse.Move. Getting a problem where the item only shows up on specific parts tho

Mouse.Move:Connect(function()
	if CurrentTopping then		
		for i, v in pairs(CurrentTopping:GetChildren()) do
			v.CanCollide = false
		end
			
		local UnitRay = workspace.CurrentCamera:ScreenPointToRay(Mouse.X, Mouse.Y, 1)
		local NewRay = Ray.new(UnitRay.Origin, UnitRay.Direction * 1000)
		local Hit, Pos = workspace:FindPartOnRayWithIgnoreList(NewRay, {CurrentTopping})
		
		local NewPos = Vector3.new(Pos.X, Pos.Y, Pos.Z)
		
		CurrentTopping:SetPrimaryPartCFrame(CFrame.new(NewPos) * CFrame.Angles(0, 0, math.rad(90))) -- Have to use the CFrame.Angles, as the model for some reason is rotated weirdly
	end
end)

robloxapp-20190910-2055491

:FindPartOnRayWithIgnoreList returns the tuple: (BasePart or Terrain that was hit, Vector3 point of intersection, Vector3 surface normal, Material of BasePart or Terrain hit) see here.

Edit: Looks like starmaq has already pointed that out oops.

I know that, but that doesn’t solve my current problem

1 Like

You can move the part in renderstepped instead of Mouse.Move

jk lol

It looks like you’re setting the topping’s CFrame to the position of the object the mouse is hovering over. This means that the topping could be hiding in the middle of the conveyor belt.

You need to instead position the topping relative to the mouse, using coordinates from mouse.Hit

1 Like

oh yeah maybe mouse.hit will work?

That’s actually not it, he’s using the position of intersection of the ray, the second return value of :FindPartOnRayWithIgnoreList. I’m guessing his PrimaryPart is some invisible part that isn’t really aligned with the other visible parts so I think pushing it a little up may be a solution.

1 Like