How efficient is this to run every frame?

I’m trying to make an interaction system and I have some code for checking if the player is near an interactable object I’m using an octree module which is pretty cool and seems to work well, however, I’m not sure if the way I’m using it is the most effective in-fact I’m not entirely sure anything I wrote here is the most effective haha.

This is my main client module that sets up a few things (for this post though I only included playerInteraction)

local function update()
	playerInteraction.update()
end

function Client.initialize()
	playerInteraction = PlayerInteraction.new(Client)

	RunService.RenderStepped:Connect(update)
end

And then this is the playerInteraction.update() function

function self.update()
	local root = Client.getPlayerCharacter().getRoot()

	if not root then
		return
	end

	local results = octree:RadiusSearch(root.Position, radius) -- radius is 10

	if results == {} then
		return
	end

	local closest = results[1]

	if closest == nil then
		-- print("Nothing nearby")
		removeCurrentHighlight()
		return
	end

	if currentClosest == closest then
		-- print("Closest object is already current closest object")
		return
	end

	removeCurrentHighlight()

	currentClosest = closest

	local highlight = Instance.new("Highlight")
	highlight.DepthMode = Enum.HighlightDepthMode.Occluded
	highlight.FillTransparency = 1
	highlight.Parent = currentClosest
end

What is this ‘octree’ module? Never heard of it.

octree (after googling it) is designed to be fast, its a lot better than stuff like region 3 queries, but idk if it raycasts to the actual point to refrain from picking things up behind walls.

computers are very fast, that shouldn’t be a big issue for them, the prints are the only things that would really slow it down

if you really want to optimize it further though, try making the highlight at the start of the script and simply change it’s parent instead of instancing another one every time

1 Like

function PlayerInteraction.new(client)
local self = setmetatable({
client = client
}, PlayerInteraction)

self.canInteract = false
self.canInteractDistance = 3

return self
end

function PlayerInteraction:update()
local player = self.client.Player
local playerCamera = player.Camera

if playerCamera then
local currentMouseHit = playerCamera:GetMouseRay()
local currentMouseHitPart = playerCamera:GetMouseHit()
local currentMouseHitPosition = currentMouseHit.Origin + (currentMouseHit.Direction * self.canInteractDistance)
local currentPosition = player.Character.PrimaryPart.Position

if currentMouseHitPart then
local currentMouseHitPartParent = currentMouseHitPart.Parent
local currentMouseHitPartParentHumanoid = currentMouseHitPartParent:FindFirstChildOfClass(“Humanoid”)
local currentMouseHitPartParentInteractable = currentMouseHitPartParent:FindFirstChildOfClass(“Interactable”)

if currentMouseHitPartParentHumanoid and currentMouseHitPartParentHumanoid.Parent == player.Character then
return
end

if currentMouseHitPartParentInteractable then
local currentMouseHitPartParentInteractableName = currentMouseHitPartParentInteractable.Name
local currentMouseHitPartParentInteractablePart = currentMouseHitPartParentInteractable.Part

if currentMouseHitPartParentInteractablePart then
 local currentMouseHitPartParentInteractablePartPosition = currentMouseHitPartParentInteractablePart.Position

 if (currentMouseHitPartParentInteractablePartPosition - currentPosition).magnitude < self.canInteractDistance then
  self.canInteract = true
  self.canInteractObject = currentMouseHitPartParentInteractable

  return
 end
end

end
end

self.canInteract = false
self.canInteractObject = nil
else
self.canInteract = false
self.canInteractObject = nil
end
end

return PlayerInteraction

I haven’t added the Interaction part yet but I’m just trying to see if this is a good way of going about it and if there are any ways it could be more efficient.
Thanks!

I think you can optimize the code that checks if the player is near an interactable object.
This is what i would do:
local function update()
playerInteraction.update()
end

function Client.initialize()
playerInteraction = PlayerInteraction.new(Client)
RunService.RenderStepped:Connect(update)
end

function PlayerInteraction.new(client)
local self = setmetatable({
client = client
}, PlayerInteraction)
self.canInteractDistance = 3
return self
end

function PlayerInteraction:update()
local mouseHit = self.client.Player.Camera:GetMouseRay()
local mouseHitPart = self.client.Player.Camera:GetMouseHit()
local mouseHitPartParent = mouseHitPart and mouseHitPart.Parent or nil
local mouseHitPartParentHumanoid = mouseHitPartParent and mouseHitPartParent:FindFirstChildOfClass(“Humanoid”) or nil
local mouseHitPartParentInteractable = mouseHitPartParent and mouseHitPartParent:FindFirstChildOfClass(“Interactable”) or nil
self.canInteract = false
self.canInteractObject = nil

if nearestInteractableObject and (nearestInteractableObject.Part.Position - self.client.Player.Character.PrimaryPart.Position).magnitude < self.canInteractDistance then
self.canInteract = true
self.canInteractObject = nearestInteractableObject
end
end

return PlayerInteraction