Jump to content

Procedural Generation in Leadwerks using Prefabs??


ShadowRadience
 Share

Recommended Posts

I dont have and huge amounths of LUA scripting knowlege, but i understand the basics, i read all the LUA tutorials on the leadworks site. What im trying to do is create a single base room where the player starts, there is one exit, and after that exit using prefabs to randomly generate the rest of the map. Is this possible? Ive read forums on it(on this website, couldnt find one that helped, at the end of this post ill link some of the forums i read, i read all the ocmments as well), i just cant seem to figure it out and its killing me, ive been working on it for 16 hours straight. So if anyone is willing to help me out i would appreciate it. I dont even know how to start other than making prefabs with clear entrances and exits.

a:http://www.leadwerks.com/werkspace/blog/52/entry-882-lets-make-a-game-procedual-content-creation-part-01/

b:http://www.leadwerks.com/werkspace/topic/12430-procedural-generation/

c:http://www.leadwerks.com/werkspace/topic/12063-procedural-generated-levels-using-prefabs/

d:http://www.leadwerks.com/werkspace/topic/8168-procedural-generation-possible/

Link to comment
Share on other sites

It's possible, but very difficult. Each room would be a prefab that would have doorways at different places. You would need to link each room by the doorways. You would need to stop rooms intersecting with one another and would need to make sure that you don't create dead ends that would stop you from getting to the end.

 

I can't help you with this, as it is too big of a project just to help someone else do it, but this is something I may look into for one of my next projects.

Link to comment
Share on other sites

This isn't so much of a game dev challenge as it is an algorithm issue. It's easy to avoid making rooms not intersect by using a 2D or 3D array. The difficult part is making the result be what you want. You need to define how you want the procedural generation to go.

 

In particular, I would look at these:

https://en.wikipedia.org/wiki/Category:Graph_algorithms

 

I would particularly look at the minimum spanning tree ones:

https://en.wikipedia.org/wiki/Kruskal%27s_algorithm

https://en.wikipedia.org/wiki/Prim%27s_algorithm

 

Then, you should have a decent base to create this. But you still need to position the nodes and stuff. It can get somewhat complicated on the conceptual end or the coding end, so if you haven't programmed before, then this might not be the best project to start out with.

Link to comment
Share on other sites

This isn't so much of a game dev challenge as it is an algorithm issue. It's easy to avoid making rooms not intersect by using a 2D or 3D array. The difficult part is making the result be what you want. You need to define how you want the procedural generation to go.

 

In particular, I would look at these:

https://en.wikipedia.org/wiki/Category:Graph_algorithms

 

I would particularly look at the minimum spanning tree ones:

https://en.wikipedia.org/wiki/Kruskal%27s_algorithm

https://en.wikipedia.org/wiki/Prim%27s_algorithm

 

Then, you should have a decent base to create this. But you still need to position the nodes and stuff. It can get somewhat complicated on the conceptual end or the coding end, so if you haven't programmed before, then this might not be the best project to start out with.

Well ive programmed in other languages honestly couple years back i picked up C++ for a year, i studied HML CSS LESS Javscript, ruby and SASS in highschool, i tried java not really a fan, im thinking that maybe i should just pick up C++ again and use cpp instead of lua(i have all the DLC, i just thought lua was easier, but considering how flexible C++ is it might be the way i should go.) Before that though, i think im gunna give Programming in LUA Third Edition a read and hope i can figure it out cuz id rather not switch to C++.

Wedmer posted a procedural generation script in the Workshop

 

http://www.leadwerks.com/werkspace/page/viewitem?fileid=543847683

 

I haven't had a look at it myself but it would be a good place to start.

I appreciate it, i read the tutorial flexman did about this tutorial on the workshop, i also read the code that was in that workshop files(if i remember it was Main.lua and Test.lua) but its not what i wanna do, thats generating terrain without the use of prefabs, im trying to do it with prefabs so i have more control over how things will spawn in the map.

 

Edit: I just read Programming in LUA Third Edition, and watch an hour long "Lua in one video" video, and i still dont have the slightest clue how to do this? Do i have to somehow store prefabs in a table and then call that table to generate it on Script:UpdateWorld()? If i did that wouldnt the world just keep generating new prefabs every frame, that would be an issue. I dont know, if anyone has any help, i could sure use it. Thanks in advance. I tried this code from another forum:

Script.startPivot="" --entity
Script.dungeon={}
Script.names={"d1", "d2l", "d2r", "d3l", "d3r"} --Names of all possible dungeon segments to check AABB intersection
Script.d1="Prefabs/Dungeon/d1.pfb"
Script.d2l="Prefabs/Dungeon/d2l.pfb"
Script.d2r="Prefabs/Dungeon/d2r.pfb"
Script.d3l="Prefabs/Dungeon/d3l.pfb"
Script.d3r="Prefabs/Dungeon/d3r.pfb"
Script.currentR=0
Script.nextR=0
Script.j=0
Script.i=0
Script.s=0
Script.allDungeonSegments={}
--Debug
function Script:Start()
--math.randomseed(10)
end
function Script:UpdateWorld()
if App.window:KeyHit(Key.G) then self:Use() end
end
function Script:Use()
self:GenerateDungeon()
end
function Script:GenerateDungeon() --main generation function
self.currentR=0
self.nextR=0
self.i=0
self.j=0
player:ConsoleLog("Generation started. Countentities = "..App.world:CountEntities())
self:DeleteAllDungeonSegments()
player:ConsoleLog("All segments deleted. Countentities = "..App.world:CountEntities())
self.dungeon={}
self.dungeon[0]=self:CreateSegment(self:GetRandomPart()) --Create first dungeon element
self.dungeon[0]:SetRotation(0,self.currentR,0,true)
local pos = self.dungeon[0]:FindChild("Enter"):GetPosition(true)
local previousPos = self.startPivot:GetPosition(true)
local dPos = pos-previousPos
self.dungeon[0]:SetPosition(pos-dPos, true)
local result = true --Create main path
self.dungeon, result=self:GeneratePath(100, self.dungeon) --If this function failed to generate dungeon we still need to save it, but we sholdn't proceed further
if not result then
self:GenerateDungeon() --Failed to generate dungeon, starting again
return
end
--Generate forks
self:GenerateForks()
end
function Script:GeneratePath(amount, startingTable, emergencyLimit)
if not emergencyLimit then emergencyLimit=200 end
local dungeon={}
dungeon=startingTable
local emergencyCounter=0
local i=#dungeon+1
self.intersectionFound=false
while i<=amount do
emergencyCounter=emergencyCounter+1
--System:Print(emergencyCounter.." i="..i)
if emergencyCounter>emergencyLimit then --reached limit of retries, generate again
return dungeon, false --still need to return current dungeon to be able to clear it
end
dungeon[i]=self:CreateSegment(self:GetRandomPart())
local yRotation=dungeon[i-1]:GetRotation(true).y+self:GetExtraRotation(dungeon[i-1])
dungeon[i]:SetRotation(0,yRotation,0,true)
pos = dungeon[i]:FindChild("Enter"):GetPosition(true)
previousPos = dungeon[i-1]:FindChild("Exit"):GetPosition(true)
dPos = pos-previousPos
dungeon[i]:SetPosition(dungeon[i]:GetPosition(true)-dPos, true)
--Check AABB
local aabb=dungeon[i]:GetAABB(Entity.GlobalAABB)
local j=1
local maximum=#self.allDungeonSegments
while j<=maximum do
--System:Print(j)
if self.allDungeonSegments[j]~=dungeon[i] and self.allDungeonSegments[j]~=dungeon[i-1] and self.allDungeonSegments[j]~=dungeon[i-2] then
if aabb:IntersectsAABB(self.allDungeonSegments[j]:GetAABB(Entity.GlobalAABB)) then
System:Print(dungeon[i]:GetKeyValue("name").." intersects with "..self.allDungeonSegments[j]:GetKeyValue("name"))
if i<4 then
return dungeon, false
else
System:Print("Three steps back")
self:DeleteSegment(dungeon[i])
System:Print("Deleted last segment")
dungeon[i]=nil
self:DeleteSegment(dungeon[i-1])
System:Print("Deleted i-1")
dungeon[i]=nil
self:DeleteSegment(dungeon[i-2])
System:Print("Deleted i-2")
dungeon[i]=nil
i=i-3
j=1000--maximum+1
end
end
end
j=j+1
end
i=i+1
--System:Print("End of I loop. i="..i)
end
return dungeon, true --returning true if managed to generate dungeon properly
end
function Script:GenerateForks()
local i=1
while i <= #self.dungeon do
if self.dungeon[i]:GetKeyValue("name")=="d1" and math.random(0, 20)==0 then
local matrix=self.dungeon[i]:GetMatrix(true)
self:DeleteSegment(self.dungeon[i])
self.dungeon[i]={}
self.dungeon[i][0]=self:CreateSegment(self:GetRandomPart(4,5))
self.dungeon[i][0]:SetMatrix(matrix, true)
self.dungeon[i][1]=self:CreateSegment(self:GetRandomPart())
local yRotation=self.dungeon[i][0]:GetRotation(true).y+self:GetExtraRotation(self.dungeon[i][0]) --second element
self.dungeon[i][1]:SetRotation(0,yRotation,0,true)
pos = self.dungeon[i][1]:FindChild("Enter"):GetPosition(true)
previousPos = self.dungeon[i][0]:FindChild("Exit2"):GetPosition(true)
dPos = pos-previousPos
self.dungeon[i][1]:SetPosition(self.dungeon[i][1]:GetPosition(true)-dPos, true)
--local dungeon
--local result
local dungeon, result = self:GeneratePath(15, self.dungeon[i], 30)
if not result then
self:DeleteSegment(dungeon[#dungeon])
self.dungeon[i]=dungeon
else
self.dungeon[i]=dungeon
end
end
i=i+1
end
end
--other function
function Script:GetRandomPart(minimum, maximum) --Choose random element
if not minimum then minimum=0; maximum=3 end
local r=math.random(minimum, maximum)
if r==1 or r==0 then
return self.d1
elseif r==2 then
return self.d2r
elseif r==3 then
return self.d2l
elseif r==4 then
return self.d3r
elseif r==5 then
return self.d3l
end
end
function Script:GetExtraRotation(name)
name=name:GetKeyValue("name")
if name=="d2r" or name=="d3r" then
return (90)
elseif name=="d2l" or name=="d3l" then
return (-90)
end
return 0 --all other segments return 0
end
function Script:CreateSegment(name)
local entity=Prefab:Load(name)
table.insert (self.allDungeonSegments, entity)
return entity
end
function Script:DeleteSegment(entity)
local i=1
local maximum=#self.allDungeonSegments
while i<=maximum do
if self.allDungeonSegments[i]==entity then
local temp = self.allDungeonSegments[i]
table.remove (self.allDungeonSegments, i)
--self.allDungeonSegments[i]=0
temp:Release()
i=maximum
end
i=i+1
end
end
function Script:DeleteAllDungeonSegments()
for i=1, #self.allDungeonSegments do
self.allDungeonSegments[i]:Release()
end
self.allDungeonSegments={}
end
function Script:IsDungeonSegment(name) --not needed
name=name:GetKeyValue("name")
for i=1, #self.names do
if self.names[i]==name then return true end
end
return false
end

and i changed it to

Script.startPivot="Exit2" --entity Starting Pivot
Script.dungeon={}
Script.names={"BaseRoom", "Hallway", "Intersection", "Corner", "Stairs"} --Names of all possible dungeon segments to check AABB intersection
Script.BaseRoom="Prefabs/Dungeon/BaseRoom.pfb"
Script.Hallway="Prefabs/Dungeon/Hallway.pfb"
Script.Intersection="Prefabs/Dungeon/Intersection.pfb"
Script.Corner="Prefabs/Dungeon/Corner.pfb"
Script.Stairs="Prefabs/Dungeon/Stairs.pfb"
Script.currentR=0
Script.nextR=0
Script.j=0
Script.i=0
Script.s=0
Script.allDungeonSegments={}
--Debug
function Script:Start()
--math.randomseed(10)
end
function Script:UpdateWorld()
if window:KeyHit(Key.G) then
self:Use()
end
end
function Script:Use()
self:GenerateDungeon()
end
function Script:GenerateDungeon() --main generation function
self.currentR=0
self.nextR=0
self.i=0
self.j=0
print("Generation started. Countentities = "..world:CountEntities())
self:DeleteAllDungeonSegments()
print("All segments deleted. Countentities = "..world:CountEntities())
self.dungeon={}
self.dungeon[0]=self:CreateSegment(self:GetRandomPart()) --Create first dungeon element
self.dungeon[0]:SetRotation(0,self.currentR,0,true)
local pos = self.dungeon[0]:FindChild("Enter"):GetPosition(true)
local previousPos = self.startPivot:GetPosition(true)
local dPos = pos-previousPos
self.dungeon[0]:SetPosition(pos-dPos, true)
local result = true --Create main path
self.dungeon, result=self:GeneratePath(100, self.dungeon) --If this function failed to generate dungeon we still need to save it, but we sholdn't proceed further
if not result then
self:GenerateDungeon() --Failed to generate dungeon, starting again
return
end
--Generate forks
self:GenerateForks()
end
function Script:GeneratePath(amount, startingTable, emergencyLimit)
if not emergencyLimit then emergencyLimit=200 end
local dungeon={}
dungeon=startingTable
local emergencyCounter=0
local i=#dungeon+1
self.intersectionFound=false
while i<=amount do
emergencyCounter=emergencyCounter+1
--System:Print(emergencyCounter.." i="..i)
if emergencyCounter>emergencyLimit then --reached limit of retries, generate again
return dungeon, false --still need to return current dungeon to be able to clear it
end
dungeon[i]=self:CreateSegment(self:GetRandomPart())
local yRotation=dungeon[i-1]:GetRotation(true).y+self:GetExtraRotation(dungeon[i-1])
dungeon[i]:SetRotation(0,yRotation,0,true)
pos = dungeon[i]:FindChild("Enter"):GetPosition(true)
previousPos = dungeon[i-1]:FindChild("Exit"):GetPosition(true)
dPos = pos-previousPos
dungeon[i]:SetPosition(dungeon[i]:GetPosition(true)-dPos, true)
--Check AABB
local aabb=dungeon[i]:GetAABB(Entity.GlobalAABB)
local j=1
local maximum=#self.allDungeonSegments
while j<=maximum do
--System:Print(j)
if self.allDungeonSegments[j]~=dungeon[i] and self.allDungeonSegments[j]~=dungeon[i-1] and self.allDungeonSegments[j]~=dungeon[i-2] then
if aabb:IntersectsAABB(self.allDungeonSegments[j]:GetAABB(Entity.GlobalAABB)) then
System:Print(dungeon[i]:GetKeyValue("name").." intersects with "..self.allDungeonSegments[j]:GetKeyValue("name"))
if i<4 then
return dungeon, false
else
System:Print("Three steps back")
self:DeleteSegment(dungeon[i])
System:Print("Deleted last segment")
dungeon[i]=nil
self:DeleteSegment(dungeon[i-1])
System:Print("Deleted i-1")
dungeon[i]=nil
self:DeleteSegment(dungeon[i-2])
System:Print("Deleted i-2")
dungeon[i]=nil
i=i-3
j=1000--maximum+1
end
end
end
j=j+1
end
i=i+1
--System:Print("End of I loop. i="..i)
end
return dungeon, true --returning true if managed to generate dungeon properly
end
function Script:GenerateForks()
local i=1
while i <= #self.dungeon do
if self.dungeon[i]:GetKeyValue("name")=="BaseRoom" and math.random(0, 20)==0 then
local matrix=self.dungeon[i]:GetMatrix(true)
self:DeleteSegment(self.dungeon[i])
self.dungeon[i]={}
self.dungeon[i][0]=self:CreateSegment(self:GetRandomPart(4,5))
self.dungeon[i][0]:SetMatrix(matrix, true)
self.dungeon[i][1]=self:CreateSegment(self:GetRandomPart())
local yRotation=self.dungeon[i][0]:GetRotation(true).y+self:GetExtraRotation(self.dungeon[i][0]) --second element
self.dungeon[i][1]:SetRotation(0,yRotation,0,true)
pos = self.dungeon[i][1]:FindChild("Enter"):GetPosition(true)
previousPos = self.dungeon[i][0]:FindChild("Exit2"):GetPosition(true)
dPos = pos-previousPos
self.dungeon[i][1]:SetPosition(self.dungeon[i][1]:GetPosition(true)-dPos, true)
--local dungeon
--local result
local dungeon, result = self:GeneratePath(15, self.dungeon[i], 30)
if not result then
self:DeleteSegment(dungeon[#dungeon])
self.dungeon[i]=dungeon
else
self.dungeon[i]=dungeon
end
end
i=i+1
end
end
--other function
function Script:GetRandomPart(minimum, maximum) --Choose random element
if not minimum then minimum=0; maximum=3 end
local r=math.random(minimum, maximum)
if r==1 or r==0 then
return self.BaseRoom
elseif r==2 then
return self.Hallway
elseif r==3 then
return self.Intersection
elseif r==4 then
return self.Corner
elseif r==5 then
return self.Stairs
end
end
function Script:GetExtraRotation(name)
name=name:GetKeyValue("name")
if name=="Hallway" or name=="Intersection" then
return (90)
elseif name=="Hallway" or name=="Intersection" then
return (-90)
end
return 0 --all other segments return 0
end
function Script:CreateSegment(name)
local entity=Prefab:Load(name)
table.insert (self.allDungeonSegments, entity)
return entity
end
function Script:DeleteSegment(entity)
local i=1
local maximum=#self.allDungeonSegments
while i<=maximum do
if self.allDungeonSegments[i]==entity then
local temp = self.allDungeonSegments[i]
table.remove (self.allDungeonSegments, i)
--self.allDungeonSegments[i]=0
temp:Release()
i=maximum
end
i=i+1
end
end
function Script:DeleteAllDungeonSegments()
for i=1, #self.allDungeonSegments do
self.allDungeonSegments[i]:Release()
end
self.allDungeonSegments={}
end
function Script:IsDungeonSegment(name) --not needed
name=name:GetKeyValue("name")
for i=1, #self.names do
if self.names[i]==name then return true end
end
return false
end

and now when i run it i get an error with startPivot as a nil value i odnt know why. Even if i set the pivot to a value like "Exit2" or "Exit" or even "Enter" it still gives me the nil value?

Link to comment
Share on other sites

That is a lot of code to go through.

 

I am still learning Lua as well and I am very inexperienced but here is my guess as to why you are getting an issue with 'startPivot'.

 

There are scripts at the very start of the code that you are calling within this script.

 

'startPivot' is it's own script that you are calling within this script. You are getting a 'nil' value because it cannot find 'startPivot'.

 

My guess would be that even if you fix that you would get further issues because throughout the code you are using scripts and calling functions that are supposed to be defined within those other scripts.

 

Then again I could be completely wrong.

 

I am still learning myself and that code above looks big and scary sad.png

 

Kudos though for the time and effort you have put in, that is some dedication right there!

Link to comment
Share on other sites

That is a lot of code to go through.

 

I am still learning Lua as well and I am very inexperienced but here is my guess as to why you are getting an issue with 'startPivot'.

 

There are scripts at the very start of the code that you are calling within this script.

 

'startPivot' is it's own script that you are calling within this script. You are getting a 'nil' value because it cannot find 'startPivot'.

 

My guess would be that even if you fix that you would get further issues because throughout the code you are using scripts and calling functions that are supposed to be defined within those other scripts.

 

Then again I could be completely wrong.

 

I am still learning myself and that code above looks big and scary sad.png

 

Kudos though for the time and effort you have put in, that is some dedication right there!

I appreciate it! Thanks! I think i may just go through trial and error with making a completely original script for it.

Link to comment
Share on other sites

I just read Programming in LUA Third Edition, and watch an hour long "Lua in one video" video, and i still dont have the slightest clue how to do this? Do i have to somehow store prefabs in a table and then call that table to generate it on Script:UpdateWorld()? If i did that wouldnt the world just keep generating new prefabs every frame, that would be an issue. I dont know, if anyone has any help, i could sure use it. Thanks in advance. I tried this code from another forum:

 

 

I didn't look at that code you posted because it's pretty long but you would generate the dungeons in either Main.lua or if done in an entity script in Script:Start(). You could do it in UpdateWorld() if your goal was to generate it on the fly as you're moving around though. That's possible but you probably for now want to stick with doing it once on start up.

 

I agree with nick that using a 2D array would probably be the way to go. Make each room the same size and the 2D array breaks things into a grid system and you place a new room at each grid or connector tunnels between rooms but they still are the same size.

Link to comment
Share on other sites

 

Script.startPivot="" --entity
Script.dungeon={}
Script.names={"d1", "d2l", "d2r", "d3l", "d3r"} --Names of all possible dungeon segments to check AABB intersection
Script.d1="Prefabs/Dungeon/d1.pfb"
Script.d2l="Prefabs/Dungeon/d2l.pfb"
Script.d2r="Prefabs/Dungeon/d2r.pfb"
Script.d3l="Prefabs/Dungeon/d3l.pfb"
Script.d3r="Prefabs/Dungeon/d3r.pfb"
Script.currentR=0
Script.nextR=0
Script.j=0
Script.i=0
Script.s=0
Script.allDungeonSegments={}
--Debug
function Script:Start()
--math.randomseed(10)
end
function Script:UpdateWorld()
if App.window:KeyHit(Key.G) then self:Use() end
end
function Script:Use()
self:GenerateDungeon()
end
function Script:GenerateDungeon() --main generation function
self.currentR=0
self.nextR=0
self.i=0
self.j=0
player:ConsoleLog("Generation started. Countentities = "..App.world:CountEntities())
self:DeleteAllDungeonSegments()
player:ConsoleLog("All segments deleted. Countentities = "..App.world:CountEntities())
self.dungeon={}
self.dungeon[0]=self:CreateSegment(self:GetRandomPart()) --Create first dungeon element
self.dungeon[0]:SetRotation(0,self.currentR,0,true)
local pos = self.dungeon[0]:FindChild("Enter"):GetPosition(true)
local previousPos = self.startPivot:GetPosition(true)
local dPos = pos-previousPos
self.dungeon[0]:SetPosition(pos-dPos, true)
local result = true --Create main path
self.dungeon, result=self:GeneratePath(100, self.dungeon) --If this function failed to generate dungeon we still need to save it, but we sholdn't proceed further
if not result then
self:GenerateDungeon() --Failed to generate dungeon, starting again
return
end
--Generate forks
self:GenerateForks()
end
function Script:GeneratePath(amount, startingTable, emergencyLimit)
if not emergencyLimit then emergencyLimit=200 end
local dungeon={}
dungeon=startingTable
local emergencyCounter=0
local i=#dungeon+1
self.intersectionFound=false
while i<=amount do
emergencyCounter=emergencyCounter+1
--System:Print(emergencyCounter.." i="..i)
if emergencyCounter>emergencyLimit then --reached limit of retries, generate again
return dungeon, false --still need to return current dungeon to be able to clear it
end
dungeon[i]=self:CreateSegment(self:GetRandomPart())
local yRotation=dungeon[i-1]:GetRotation(true).y+self:GetExtraRotation(dungeon[i-1])
dungeon[i]:SetRotation(0,yRotation,0,true)
pos = dungeon[i]:FindChild("Enter"):GetPosition(true)
previousPos = dungeon[i-1]:FindChild("Exit"):GetPosition(true)
dPos = pos-previousPos
dungeon[i]:SetPosition(dungeon[i]:GetPosition(true)-dPos, true)
--Check AABB
local aabb=dungeon[i]:GetAABB(Entity.GlobalAABB)
local j=1
local maximum=#self.allDungeonSegments
while j<=maximum do
--System:Print(j)
if self.allDungeonSegments[j]~=dungeon[i] and self.allDungeonSegments[j]~=dungeon[i-1] and self.allDungeonSegments[j]~=dungeon[i-2] then
if aabb:IntersectsAABB(self.allDungeonSegments[j]:GetAABB(Entity.GlobalAABB)) then
System:Print(dungeon[i]:GetKeyValue("name").." intersects with "..self.allDungeonSegments[j]:GetKeyValue("name"))
if i<4 then
return dungeon, false
else
System:Print("Three steps back")
self:DeleteSegment(dungeon[i])
System:Print("Deleted last segment")
dungeon[i]=nil
self:DeleteSegment(dungeon[i-1])
System:Print("Deleted i-1")
dungeon[i]=nil
self:DeleteSegment(dungeon[i-2])
System:Print("Deleted i-2")
dungeon[i]=nil
i=i-3
j=1000--maximum+1
end
end
end
j=j+1
end
i=i+1
--System:Print("End of I loop. i="..i)
end
return dungeon, true --returning true if managed to generate dungeon properly
end
function Script:GenerateForks()
local i=1
while i <= #self.dungeon do
if self.dungeon[i]:GetKeyValue("name")=="d1" and math.random(0, 20)==0 then
local matrix=self.dungeon[i]:GetMatrix(true)
self:DeleteSegment(self.dungeon[i])
self.dungeon[i]={}
self.dungeon[i][0]=self:CreateSegment(self:GetRandomPart(4,5))
self.dungeon[i][0]:SetMatrix(matrix, true)
self.dungeon[i][1]=self:CreateSegment(self:GetRandomPart())
local yRotation=self.dungeon[i][0]:GetRotation(true).y+self:GetExtraRotation(self.dungeon[i][0]) --second element
self.dungeon[i][1]:SetRotation(0,yRotation,0,true)
pos = self.dungeon[i][1]:FindChild("Enter"):GetPosition(true)
previousPos = self.dungeon[i][0]:FindChild("Exit2"):GetPosition(true)
dPos = pos-previousPos
self.dungeon[i][1]:SetPosition(self.dungeon[i][1]:GetPosition(true)-dPos, true)
--local dungeon
--local result
local dungeon, result = self:GeneratePath(15, self.dungeon[i], 30)
if not result then
self:DeleteSegment(dungeon[#dungeon])
self.dungeon[i]=dungeon
else
self.dungeon[i]=dungeon
end
end
i=i+1
end
end
--other function
function Script:GetRandomPart(minimum, maximum) --Choose random element
if not minimum then minimum=0; maximum=3 end
local r=math.random(minimum, maximum)
if r==1 or r==0 then
return self.d1
elseif r==2 then
return self.d2r
elseif r==3 then
return self.d2l
elseif r==4 then
return self.d3r
elseif r==5 then
return self.d3l
end
end
function Script:GetExtraRotation(name)
name=name:GetKeyValue("name")
if name=="d2r" or name=="d3r" then
return (90)
elseif name=="d2l" or name=="d3l" then
return (-90)
end
return 0 --all other segments return 0
end
function Script:CreateSegment(name)
local entity=Prefab:Load(name)
table.insert (self.allDungeonSegments, entity)
return entity
end
function Script:DeleteSegment(entity)
local i=1
local maximum=#self.allDungeonSegments
while i<=maximum do
if self.allDungeonSegments[i]==entity then
local temp = self.allDungeonSegments[i]
table.remove (self.allDungeonSegments, i)
--self.allDungeonSegments[i]=0
temp:Release()
i=maximum
end
i=i+1
end
end
function Script:DeleteAllDungeonSegments()
for i=1, #self.allDungeonSegments do
self.allDungeonSegments[i]:Release()
end
self.allDungeonSegments={}
end
function Script:IsDungeonSegment(name) --not needed
name=name:GetKeyValue("name")
for i=1, #self.names do
if self.names[i]==name then return true end
end
return false
end

 

 

That's my script. You are supposed to have 5 prefabs with specified entry and exit pivots. And a start pivot as a beginning of a dungeon.

But I don't know what have you changed.

 

Edit: Have you just typed a string value in startPivot variable? You should drag a pivot entity in the scene on this variable in the inspector.

  • Upvote 1
Link to comment
Share on other sites

That's my script. You are supposed to have 5 prefabs with specified entry and exit pivots. And a start pivot as a beginning of a dungeon.

But I don't know what have you changed.

 

Edit: Have you just typed a string value in startPivot variable? You should drag a pivot entity in the scene on this variable in the inspector.

I changed the code "if App.window:KeyHit(Key.G)then self:Use()end" to "if window:KeyHit(Key.G)" along with the console print thing to just print. and i typed in the strng for start pivot, what ive done using your code is, i made a base room, put the player in it, added a pivot at the entrance and put the script onto it, then i just put a pivot at every other prefabs entrance and exit, i got it to work at one point(like just being able to run the game without errors) and then i pressed g and well, nothing happened anywhere in the map. The only script attached to any of the pivots are the one in the player spawn room. and then the rest are just plain pivots nothing attached, no renames. So, if i repaste your original code into a script and change the location names for the prefabs and saved the script it would be the exact same thing as your original one, but with this :

[/font]
[size=2][size=4][font=arial,helvetica,sans-serif]Script.d1="Prefabs/Dungeon/d1.pfb"
Script.d2l="Prefabs/Dungeon/d2l.pfb"
Script.d2r="Prefabs/Dungeon/d2r.pfb"
Script.d3l="Prefabs/Dungeon/d3l.pfb"
Script.d3r="Prefabs/Dungeon/d3r.pfb"

[/size][/size]

changed to something like this

Script.d1="Prefabs/Dungeon/Room5.pfb"
Script.d2l="Prefabs/Dungeon/Room4.pfb"
Script.d2r="Prefabs/Dungeon/Room3.pfb"
Script.d3l="Prefabs/Dungeon/Room2.pfb"
Script.d3r="Prefabs/Dungeon/Room1.pfb"

and then all i would do is say i want the player to start in room 1 i would put a pivot at room ones entrance(there would be no exit on this one just one exit point) and attach the script you made to it, and then save that room as a prefab named Room1 in the Prefabs/Dungeon/Room1.pfb and then place it in the scene, and then all the other prefabs would just have plain old normal pivots at the entrance and exit for each one?

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...