Part going towards the camera

Hey i already reported this on the devforum but im posting this again cuz the old script didnt work excactly right for me so ima making a new one

I have two scripts in my Roblox game. One script fires a RemoteEvent, and the other controls a part that is cloned from ReplicatedStorage and made to follow the player’s mouse. The script works, but there’s a glitch.

In the video below, you can see that the part moves towards the camera when I stop moving my mouse. However, when I move the mouse again, the part returns to its correct position.

Can anyone help me fix this? I want the part to continuously follow the mouse, without moving toward the camera when the mouse stops moving.

Server Script

local tool = script.Parent
local tweenService = game:GetService("TweenService")
local remoteEvent = tool:WaitForChild("TeleportEvent")
local replicatedStorage = game:GetService("ReplicatedStorage")

local part = nil
local lastMousePosition = nil
local partTemplate = replicatedStorage:WaitForChild("Part")

local function onTeleportRequest(player, mousePosition)
	if player.Backpack:FindFirstChild(tool.Name) or player.Character:FindFirstChild(tool.Name) then
		if not part then
			part = partTemplate:Clone()
			part.Position = player.Character.HumanoidRootPart.Position
			part.Anchored = true
			part.CanCollide = false
			part.Parent = workspace
		end

		if not lastMousePosition or (mousePosition - lastMousePosition).Magnitude > 0.1 then
			local goal = {Position = mousePosition}
			local tweenInfo = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
			local tween = tweenService:Create(part, tweenInfo, goal)
			tween:Play()
			lastMousePosition = mousePosition
		else
			local offset = (mousePosition - part.Position).Unit * 0.1
			local newPos = part.Position + offset
			local goal = {Position = newPos}
			local tweenInfo = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
			local tween = tweenService:Create(part, tweenInfo, goal)
			tween:Play()
		end
	else
		-- Destroy the part if the player is no longer holding the tool or it is not equipped
		if part then
			part:Destroy()
			part = nil
		end
	end
end

remoteEvent.OnServerEvent:Connect(onTeleportRequest)

Localscript

local player = game.Players.LocalPlayer
local userInputService = game:GetService("UserInputService")
local tool = script.Parent
local remoteEvent = tool:WaitForChild("TeleportEvent")

local isHoldingT = false

local function onKeyPress(input, gameProcessedEvent)
	if input.KeyCode == Enum.KeyCode.T and not gameProcessedEvent then
		isHoldingT = true
		while isHoldingT do
			local mousePos = player:GetMouse().Hit.p
			remoteEvent:FireServer(mousePos)
			wait(0.1)
		end
	end
end

local function onKeyRelease(input)
	if input.KeyCode == Enum.KeyCode.T then
		isHoldingT = false
	end
end

userInputService.InputBegan:Connect(onKeyPress)
userInputService.InputEnded:Connect(onKeyRelease)

if somone needs file to the game i can give it to you

2 Likes

the mouse position currently isn’t ignore the part. You should make a function that check a mouse position using raycast and ignore the part while you are holding like this

local UserInputService = game:GetService('UserInputService')
local Camera = workspace.CurrentCamera
local MaxDistance = 1000 -- the max distance

local partHolding -- the holding part

local GetMousePosition = function()
	local Location = UserInputService:GetMouseLocation()
	local Raycast = Camera:ViewportPointToRay(Location.X, Location.Y)
	
	local Params = RaycastParams.new()
	Params.FilterDescendantsInstances = {partHolding}
	
	local Result = workspace:Raycast(Raycast.Origin, Raycast.Direction*MaxDistance, Params)
	return Result and Result.Position
end

GetMousePosition() -- it can returns nil, should do if getposition then ...

Or you can just do Mouse.TargetFilter = the part

local player = game.Players.LocalPlayer
local userInputService = game:GetService("UserInputService")
local tool = script.Parent
local remoteEvent = tool:WaitForChild("TeleportEvent")

local isHoldingT = false
local partHolding = nil


local function GetMousePosition()
	local camera = workspace.CurrentCamera
	local location = userInputService:GetMouseLocation()
	local raycast = camera:ViewportPointToRay(location.X, location.Y)

	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {partHolding}
	params.FilterType = Enum.RaycastFilterType.Exclude 

	local result = workspace:Raycast(raycast.Origin, raycast.Direction * 1000, params)
	return result and result.Position or nil
end

-- Function to handle key press event
local function onKeyPress(input, gameProcessedEvent)
	if input.KeyCode == Enum.KeyCode.T and not gameProcessedEvent then
		isHoldingT = true
		while isHoldingT do
			local mousePos = GetMousePosition()
			if mousePos then
				remoteEvent:FireServer(mousePos)
			end
			wait(0.1) 
		end
	end
end

-- Function to handle key release event
local function onKeyRelease(input)
	if input.KeyCode == Enum.KeyCode.T then
		isHoldingT = false
	end
end

-- Listen for key press and release
userInputService.InputBegan:Connect(onKeyPress)
userInputService.InputEnded:Connect(onKeyRelease)

–hey thamks for responding here i modified the script and im not sure what im supposed to do can you pls explain it a bit better

It’s better to make the ‘preview’ object in the client rather than the server for the smoothest experience like most game do.

-- Client --
local userInputService = game:GetService("UserInputService")
local replicatedStorage = game:GetService("ReplicatedStorage")

local player = game.Players.LocalPlayer

local Character = player.Character or player.CharacterAdded:Wait()

local Tool = script.Parent

local CurrentTemplate = replicatedStorage:WaitForChild("Part")
local Object

local Place = Tool:WaitForChild('Place')

local function GetMousePosition()
	local camera = workspace.CurrentCamera
	local location = userInputService:GetMouseLocation()
	local raycast = camera:ViewportPointToRay(location.X, location.Y)

	local params = RaycastParams.new()
	params.FilterDescendantsInstances = {Object}
	params.FilterType = Enum.RaycastFilterType.Exclude 

	local result = workspace:Raycast(raycast.Origin, raycast.Direction * 1000, params)
	return result and result.Position or nil
end

local IsHolding = false

local onKeyPress = function(input, Processed)
	if input.KeyCode == Enum.KeyCode.T and not Processed and Object then
		IsHolding = true
		while Object and IsHolding do
			local mousePos = GetMousePosition()
			if mousePos then
				Object.Position = mousePos
			end
			task.wait()
		end
	end
end

local function onKeyRelease(input)
	if input.KeyCode == Enum.KeyCode.T then
		IsHolding = false
	end
end

local Equipped = function()
	Object = CurrentTemplate:Clone()
	Object.Position = Character.HumanoidRootPart.Position
	Object.Anchored = true
	Object.CanCollide = false
	Object.Parent = workspace
end

local Unequipped = function()
	Object:Destroy()
	Object = nil
end

Tool.Equipped:Connect(Equipped)
Tool.Unequipped:Connect(Unequipped)
userInputService.InputBegan:Connect(onKeyPress)
userInputService.InputEnded:Connect(onKeyRelease)

I don’t know if this works, have not test it yet.

i put the script into a local script idk if i should do that but it doesnt work

where do i put the script by the way im not sure

Try setting the part’s CanQuery and CanTouch to false.

Put the script into the local script inside the tool. the server script, you can just disable it for the future work ( placing system ).

Heres a model if you want:
Tool.rbxm (3.2 KB)

I tested it, it works. Also remember to put your template inside replicatedStorage like you usually do.

1 Like

i dont know if im doing something wrong but its not working

Can you show me the video why its not working or the explorer, properties of the tool, model? Or any error from the output? Its very helpful to see what is going on

sorry for late responce but Theres nothing in the output
Screenshot 2024-12-08 110659


Im holding T in the vid

If it helps, this very simple client script, when placed inside a tool and with a part in ReplicatedStorage should work as intended. Then you can modify it with remotes etc.

local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")

local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local part = game.ReplicatedStorage.Part

local tPressed = false
local renderedPart = nil

uis.InputBegan:Connect(function(input, gpe)
	if input.KeyCode == Enum.KeyCode.T and not gpe then
		tPressed = true; print("T pressed")
		renderedPart = part:Clone()
		renderedPart.Parent = workspace
	end
end)

uis.InputEnded:Connect(function(input, gpe)
	if input.KeyCode == Enum.KeyCode.T and not gpe then
		tPressed = false; print("T released")
		
		if renderedPart then renderedPart:Destroy() end
	end
end)

rs.RenderStepped:Connect(function()
	if tPressed and renderedPart then
		renderedPart.Position = mouse.Hit.Position
	end
end)

I think you should equip the tool to make it spawns first, hold T to make it moves.
That should works!

If you want a version without a tool equipped. Here!
PutOnReplicatedFirst.rbxm (1.6 KB)
You should put it on replicatedFirst