I have this code, it works fine. However I do not like that a function is being called every frame, but I don’t know another way to accomplish what I want, this is a local script for a single player shooter game and server does perform checks as to avoid exploiters.
Is having it call that function every frame a bad idea, will it hurt performance? In testing it doesn’t, but yet again I have a decent system so it might actually be bad and i just would not know
local highlite = game.ReplicatedStorage:WaitForChild('Highlight')
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local root = char:WaitForChild("HumanoidRootPart")
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local takeables = game.Workspace:WaitForChild("Takeable")
local takeItemEvent = game.ReplicatedStorage:WaitForChild("ImportantRemotes"):WaitForChild('TakeItem')
local pickupRange = 20
local LastHeighliteModel = nil
local LastHeighlite = nil
local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Exclude
function lineOfSight(target)
local rayDirection = target.Position - root.Position
local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {root.Parent}
local RayResult = workspace:Raycast(root.Position, rayDirection, rayParams)
if RayResult and RayResult.Instance then
if RayResult.Instance:IsDescendantOf(target.Parent) then
return true
else
return false
end
end
end
function getNearby()
local WithinDistance = {}
for i, v in pairs(takeables:GetDescendants()) do
if v:IsA('Model') and v.PrimaryPart then
local distance = (v.PrimaryPart.Position - root.Position).Magnitude
if distance <= pickupRange and lineOfSight(v.PrimaryPart) then
WithinDistance[v] = distance
end
end
end
if next(WithinDistance) ~= nil then
local smallestDistance = 10000000000
local closestModel = nil
for i, v in pairs(WithinDistance) do
if v < smallestDistance then
smallestDistance = v
closestModel = i
end
end
return closestModel
else
return nil
end
end
UIS.InputBegan:Connect(function(input, gp)
if gp then return end
if input.KeyCode ~= Enum.KeyCode.T then return end
local itemToTake = getNearby()
if itemToTake ~= nil then
takeItemEvent:FireServer(itemToTake)
end
end)
RS.RenderStepped:Connect(function()
local nearby = getNearby()
if nearby ~= nil and LastHeighliteModel ~= nearby then
if LastHeighlite then
LastHeighlite:Destroy()
end
local newHiglite = highlite:Clone()
newHiglite.Parent = nearby
LastHeighliteModel = nearby
LastHeighlite = newHiglite
else
if nearby == nil and LastHeighlite ~= nil then
LastHeighlite:Destroy()
LastHeighliteModel = nil
end
end
end)