Would it be possible to apply a circular radius to mouse.Target? In the sense that it only returns one part which is closest to inside the radius, like in my drawing here:
Two ways i know
-
Magnitude
You may be able to use magnitude to apply a bigger radius from the hit position -
RayCast
you may be able to cast a ray between a certain distance from the hit position
how would i use magnitude to apply a radius? it just calculates the distance as far as i know
Here is one example with the Player, However i think used the Wrong Mouse
PlayerMouse = game.Players.LocalPlayer:GetMouse()
char = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
function A()
local Mag = (char.PrimaryPart.Position - PlayerMouse.Hit.p).Magnitude
if Mag < 10 then
print("Ok")
end
end
while true do
game:GetService("RunService").RenderStepped:Wait()
A()
end
Its Probably better to cast a ray tho
Bro i dont think you understand what i said in the thread, i asked on how i could make a radius around mouse.target, a circular radius in which parts closest to the inside of the radius are returned. the code you wrote will only return me the distance between the mouse.hit and character
To be fair, I did say I think I used the wrong one
You can use workspace :GetPartsBoundInRadius() for this. You can then iterate through the objects for the lowest magnitude.
I didn’t check if this code works but it should convey the ideas you need to use for something like this.
local function cameracalc()
local mp = UserInputService:GetMouseLocation()
local rayresult = workspace:Raycast(Camera:ViewportPointToRay(mp.X,mp.Y).Origin, Camera:ViewportPointToRay(mp.X,mp.Y).Direction * Distance, RayCastParams) and rayresult or ""-- something here to return the max position i dont wanna do math for it
if not rayresult then
return
end
local Result = workspace:GetPartsBoundInRadius(CFrame.new(rayresult.Position), Radius)
local Closest = {Result[1], (Character.HumanoidRootPart.Position-Result[1].Position).Magnitude}
for i,v in pairs(Result) do
if (Character.HumanoidRootPart.Position-v.Position).Magnitude <= Closest[2] then
Closest = {v, (Character.HumanoidRootPart.Position-v.Position).Magnitude}
end
end
return Closest
end
This isn’t a built in feature but you can replicate it partially or fully in Lua. It will be laggy if you do it that way so I wouldn’t do it too many times in a second.
First, I’d filter out parts behind the mouse ray. Then I’d use ClosestPointOnRay and Magnitude to work out which of those parts are close enough to be affected.
I can help with it in a few hours if you want, we can see if it’s efficient enough to work in a game.
I’m very confused by what you’re asking.
What do you mean by “one part which is closest to inside the radius”? The radius is an arbitrary line segment from the center of the sphere (I assume you meant sphere, not circle) to the surface of it. Do you mean the closest part to the the center of the sphere? If that’s the case, unless the mouse is pointing at nil
, then the closet part to the center of the sphere would be Mouse.Target itself, assuming that Mouse.Target is the center of the sphere (by your drawing and natural intuition this would make sense). This is by inherent design of Mouse.Target. The closest part to the center of the sphere would have to be Mouse.Target. If the mouse is pointing at nil
(like in your drawing), then how would you know how far to go down the z-axis to get to the desired part? A part could be at 50 studs away or 300. How could you clarify which one you want? I don’t really understand what you’re trying to do here.
The only other conclusion I can come up with is that you want the second closest part when Mouse.Target is not nil. In this case, I don’t believe this is possible (see my reply below). @Kokabiella’s solution does not work because it does not account for the position and size of the part. The closest position to position magnitude is not the same as the closest physical presence of a part.
Actually, now that I think about it, if you assume what I said above is true (you want the second closest part to Mouse.Target), then you could use a resizing GetPartsBoundInRadius method to achieve what you want, although this is probably not the greatest idea for performance reasons. You could have your query start out as a radius of 0, and expand until it includes a part that isn’t the Mouse.Target part. This would be your second closest part besides Mouse.Target. Though again, this is terribly inefficient.
Ill rephrase what i said in the thread, i want to return the part which is closest to
mouse.Target
right. but mouse.Target
will only return a part if my mouse is actually on the part right, but im looking to extend the search range of mouse.Target
to a circular radius instead of 1 pixel. i wish to use this for an interaction system, in a function which runs every renderstep, but people are saying theres no way to do this efficiently enough? im not sure what other alternative i could use
Yeah sure, just lmk when you can
Ok. Let me just make sure I’m on the same page with you here:
Keep in mind these drawings are from TOP to BOTTOM view.
In the drawing below, assume Part A is what the target is. You do NOT want this part, you want the closest part to the center (within the range of your radius) of the Mouse.Target point. In other words, you would want Part C (because C is the closest to Mouse.Target).
Let me know if I’m correct about what I said above.
I’m still confused about your original drawing though. Below is your drawing from a bird’s eye view.
If Mouse.Target is nil
, then the mouse ray will infinitely travel until it cannot any longer. As you can see by the drawing, if Mouse.Target is nil
, the line will not stop at your part, because it has no reason to. It does not collide with anything because nothing is in the way of it. You would have to make the radius unreasonably big for it to even come near Part A, and that would obviously not be a good idea, because it would make the query very inaccurate (and inefficient).
Disregard my drawing, the first drawing which you made is essentially what im trying to achieve. The only reason I had my part 3D was for visual purposes so people may better understand what i mean, but this had the opposite effect.
Cool.
The system I’m thinking of would work using an expanding sphere. Starting out with a sphere of radius 0, it would increase its radius until the sphere touches a part (barring Mouse.Target). Here’s how I would approach this in pseudocode.
- Ensure Mouse.Target is not nil. It can’t be nil as we just described or the system won’t work.
- Given the Mouse.Target, also obtain Mouse.Hit (the position in 3D space where the mouse hits)
- Letting x start out as 0 and increment by small amounts until x == your maximum, desired radius, create a spherical spatial query of radius x UNTIL the spatial query detects a part. Yes, you will have to create a new query for every new radius. You should also blacklist Mouse.Target from being able to be a part of this query using the query’s overlap params.
.
The part that the sphere detects first should be the part closest to Mouse.Hit.
Keep in mind that the system I present is pretty inefficient. Perhaps @JarodOfOrbiter’s solution might be slightly more efficient. However, I don’t believe you will be able to achieve what you want without it being expensive.
I think we’re doing different things. My understanding of the problem was that the mouse ray would be able to act physically larger. Imagine in your second photo that the mouse hits because the brown circle would be a brown tube extending along your Z line. That was my interpretation of the problem.
I originally thought that’s what he meant, but that would still be nebulous as he stated he wanted the closest part to the mouse point, not the line. That’s what threw me off.
local mouse = game.Players.LocalPlayer:GetMouse()
local Radius = 5 --Your radius
local Array = {} --List all your parts here which you want to check on.
function GetClosestPartInRadius()
local Centre = Mouse.Hit.p
local MagTable = {}
for i,v in Array do
if (Centre - v.Position).Magnitude >= Radius then
MagTable[i] = {v,(Centre - v.Position).Magnitude}
end
end
local ActTable = table.sort(MagTable,function(a,b)
return MagTable[a][1] > MagTable[b][1]
end
return ActTable[1]
end
-- Do whatever u wish with it
Your solution will not work for the same reasons @Kokabiella’s solution will not work because point to center of part distance is not the same as point to closest to point on part distance.
Given the scenario in the drawing above, your code would say that Part A is closer to the middle point because the center of Part A is closer to the point than the center of Part B. While the center distance between Part A and the middle point is smaller than that of Part B and the point, the closest point on Part A to the point is a larger magnitude than the closest point on Part B to the point. We are trying to find the part that is physically closest to the point, not the part that has the closest center position.