Hey, toast! Avocado here.
There are a few ways I can think of. First, you shouldn’t wait in a RenderStepped or Heartbeat connection. Instead, return if conditions aren’t right. Waiting in this way could cause the thread count to climb incredibly quickly while the character doesn’t exist. This may crash players with a poor connection, because they are still waiting for their character.
local c = coinclone:GetPivot()
local start = tick() + math.random() * 10
game:GetService("RunService").Heartbeat:Connect(function()
if not game.Players.LocalPlayer.Character then return end
local dist = (coin:GetPivot().Position - game.Players.LocalPlayer.Character:GetPivot().Position).Magnitude
if dist > 200 then return end
local time = tick() - start -- The amount of seconds since the start time
local rotation = math.rad(time * 180) -- Rotation (180 degrees per second)
local upoffset = Vector3.new(0, math.cos(time * math.pi / 2) * 0.5 + 1) -- The hover variable
coinclone:PivotTo(c * CFrame.Angles(0, 0, rotation) + upoffset, 0) -- Set new position + orientation
end)
Then, we should optimize by making variables to reduce the amount of indexing done every frame.
local player = game.Players.LocalPlayer
local RunService = game:GetService("RunService")
local c = coinclone:GetPivot()
local origin = c.Position
local start = tick() + math.random() * 10
local halfpi = math.pi / 2
RunService.Heartbeat:Connect(function()
local char = player.Character
if not char then return end
local dist = (origin - char:GetPivot().Position).Magnitude
if dist > 200 then return end
local time = tick() - start
local rotation = math.rad(time * 180)
local upoffset = math.cos(time * halfpi) * 0.5 + 1
coinclone:PivotTo(c * CFrame.Angles(0, 0, rotation) + Vector3.yAxis * upoffset, 0)
end)
Finally, we can use octrees to massively improve the distance checks.
Octrees are a recursive chunking system. They group items up based on which chunks they are in. Searching this way only searches the nearest chunks, and then the items inside of the chunks. Big improvement! It’s easy to set up.
This video helped me learn how to use it.
Here’s a benchmark I made that compares this and checking with magnitude!
Octrees are 10-40 times faster than using Magnitude. The more objects and the further apart objects are, the more efficient these are. Even DOORS uses them!
Try implementing Octrees yourself using the tutorial!