Door tweening/generation issues

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!

1 Like
cf = CFrame.new(newPiece.PrimaryPart.Position) * CFrame.Angles(math.rad(0),math.rad(newPiece.PrimaryPart.Orientation.Y), math.rad(newPiece.PrimaryPart.orientation.Z))

Instead of using CFrame.Angles you can just move the position upwards instead of rotating using Vector3.new(…)

If you mean what’s in line 39 and 95 of RoomGen, that doesn’t affect the doors. The rooms aren’t meant to be moved up, they need to rotate the way they do.

The only scripts that directly control the doors functionality are DoorGeneration and DoorOpening

these properties do not copy the inital rotation of the doors, you created a cframe that only took the position (X, Y, Z), thus resetting the rotation given by cloneDoor:PivotTo(spawner.CFrame)

in short, you forgot to cframe the rotation as you should be doing so:

local oldCFrame = CFrame.new()
local newCFrame = {CFrame = CFrame.new(oldCFrame.X, oldCFrame.Y, oldCFrame.Z) * oldCFrame.Rotation}
1 Like

Ah, I understand. Where/how would I implement this into the script(s)?

Edit: I messed around with it but still couldn’t find a way to get it to work.

local doorOpen = {CFrame = CFrame.new(doorPart.CFrame.X, doorPart.Primary.CFrame.Y+10, doorPart.CFrame.Z) * door.CFrame.Rotation}
local doorClosed = {CFrame = CFrame.new(doorPart.CFrame.X, doorPart.Primary.CFrame.Y, doorPart.CFrame.Z) * door.CFrame.Rotation}`
1 Like

Thank you! It worked perfectly!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.