By chunk manager, do you mean clones of the ocean that get placed around the player’s character?
I tried creating something like that:
local DEBOUNCE_TIME = 3
local CHANGE_RADIUS = 10
local debounce = 0
local partTable = {}
local updateInProgress = false
-- Standard configuration (indexes of table):
-- 1 = TopLeft
-- 2 = TopMiddle
-- 3 = TopRight
-- 4 = MiddleLeft
-- 5 = MiddleMiddle (reference)
-- 6 = MiddleRight
-- 7 = BottomLeft
-- 8 = BottomMiddle
-- 9 = BottomRight
local folder = Instance.new("Folder")
folder.Name = "SeaParts"
folder.Parent = workspace
-- Return positions around referencePosition (only for squares)
local function positionsAroundReference(refPart)
local refPos = refPart.Position
local length = refPart.Size.X
return {
[1] = refPos + Vector3.new(-length, 0, length),
[2] = refPos + Vector3.new(0, 0, length),
[3] = refPos + Vector3.new(length, 0, length),
[4] = refPos + Vector3.new(-length, 0, 0),
[5] = refPos,
[6] = refPos + Vector3.new(length, 0, 0),
[7] = refPos + Vector3.new(-length, 0, -length),
[8] = refPos + Vector3.new(0, 0, -length),
[9] = refPos + Vector3.new(length, 0, -length),
}
end
-- Create a part at the specified position
local function createPart(pos)
local part = Instance.new("Part")
part.Size = Vector3.new(25, 1, 25)
part.Anchored = true
part.CanCollide = true
part.Position = pos
part.Parent = folder
CHANGE_RADIUS = part.Size.X / 2
-- local part = workspace.Ocean.Plane:Clone()
-- part.Position = pos
-- part.Parent = workspace
return part
end
local function updatePartTable(sourcePart)
if updateInProgress then
return
end
-- Check debounce
if debounce <= 0 then
debounce = DEBOUNCE_TIME
else
return
end
print("Update")
updateInProgress = true
-- Get new positions
local newPositions = positionsAroundReference(sourcePart)
local newTable = {}
for index, newPos in pairs(newPositions) do
if index == 5 then
-- Use sourcePart in the middle
newTable[index] = sourcePart
newTable[index].Color = Color3.fromRGB(255, 0, 0)
else
for _, part in pairs(folder:GetChildren()) do
if (part.Position - newPos).Magnitude <= 0.25 then
-- This already created part has the position we want!
newTable[index] = part
end
end
if not newTable[index] then
-- Create a new part
newTable[index] = createPart(newPos)
end
end
end
-- Remove unused parts
-- for _, v in pairs(folder:GetChildren()) do
-- local found = table.find(newTable, v)
-- if not found then
-- v:Destroy()
-- end
-- end
-- Update partsTable
for i, v in pairs(newTable) do
partTable[i] = v
end
updateInProgress = false
end
local sourcePart = createPart(Vector3.new(0, 200, 0))
updatePartTable(sourcePart)
game:GetService("RunService").Heartbeat:Connect(function(dt)
debounce -= dt
local char = game:GetService("Players").LocalPlayer.Character
if char then
local rootPart = char:FindFirstChild("HumanoidRootPart")
if rootPart and partTable[5] then
-- Vector pointing from middle part to HumanoidRootPart (Vector2)
local distance = (Vector2.new(rootPart.Position.X, rootPart.Position.Z) - Vector2.new(
partTable[5].Position.X,
partTable[5].Position.Z
)).Magnitude
if distance > CHANGE_RADIUS then
-- Player has walked further than max distance --> update parts
local closestPart
local closestDistance = math.huge
for i, part in pairs(partTable) do
if i ~= 5 then -- Don't use middle part
local newDistance = (Vector2.new(part.Position.X, part.Position.Z) - Vector2.new(
rootPart.Position.X,
rootPart.Position.Z
)).Magnitude
if newDistance < closestDistance then -- If part is closer (by a margin)
closestPart = part
closestDistance = newDistance
end
end
end
updatePartTable(closestPart)
end
end
end
end)
This should be ran inside a LocalScript, and should work in an empty place.
Now, if I use the ocean mesh instead of the parts, it works nicely. But the animation part is where I struggle.
Mainly this question:
- How can I get the bones within a radius of the player efficiently?
Simply looping through all the bones (of all the different meshes) every frame, causes lag. As there are 4000 * 9 = 36000 bones the client has to check the distance from their HumanoidRootPart of.
Does there exist an efficient way of getting all bones within a radius from a point?