if mouse.Target.Name == 'Hitbox' then
mouse.TargetFilter = mouse.Target
end
if mouse.Target.Name == 'Spawn' then
mouse.TargetFilter = mouse.Target
end
Problem being that if one is set, the other becomes unset, and causes further problems. So I need basically both of these items to have their TargetFilterer
How would I go about having to change what I got then, becausae the system I have currently works like a charm, and I don’t really wanna have to change it all now
if mouse.Target.Name == 'Hitbox' then
mouse.TargetFilter = mouse.Target
end
if mouse.Target.Name == 'Spawn' then
mouse.TargetFilter = mouse.Target
end
if mouse.Target.Name == 'Base' or mouse.Target.Name == 'PlaceArea' then
playersPlot.PrimaryPart = mouse.Target
end
local cframe = placement(
playersPlot.PrimaryPart,
itemClone,
mouse.Hit.p,
var.Rotation
)
itemClone:SetPrimaryPartCFrame(cframe)
For starters, the mouse has a UnitRay property, which returns a Ray that’s oriented at where the mouse is on the screen.
Since this ray is only one stud long, you’ll need to make a new ray with the length that you want, and then do your raycasts using that ray.
local ray = Mouse.UnitRay
ray = Ray.new(ray.Origin, ray.Direction)
-- Do your raycasts here with Spawn and Hitbox in the ignore list,
-- or cast the ray again until you hit either nothing or something that isn't named Hitbox/Spawn
You’ll need to stop using the mouse’s Hit property and use whatever position that the raycast returns instead.
There’s also probably an if mouse.Target == nil check above that code that you didn’t include. You’ll need to perform your raycast before that and check that the raycast didn’t hit nothing instead.
Ok sweet. Not entirely sure how to get the ignore and all that. Looking at the wiki with this
local ray = Ray.new(
Weapon.Handle.CFrame.p, -- origin
(mouse.Hit.p - Weapon.Handle.CFrame.p).unit * 500 -- direction
)
local ignore = game.Players.LocalPlayer.Character
local hit, position, normal = Workspace:FindPartOnRay(ray, ignore)
It only has 1 ignore variable. How could I go about it with the 2 then?
And then removing mouse.Hit and mouse.Target, would they just be changed to ray?
if ray then
-- etc..
local cframe = placement(
playersPlot.PrimaryPart,
itemClone,
ray,
var.Rotation
)
itemClone:SetPrimaryPartCFrame(cframe)
end
And also, since I’m ignoring items with names of ‘Hitbox’ and ‘Spawn’ is there anyway to ignore names? As theres millions of hitboxes in the game, I can’t reference all of them
There’s also FindPartOnRayWithIgnoreList, which takes a list of things to ignore. Shove your player’s character + all your spawns and anything you want to ignore in here.
Alternatively, there’s FindPartOnRayWithWhitelist, which takes a list of things that you want to hit ONLY, and everything that isn’t in that list is ignored.
No, you’ll need to cast a ray. In the code snippet you saw from the wiki hit will be your mouse.Target and position will be Mouse.Hit.p.
local ray = mouse.UnitRay
ray = Ray.new(ray.Origin, ray.Direction)
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
if hit then
local cframe = placement(
playersPlot.PrimaryPart,
itemClone,
position,
var.Rotation
)
itemClone:SetPrimaryPartCFrame(cframe)
end
Problem arises with how to ignore said items. The game can include any number of hitboxes at once. That’s why I was doing mouse.Target.Name, so it was ignoring any parts named Hitbox and not so much the actual object itself.
I can’t actually ignore all the parts with hitbox in them, as if a player adds more items into their place, then there’s more hitboxes to that list
I also have mouse.Target, etc. used elsewhere in my code
local renderStepped
renderStepped = runService.RenderStepped:Connect(function()
local ray = mouse.UnitRay
ray = Ray.new(ray.Origin, ray.Direction)
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)
if hit then
if mouse.Target:IsDescendantOf(playersPlot) then
if furnitureData[itemClone.Name].Base == 'Floor' or furnitureData[itemClone.Name].Base == 'Table' then
if mouse.Target.Name == 'Base' or mouse.Target.Name == 'PlaceArea' then
playersPlot.PrimaryPart = mouse.Target
end
local cframe = placement(
playersPlot.PrimaryPart,
itemClone,
position,
var.Rotation
)
itemClone:SetPrimaryPartCFrame(cframe)
else
if mouse.Target.Parent:IsDescendantOf(playersPlot.House) then
itemClone:SetPrimaryPartCFrame((getCFrame(mouse, itemClone.PrimaryPart.Size.Z))*CFrame.Angles(0, 0, var.Rotation))
end
end
for _, v in pairs(getTouchingParts(itemClone.Hitbox)) do
if not v:IsDescendantOf(itemClone) and v.Name ~= 'Spawn' and not v:IsDescendantOf(players:FindFirstChild(playersPlot.Name).Character) then
itemClone.Hitbox.Transparency = 0.5
break
end
itemClone.Hitbox.Transparency = 1
end
end
end
end)
local ray = mouse.UnitRay
ray = Ray.new(ray.Origin, ray.Direction)
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray, {playersPlot.Spawn})
print(1)
if hit then
print(2)
end
Just been playing around with it, however, it isn’t recognizing the hit, so it’s only printing 1 and not 2.
Reading some of the earlier replies, I think I have a better understanding of what your problem is.
Since new hit boxes can appear whenever a new model is placed, you can try to get all the models named hitbox in the area you’re allowed to plot at, and add them to a table along with their current parent. Then set all their parents to the same model and change the target filter to that model until the model you’re placing gets placed. Then just parent all the items in that table back where they were originally.
I don’t see why you wouldn’t be able to set the spawn and hitbox models to the same parent.
I have been doing stuff like this for awhile. I put a folder in the workspace called “Ignore” and set the targetfilter to that folder. (The folder can be inside other models.) Now, when you want something to be ignored just stick it into the folder.
Idk what your system is but I would suggest going to this because it could make things easier in the future if you ever want to have even more target filters.
Now when somebody clicks something to place, stick the placement model in the folder with the hitbox. To check collision use Region3 and do FindPartsInRegion3 so that if anything is inside the hitbox then don’t let the player place. Then when the player actually places it stick the real model into their base or whatever it is.
I feel like this should be a feature to be able to make a table of Instances instead of using a folder, it would be very convenient to have something like Mouse.TargetFilterList
local ray = mouse.UnitRay
ray = Ray.new(ray.Origin, ray.Direction)
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray, {playersPlot.Spawn})
print(1)
if hit then
print(2)
end
Because mouse.UnitRay is, well, a unit ray, you have to multiply its direction by how far you want the ray to reach, otherwise, it will only look for parts in your desired direction for one stud. I would multiply by 500 or so just to be safe:
local ray = mouse.UnitRay
ray = Ray.new(ray.Origin, ray.Direction*500)
I would also use a pre-assigned ignore list and a repeat until loop to repeat raycasting until either the hit does not exist or you hit an object whose name is either “Spawn” or “Base”:
local hit, position, normal
local IgnoreList = {playersPlot.Spawn}
repeat
hit, position, normal = workspace:FindPartOnRayWithIgnoreList(ray, IgnoreList)
table.insert(IgnoreList, hit)
until not hit or hit.Name == "Spawn" or hit.Name == "Base"
print(1)
if hit then
print(2)
end
until conditional erroring
The until conitional at the end might error if OR gates continue evaluating after their ultimate condition is true, unlike AND gates. If this is the case, use this:
until not (hit and hit.Name ~= "Spawn" and hit.Name ~= "Base")
tysm ive been looking for something like this for a bit
edit: for anyone looking at this, u can also do workspace:FindPartOnRayWithWhitelist(ray,whiteList)
the whitelist can be workspace:GetChildren() or descendants