So I want to make a loading/unloading chunk script which loads part terrain around a player and deletes them when they arent in range of the player
So I have achieved the loading part but the unloading/deleting part proves quite a difficult thing for me so can someone offer my some helpful insight on this problem?
I want to look through an array of which contains the loaded positions and see if its in the array of the positions that is needed to be loaded. If it detectes that it isnt in a position that is needed to be loaded then it will look through another array with contains the chunks themselves and deletes the chunk assosiated with the position that we want to delete
local LoadedChunks={} -- the loaded chunks
local LoadedPositions={} -- the loaded positions
local HaveToLoadPositions={} -- positions that is needed/requested to be loaded
--pseudo code:
for i,v in LoadedPositions do
if not table.find(HaveToLoadPositions,v) then
local Number=table.find(LoadedChunks,tostring(v))
if Number~=nil then
LoadedChunks[Number]:Destroy()
table.remove(LoadedChunks,Number)
end
end
end
well I forgot to save my code when I was attempting this and were stuck with the code that can only create chunks.
Heres the code:
--!nocheck
--credit
--youtube.com/watch?v=XtqCjPl57mM
--put togethor by strategic_oof
local HeartBeat=game:GetService("RunService").Heartbeat
HeartBeat:Wait()
local WorkspaceChunkStorage=workspace:FindFirstChild("GeneratedChunks") or Instance.new("Folder",workspace)
WorkspaceChunkStorage.Name="GeneratedChunks"
local Seed=Random.new(43568745):NextInteger(-100000,100000)
local width=200--size of eatch segment of chunk (if u wanna reduce triangle count then width*10 chunksize/10 = ten times less triangles)
local halfwidth=width/2
local size=900--size of perlin noise
local hight=175--hight of perlin noise
local chunksize=5--size of chunk
local wedge = Instance.new("WedgePart")
wedge.Anchored = true
wedge.TopSurface = Enum.SurfaceType.Smooth
wedge.BottomSurface = Enum.SurfaceType.Smooth
wedge.BrickColor=BrickColor.new("Artichoke")
wedge.Material=Enum.Material.Grass
local function Snap(Position:Vector3,SnapAmount:number)
local X = math.floor((Position.X+(SnapAmount/2))/SnapAmount)*SnapAmount -- Gets the position snapped to the snap amount on the x Axis
local Y = math.floor((Position.Y+(SnapAmount/2))/SnapAmount)*SnapAmount -- Gets the position snapped to the snap amount on the y Axis
local Z = math.floor((Position.Z+(SnapAmount/2))/SnapAmount)*SnapAmount -- Gets the position snapped to the snap amount on the z Axis
local NewBlockPos = Vector3.new(math.round(X*1000)/1000,math.round(Y*1000)/1000,math.round(Z*1000)/1000) -- Removes floating point imprecision.
return NewBlockPos
end
local function draw3dTriangle(a, b, c, parent, w1, w2)
local ab, ac, bc = b - a, c - a, c - b
local abd, acd, bcd = ab:Dot(ab), ac:Dot(ac), bc:Dot(bc)
if (abd > acd and abd > bcd) then
c, a = a, c
elseif (acd > bcd and acd > abd) then
a, b = b, a
end
ab, ac, bc = b - a, c - a, c - b
local right = ac:Cross(ab).unit
local up = bc:Cross(right).unit
local back = bc.unit
local height = math.abs(ab:Dot(up))
w1 = w1 or wedge:Clone()
w1.Size = Vector3.new(0, height, math.abs(ab:Dot(back))) + Vector3.new(.1,.1,.1)
w1.CFrame = CFrame.fromMatrix((a + b)/2, right, up, back)
w1.Parent = parent
w2 = w2 or wedge:Clone()
w2.Size = Vector3.new(0, height, math.abs(ac:Dot(back))) + Vector3.new(.1,.1,.1)
w2.CFrame = CFrame.fromMatrix((a + c)/2, -right, up, -back)
w2.Parent = parent
return w1, w2
end
local function makePoints(x,z,offset,folder)
x+=offset.X
z+=offset.Z
local APosX,APosZ=x+halfwidth,z-halfwidth
local BPosX,BPosZ=x+halfwidth,z+halfwidth
local CPosX,CPosZ=x-halfwidth,z-halfwidth
local DPosX,DPosZ=x-halfwidth,z+halfwidth
local noiseA=math.noise(Seed,APosX/size,APosZ/size)*hight
local noiseB=math.noise(Seed,BPosX/size,BPosZ/size)*hight
local noiseC=math.noise(Seed,CPosX/size,CPosZ/size)*hight
local noiseD=math.noise(Seed,DPosX/size,DPosZ/size)*hight
local A=Vector3.new(APosX,noiseA,APosZ)
local B=Vector3.new(BPosX,noiseB,BPosZ)
local C=Vector3.new(CPosX,noiseC,CPosZ)
local D=Vector3.new(DPosX,noiseD,DPosZ)
draw3dTriangle(A,B,C,folder)
draw3dTriangle(D,B,C,folder)
end
local X
local Z
local LoadedChunks={}
local LoadedPositions={}
local HaveToLoadPositions={}
local function makechunk(offset:Vector3,PlayerName:string)
local folder=Instance.new("Folder",WorkspaceChunkStorage)
folder.Name=tostring(offset)
folder:SetAttribute("Player",PlayerName)
table.insert(LoadedChunks,folder)
table.insert(LoadedPositions,offset)
for A=-chunksize/2,chunksize/2 do
Z=A*width
for B=-chunksize/2,chunksize/2 do
X=B*width
makePoints(X,Z,offset,folder)
end
end
end
local Players=game:GetService("Players")
local RootParts={}
task.spawn(function()
while true do
table.clear(HaveToLoadPositions)
for i,Root:BasePart in RootParts do
if Root~=nil and Root.Parent then
local p=Snap(Vector3.new(Root.Position.X,0,Root.Position.Z),
chunksize*width
)--calculate plrs position
--print(p)
if not table.find(HaveToLoadPositions,p) then--request chunks to load around the player
table.insert(HaveToLoadPositions,p)
end
else
table.remove(RootParts,i)
end
end
for i=0, 60*2 do
HeartBeat:Wait()
end--align
end
end)
local function PlayerAdded(Plr:Player)
local function CharacterAdded(Char:Model)
local Hum:Humanoid=Char:WaitForChild("Humanoid",3) or Char:FindFirstChildOfClass("Humanoid")
local Root:BasePart=Char:WaitForChild("HumanoidRootPart",3) or Char:WaitForChild("Head",3) or Char.PrimaryPart
if Hum~=nil and Root~=nil then
if Hum.Health>0 then
table.insert(RootParts,Root)
Hum.Died:Once(function()
local Numb=table.find(RootParts,Root)
if Numb~=nil then
table.remove(RootParts,Numb)
end
end)
--old example
--while Root~=nil and Hum~=nil do
-- if Hum.Health>0 then
-- table.clear(HaveToLoadPositions)
-- local p=Snap(Vector3.new(Root.Position.X,0,Root.Position.Z),
-- chunksize*width
-- )
-- print(p)
-- if not table.find(HaveToLoadPositions,p) then
-- table.insert(HaveToLoadPositions,p)
-- end
-- else
-- break
-- end
-- for i=0, 60*2 do
-- HeartBeat:Wait()
-- end--align
--end
end
end
end
local function PlayerRemoved(Player:Player)
if Player==Plr then
else
Players.PlayerRemoving:Once(PlayerRemoved)
end
end
Players.PlayerRemoving:Once(PlayerRemoved)
Plr.CharacterAdded:Connect(CharacterAdded)
end
Players.PlayerAdded:Connect(PlayerAdded)
while true do
for i=0, 60*3 do
HeartBeat:Wait()
end--align
--find chunks that arent in the "HaveToLoadPositions" table and delete them
for i, v in HaveToLoadPositions do
if not table.find(LoadedPositions,v) then
makechunk(v)--v,closestplayer
end
end
end
Im not asking for people to rewrite the script thats for a different topic. I just need a reliable way to delete chunks that arent in the range of a player.