I would suggest that mouse.target isn’t the most flexible to use with this, so as an extra note, I’d encourage you to look at using UserInputService, Mouse Movement Inputs and ScreenToPointRay, as it’ll grant you alot more flexibility when it comes to detecting objects you want to detect. (a flaw with mouse.target especially is you can’t ignore invisible parts very easily/you can but a struggle to organise your workspace around it).
Either way, if you group parts into a model, you can use a method to create an invisible box that covers the bounds of the model. This method is called :GetBoundingBox()
, and you can run a script on game startup, that automatically creates these boxes for you. The bit where it gets difficult (and why I suggest using UIS) is detecting these boxes. Now, as you said, mouse.target will work just fine, but you may experience issues where your mouse.target
isn’t actually the hitbox, but parts in the physical model and/or invisible parts the player can’t see, which unless you make a check for, can be quite annoying for the end user.
As such, using ScreenPointToRay will allow you to ignore/whitelist certain parts through the use of FindPartOnRayWithWhitelist
or FindPartOnRayWithIgnoreList
. This means potentially if you wanted, you could get all of the bounding boxes into a list, and use it as a whitelist so you only cast a ray to those objects. I made a small code example as a proof of concept.
local UIS = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")
local Target = nil
local MagicModel = Workspace.MagicModel -- whatever your model is
local Camera = Workspace.CurrentCamera
local Selection = Instance.new("SelectionBox")
Selection.Parent = workspace
-- This section is for creating bounding boxes
local block1 = Instance.new("Part")
local cf,size = MagicModel:GetBoundingBox()
block1.CFrame= cf
block1.Size = size
block1.Transparency = 1
block1.Anchored = true
block1.Parent = workspace
-- This section is for detecting them
local whiteList = {block1} -- throw any instances you want to ignore in here.
UIS.InputChanged:Connect(function(input,processed)
if not processed and input.UserInputType == Enum.UserInputType.MouseMovement then -- if you aren't clicking on any Roblox things or UI
local position = input.Position
local unitRay = Camera:ScreenPointToRay(position.X,position.Y)
local finalRay = Ray.new(unitRay.Origin,unitRay.Direction*400) -- lets say 400 is our fall off range
Target = Workspace:FindPartOnRayWithWhitelist(finalRay,whiteList,false,false)
if Target then
Selection.Adornee = block1
else
Selection.Adornee =nil
end
end
end)
The API for the method is pretty straight forward and provides you with all the information (box size, box CFrame) to make a bounding box, all you have to do then is detect those boxes. While the UIS method isn’t necessarily related to your question, I think it’ll be useful stating it now, as I’ve run into my own issues in the past with mouse.hit/mouse.target!
Hope I helped.