Right now im confused on why one script works while the other doesnt
heres a video
heres the script (btw both are same just using a different remote function)
local tool = script.Parent
local cooldown = false
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local animation = script:WaitForChild("Up")
local animater = humanoid:LoadAnimation(animation)
local mouse = player:GetMouse()
local toolequipped = false
local trackingPart = Instance.new("Part")
trackingPart.Size = Vector3.new(1.5, 1.5, 1.5)
trackingPart.Color = Color3.new(0.215686, 1, 0)
trackingPart.Transparency = 0.5
trackingPart.Shape = Enum.PartType.Ball
trackingPart.Material = Enum.Material.Neon
trackingPart.Anchored = true
trackingPart.CanCollide = false
trackingPart.Parent = workspace
mouse.TargetFilter = trackingPart
tool.Equipped:Connect(function()
toolequipped = true
while toolequipped do
local hit = mouse.Hit
if hit then
local characterPosition = character.PrimaryPart.Position
local hitPosition = hit.Position
local distance = (hitPosition - characterPosition).magnitude
local minDistance = 5
if distance > minDistance then
trackingPart.Position = hitPosition + Vector3.new(0, trackingPart.Size.Y / 2, 0)
else
local direction = (hitPosition - characterPosition).unit
trackingPart.Position = characterPosition + direction * minDistance + Vector3.new(0, trackingPart.Size.Y / 2, 0)
end
end
wait(0.01)
end
end)
tool.Unequipped:Connect(function()
toolequipped = false
trackingPart.Position = Vector3.new(0, -1000, 0)
end)
tool.Activated:Connect(function()
if not cooldown and toolequipped then
local pos = trackingPart.CFrame
cooldown = true
animater:Play()
game.ReplicatedStorage.RemoteTools.Blaster.Sans.BlastZone:FireServer(pos)
trackingPart.Color = Color3.new(1, 0, 0.0156863)
wait(9)
cooldown = false
trackingPart.Color = Color3.new(0.215686, 1, 0)
end
end)
I would recommend using UserInputService rather than Mouse for new work, as it allows for more precise control for filtering.
You can get the mouse’s location on the screen with :GetMouseLocation() and raycast from the camera in order to find where it is in 3D space (with support for different filters at the same time).
So this happens when your code runs:
Tool 1 localscript creates their part and sets mouse.Target filter to that part.
Tool 2 localscript is loaded and creates their part and sets mouse.Target filter to that part.
The target filter now equals to tool2’s part. When you use tool 2, it works fine. But using tool 1 it now breaks, because the target filter was overwritten.
So you can set the target filter of a part in tool.equipped and then it will work. But I suggest you create/destroy the tracking part in tool.equipped/unequipped instead to avoid memory leaks.
minimal solution:
--move this line in both tools' scripts
mouse.TargetFilter = trackingPart
--inside of tool.equipped:
tool.Equipped:Connect(function()
mouse.TargetFilter = trackingPart
--rest of code...
--bonus:
--toolequipped = true--remove this line
--why? Because Activated can only fire if a tool is equipped
-- you don't need to check again.
--use runservice to handle positioning instead of a while loop, it is cleaner
end)
Bonus:
It would be better to handle the lifetime of your part inside of equip/unequip though like so:
tool.Equipped:Connect(function()
trackingPart = instance.new("Part")
--customize
mouse.TargetFilter = trackingPart
--other code
end)
tool.Unequipped:Connect(function()
if trackingPart then
trackingPart:Destroy()
trackingPart = nil
end
end)
so i did something kinda simillar you can correct me cus im kinda new to raycast but
it works, just that another part of the script which is suppost to keep making the part follow the mouse is making it float to my screen
tool.Equipped:Connect(function()
toolequipped = true
while toolequipped do
local hit = mouse.Hit
if hit then
local characterPosition = character.PrimaryPart.Position
local hitPosition = hit.Position
local distance = (hitPosition - characterPosition).magnitude
local minDistance = 5
if distance > minDistance then
trackingPart.Position = hitPosition + Vector3.new(0, trackingPart.Size.Y / 2, 0)
else
local direction = (hitPosition - characterPosition).unit
trackingPart.Position = characterPosition + direction * minDistance + Vector3.new(0, trackingPart.Size.Y / 2, 0)
end
end
wait(0.01)
end
end)
--services
local rs = game:GetService "RunService"
--plr related vars
local plr = game.Players.LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()
local mouse = plr:GetMouse()
--other
local tool = script.Parent
local hum = char:FindFirstChildOfClass "Humanoid"
local track = hum:LoadAnimation(script:WaitForChild "Up")
--nil values
local part = nil
local connection = nil
--define constants up here:
local MIN_DISTANCE = 5
--text
tool.Equipped:Connect(function()
part = instance.new "Part"
part.Shape = Enum.PartType.Ball
part.Transparency = 0.5
part.CanCollide = false
part.Anchored = true
part.Size = Vector3.new(1.5, 1.5, 1.5)
part.Material = Enum.Material.Neon
part.Color = Color3.fromRGB(55, 255, 0)
part.Parent = workspace
mouse.TargetFilter = part
connection = rs.Heartbeat:Connect(function()
local hit = mouse.Hit.Position
local charPos = char.PrimaryPart.Position
local distance = (hit - charPos).Magnitude --player:DistanceFromCharacter(hit)
if distance > MIN_DISTANCE then
part.Position = hit + Vector3.new(0, part.Size.Y / 2, 0)
else
local direction = (hit - charPos).Unit
part.Position = charPos + direction * MIN_DISTANCE + Vector3.new(0, part.Size.Y, 0)
end
end)
end)
--clean up resources here
tool.Unequipped:Connect(function()
if part then
part:Destroy()
part = nil
end
if connection then
connection:Disconnect()
connection = nil
end
end)
To get the result of a raycast you need to use workspace:Raycast().
It also seems like you’re still using mouse.Hit in your while loop.
We need to perform the raycast every time we want to get the mouse position.
I would recommend implementing something that looks like this:
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local MAX_MOUSE_DISTANCE = 1000
local function getWorldMousePosition()
local mouseLocation = UserInputService:GetMouseLocation()
local screenToWorldRay = workspace.CurrentCamera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local directionVector = screenToWorldRay.Direction * MAX_MOUSE_DISTANCE
-- THIS IS WHAT FILTERS THE RAYCAST
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {} -- Parts to ignore go in this table
-- There are some other raycast filter options as well
local raycastResult = workspace:Raycast(screenToWorldRay.Origin, directionVector, raycastParams)
return raycastResult
end
tool.Equipped:Connect(function()
toolequipped = true
while toolequipped do
local mouseRaycast = getWorldMousePosition()
if mouseRaycast then
local characterPosition = character.PrimaryPart.Position
local hitPosition = mouseRaycast.Position
local distance = (hitPosition - characterPosition).magnitude
local minDistance = 5
if distance > minDistance then
trackingPart.Position = hitPosition + Vector3.new(0, trackingPart.Size.Y / 2, 0)
else
local direction = (hitPosition - characterPosition).unit
trackingPart.Position = characterPosition + direction * minDistance + Vector3.new(0, trackingPart.Size.Y / 2, 0)
end
end
-- This line replaces wait(0.01), as using wait() can have longer delays than intended
-- If you need to wait more than a single frame, use task.wait() instead
RunService.Heartbeat:Wait()
end
end)
You should be able to adapt this code into your current script; hopefully that made sense!
(Raycasting will replace the need for using mouse.TargetFilter as it has its own filtering options)