✓ Accepted answer
Thanks to Crazyman32
for creating a Module Script
Here the ModelScript You will need to create in the same folder as your localScript
ModuleScript
local Mouse = {}
Mouse.__index = Mouse
function Mouse.new()
local player = game.Players.LocalPlayer
assert(player, "Could not get player")
local cam = game.Workspace.CurrentCamera
local Ray = Ray.new
local input = game:GetService("UserInputService")
local button1 = Enum.UserInputType.MouseButton1
local button2 = Enum.UserInputType.MouseButton2
local button3 = Enum.UserInputType.MouseButton3
local mouseMovement = Enum.UserInputType.MouseMovement
local mouseWheel = Enum.UserInputType.MouseWheel
local mouse = {}
local mousePos, mouseDelta = Vector2.new(), Vector2.new()
local clicking = {
[button1] = false;
[button2] = false;
[button3] = false;
}
local function CreateEvent(eventName)
local e = Instance.new("BindableEvent")
mouse[eventName] = e.Event
return function(...)
e:Fire(...)
end
end
local buttonDown = CreateEvent("ButtonDown")
local buttonUp = CreateEvent("ButtonUp")
local moved = CreateEvent("Moved")
local scrolled = CreateEvent("Scrolled")
function mouse:IsDown(inputType)
return (clicking[inputType] == true)
end
function mouse:GetPosition()
return mousePos, mouseDelta
end
function mouse:ProjectMouseRay(ignoreList)
local pos = self:GetPosition()
local ray = cam:ScreenPointToRay(pos.X, pos.Y, 0)
ray = Ray(ray.Origin, (ray.Unit.Direction * 999))
local hit, hitPos, normal = game.Workspace:FindPartOnRayWithIgnoreList(ray, ignoreList or {}, true, false)
local cframe = CFrame.new(hitPos, (hitPos + ray.Unit.Direction))
return cframe, hit, normal
end
local function InputBegan(inputObject, gameProcessed)
if (gameProcessed) then return end
local inputType = inputObject.UserInputType
if (inputType == button1 or inputType == button2 or inputType == button3) then
clicking[inputType] = true
buttonDown(inputType)
end
end
local function InputChanged(inputObject, gameProcessed)
local inputType = inputObject.UserInputType
if (inputType == mouseMovement) then
local newMousePos = Vector2.new(inputObject.Position.X, inputObject.Position.Y)
local delta = newMousePos - mousePos
mousePos = newMousePos
mouseDelta = Vector2.new(delta.X, delta.Y)
moved(mousePos, mouseDelta)
elseif (inputType == mouseWheel) then
local num = inputObject.Position.Z
scrolled(num < 0 and -1 or num > 0 and 1 or 0)
end
end
local function InputEnded(inputObject, gameProcessed)
local inputType = inputObject.UserInputType
if (inputType == button1 or inputType == button2 or inputType == button3) then
clicking[inputType] = false
buttonUp(inputType)
end
end
input.InputBegan:connect(InputBegan)
input.InputChanged:connect(InputChanged)
input.InputEnded:connect(InputEnded)
return setmetatable(mouse, Mouse)
end
function Mouse:__tostring()
local pos = self:GetPosition()
return ("Mouse <" .. tostring(pos) .. ">")
end
return Mouse
and here is a edited version of your localScript
local mouse = require(script.Parent:WaitForChild("ModuleScript")).new()
local modelMode = false
local player = game.Players.LocalPlayer
local selection = Instance.new("SelectionBox")
selection.Color3 = Color3.new(0,0,5)
selection.Parent = player.PlayerGui
mouse.Moved:connect(function()
local cframeHit, target, surfaceNormal = mouse:ProjectMouseRay()
if not target then
selection.Adornee = nil
elseif modelMode then
if target.Parent:IsA("Model") then
selection.Adornee = target.Parent
elseif target.Parent.Parent:IsA("Accoutrement") then
selection.Adornee = target.Parent.Parent
elseif target:IsA("BasePart") then
selection.Adornee = target
else
selection.Adornee = nil
end
else
if target:IsA("BasePart") then
selection.Adornee = target
else
selection.Adornee = nil
end
end
end)
I hope this will solve your problem :D
And no there is no other way to solve this without using ray casting
1 comment
connect() is deprecated in favour of Connect(). I'm not sure why this doesn't work, wonder if you can use print()s to discern what's being chosen when it hovers over the character.