Jump to content

Easy to use lua based grid for massive 3d entity management


shadmar
 Share

Recommended Posts

Based on :

https://github.com/ING1337/CellGrid

 

1. Create a script called Scripts/class.lua

 

function class(base)

local c = {}

 

if type(base) == "table" then

for key,value in pairs(base) do

c[key] = value

end

c._base = base

end

 

c.__index = c

 

local mt = {}

mt.__call = function(class_table, ...)

local self = {}

setmetatable(self, c)

 

if class_table.init then

class_table.init(self, ...)

else

if base and base.init then

base.init(self, ...)

end

end

 

return self

end

 

c.is_a = function(self, klass)

local m = getmetatable(self)

 

while m do

if m == klass then return true end

m = m._base

end

 

return false

end

 

setmetatable(c, mt)

return c

end

 

2. Create a script called Scripts/grid.lua

 

require "Scripts/class"

 

-- LUA CellGrid by ING

-- allows massive 3d entity management

 

CellGrid = class()

 

function CellGrid:init(cellSize, offsetX, offsetY)

self.grid = {}

self.size = cellSize or 100

self.offsetX = offsetX or -15000

self.offsetY = offsetY or -15000

end

 

-- #################################################################################################################################

 

function CellGrid:AddEntity(entity, position, radius)

range = radius and (math.ceil(radius / self.size)) or 0

x = math.max(1, math.floor((position.x - self.offsetX) / self.size - range))

y = math.max(1, math.floor((position.z - self.offsetY) / self.size - range))

 

for i = x, range * 2 + x, 1 do

if self.grid == nil then self.grid = {} end

for j = y, range * 2 + y, 1 do

if self.grid[j] == nil then self.grid[j] = {} end

table.insert(self.grid[j], entity)

end

end

end

 

function CellGrid:RemoveEntity(entity, position, radius)

range = radius and (math.ceil(radius / self.size)) or 0

x = math.max(1, math.floor((position.x - self.offsetX) / self.size - range))

y = math.max(1, math.floor((position.z - self.offsetY) / self.size - range))

 

for i = x, range * 2 + x, 1 do

for j = y, range * 2 + y, 1 do

for k, comp in ipairs(self.grid[j]) do

if comp == entity then

table.remove(self.grid[j], k)

break

end

end

end

end

end

 

-- #################################################################################################################################

 

function CellGrid:GetCell(position)

x = math.max(1, math.floor((position.x - self.offsetX) / self.size))

y = math.max(1, math.floor((position.z - self.offsetY) / self.size))

 

if not self.grid[x] then return nil end

return self.grid[x][y]

end

 

3. Example usage for putting in entities : Make a camara/player/etc attached script :

 

require "Scripts/grid"

 

function Script:Start()

--init the grid

self.cell = CellGrid()

self.cell:init(50) -- sets size of one grid cell

 

-- place some entities around the xz plane

entities = { }

for x=0,20000,1

do

entities[x] = some.loaded.entity:Instance()

entities[x]:SetPosition(Math:Random(-500,500),0,SetPosition(Math:Random(-500,500))

entities[x]:Hide()

end

 

--add entities to the grid

for i,j in pairs(entities)

local position = {

x = j:GetPosition().x,

z = j:GetPosition().z

}

self.cell:AddEntity(j, position, 1)

end

end

 

function Script:UpdateWorld()

-- get player/camera position

local position = {

x = self.entity:GetParent():GetPosition().x, --assuming parent is player or camera

z = self.entity:GetParent():GetPosition().z --assuming parent is player or camera

}

-- fetch entites and show them within cell size of position

local grid = self.cell:GetCell(position)

if grid ~=nil then

for k,v in pairs(grid)

do

if v~=nil then

v:Show()

end

end

end

end

  • Upvote 5

HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB

Link to comment
Share on other sites

I notice you show the grid the player is in, but what about hiding the grid the player leaves? This seems like it would accumulate over time as the player is moving reducing it's benefit.

 

I wonder if you could automatically make a pivot inside each grid and set each entity in the grid as a child to said pivot and that way you could hide/show just the pivots and all children will go with it? Just an idea.

Link to comment
Share on other sites

Using Rick idea, perhaps show the pivots (so all tehir childs) that are around the player making perhaps square grid unit more small.

To work in a real game level, it should need to read all static entities that exist, and place them in the right cell instead of creating random entities.

Stop toying and make games

Link to comment
Share on other sites

thank's for share it

 

just a small typo:

 

on grid.lua, start function

 

entities[x]:SetPosition(Math:Random(-500,500),0,SetPosition(Math:Random(-500,500))

 

 

should be

 

entities[x]:SetPosition(Math:Random(-500,500),0,Math:Random(-500,500))

 

test%20grid.png

  • Upvote 1

Paren el mundo!, me quiero bajar.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...