I can move this to a different category if needed.
I am having issues with a dungeon generation system. I’ve been learning how these systems work, so I am currently using this guide, and I plan to either edit it or make my own in the future. The generation itself it alright, but my issue stems from trying to add doors at every doorway point. I only need a working base.
Desired result: Doors spawn properly in every doorway, and open normally.
What is happening: Doors spawn mostly correctly, but the doors rotate to always face forwards in a certain direction, and are taking welded details with them.
Video of issue:
(ignore the doors that spawn two together, I’ll fix that later)
Image of door hierarchy:
All related scripts:
RoomGen (server script)
workspace.Baseplate:Destroy()
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local setPieces = ReplicatedStorage:FindFirstChild("SetPieces")
door = require(script.DoorGeneration)
local function Generate(StartPosition, MaxRooms)
local CurrectRoomGenerated = 0
local DistanceBetweenTiles = 16.86713409423828
local LastGenerated
local function Branchout(Model:model)
task.wait()
if Model:GetAttribute("Room") == false then
for i, v in pairs(Model:GetChildren()) do
if v:IsA("BasePart") and v.name == "Doorway" then
local newPosition = v.Position + v.CFrame.LookVector * DistanceBetweenTiles
local checkBox = Instance.new("Part", workspace.Debris)
checkBox.Anchored = true
checkBox.Size = Vector3.new(14,19,1)
checkBox.Position = newPosition
local partsInCheckBox = workspace:GetPartsInPart(checkBox)
checkBox:Destroy()
if #partsInCheckBox > 0 or CurrectRoomGenerated >= MaxRooms then
v.Transparency = 0
v.Color = Color3.new(0.639216, 0.635294, 0.647059)
else
local newPiece = setPieces:GetChildren()[math.random(1,#setPieces:GetChildren())]:Clone()
newPiece.Parent = workspace.ActivePieces
local cf = CFrame.new(Vector3.new(newPosition.X, StartPosition.Y, newPosition.Z), v.Position)
newPiece:PivotTo(cf)
cf = CFrame.new(newPiece.PrimaryPart.Position) * CFrame.Angles(math.rad(0),math.rad(newPiece.PrimaryPart.Orientation.Y), math.rad(newPiece.PrimaryPart.orientation.Z))
newPiece:PivotTo(cf)
--[[local doorSpawner = newPiece:FindFirstChild("DoorSpawner")
local doorsFolder = workspace.ActivePieces.Doors
local doorClone = facilityDoor:Clone()
if doorSpawner then
doorClone.Parent = doorsFolder
doorClone.PrimaryPart:PivotTo(doorSpawner.CFrame)
end]]--
if newPiece:GetAttribute("Room") == true then
CurrectRoomGenerated += 1
end
coroutine.wrap(Branchout)(newPiece)
door.GenerateDoors(newPiece)
v:Destroy()
end
end
end
else
local possibleHallways = {
setPieces:WaitForChild("SmallHallway_4");
setPieces:WaitForChild("SmallHallway_L");
setPieces:WaitForChild("SmallHallway_S");
setPieces:WaitForChild("SmallHallway_T");
setPieces:WaitForChild("SmallHallway_R");
}
for i,v in pairs(Model:GetChildren()) do
if v:IsA("BasePart") and v.name == "Doorway" then
local newPosition = v.Position + v.CFrame.LookVector*16.9
local checkBox = Instance.new("Part", workspace.Debris)
checkBox.Anchored = true
checkBox.Size = Vector3.new(14,19,1)
checkBox.Position = newPosition
local partsInCheckBox = workspace:GetPartsInPart(checkBox)
checkBox:Destroy()
if #partsInCheckBox > 0 or CurrectRoomGenerated >= MaxRooms then
v.Transparency = 0
v.Color = Color3.new(0.639216, 0.635294, 0.647059)
else
local newPiece = possibleHallways[math.random(1,#possibleHallways)]:Clone()
newPiece.Parent = workspace.ActivePieces
local cf = CFrame.new(Vector3.new(newPosition.X, StartPosition.Y, newPosition.Z), v.Position)
newPiece:PivotTo(cf)
cf = CFrame.new(newPiece.PrimaryPart.Position) * CFrame.Angles(math.rad(0),math.rad(newPiece.PrimaryPart.Orientation.Y), math.rad(newPiece.PrimaryPart.Orientation.Z))
newPiece:PivotTo(cf)
--[[local doorSpawner = newPiece:FindFirstChild("DoorSpawner")
local doorsFolder = workspace.ActivePieces.Doors
local doorClone = facilityDoor:Clone()
if doorSpawner then
doorClone.Parent = doorsFolder
doorClone.PrimaryPart:PivotTo(doorSpawner.CFrame)
end]]--
if newPiece:GetAttribute("Room") == true then
CurrectRoomGenerated += 1
end
coroutine.wrap(Branchout)(newPiece)
door.GenerateDoors(newPiece)
v:Destroy()
end
end
end
end
LastGenerated = tick()
end
local StartRoom = ReplicatedStorage:WaitForChild("StartRoom"):Clone()
StartRoom.Parent = workspace.ActivePieces
StartRoom:SetPrimaryPartCFrame(CFrame.new(StartPosition))
CurrectRoomGenerated += 1
Branchout(StartRoom)
while CurrectRoomGenerated < MaxRooms do
print("Running")
task.wait(.5)
if tick() - LastGenerated > 2 then
print("Error. Retrying.")
workspace.ActivePieces:ClearAllChildren()
workspace.Debris:ClearAllChildren()
Generate(StartPosition,MaxRooms)
return
end
end
print("Done")
end
Generate(Vector3.new(0,30,0),5)
DoorGeneration (module)
local door = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local facilityDoor = ReplicatedStorage:WaitForChild("FacilityDoor")
function door.GenerateDoors(newPiece)
if newPiece:FindFirstChild("DoorSpawner") then
local spawner = newPiece:FindFirstChild("DoorSpawner")
local doorway = newPiece:GetChildren("Doorway")
if doorway.Transparency == 0 then end
if doorway.Transparency ~= 0 then
local cloneDoor = facilityDoor:Clone()
local doorOpen = require(cloneDoor.DoorOpening)
cloneDoor.Parent = workspace.ActivePieces.Doors
cloneDoor:PivotTo(spawner.CFrame)
doorOpen.Opening()
end
end
end
return door
DoorOpening (module)
local doorOpen = {}
local TweenService = game:GetService("TweenService")
function doorOpen.Opening()
local doorPart = script.Parent.AutoDoor.Door:WaitForChild("Door")
local doorPrimaryPart = script.Parent.PrimaryPart
local tweenInfo = TweenInfo.new(
0.2,
Enum.EasingStyle.Sine,
Enum.EasingDirection.Out,
0,
false,
0
)
local doorOpen = {CFrame = CFrame.new(doorPart.CFrame.X, doorPart.Primary.CFrame.Y+10, doorPart.CFrame.Z)}
local doorClosed = {CFrame = CFrame.new(doorPart.CFrame.X, doorPart.Primary.CFrame.Y, doorPart.CFrame.Z)}
local tweenOpen = TweenService:Create(doorPart, tweenInfo, doorOpen)
local tweenClosed = TweenService:Create(doorPart, tweenInfo, doorClosed)
script.Parent.DoorHitbox.Touched:Connect(function(hit)
tweenOpen:Play()
task.wait(1)
tweenClosed:Play()
end)
end
return doorOpen
(My apologies for the server code being long right now, I will move it into a module later. First two are in ServerScriptService, the DoorOpening script is inside the door.)
I can supply more information as needed. Thank you!
