I made a working door script, but I feel like it can be more optimized, organized, and all around better.
local RunService = game:GetService("RunService") ;
local CollectionService = game:GetService("CollectionService") ;
local TweenService = game:GetService("TweenService") ;
local PromptUsed = script.Remotes.PromptUsed
local function TweenDoor(Side, Tweeninfo, Cframe)
assert(Side:IsA("Model"), string.format("Side: %s is not a model.", Side.Name))
assert(Cframe ~= nil, "Cframe: CFrame has no value.")
TweenService:Create(
Side.PrimaryPart,
Tweeninfo,
{CFrame = Side.Primary.CFrame * Cframe}
):Play() ;
end ;
local function Weld(Side: Model)
for _, Parts in pairs(Side:GetChildren()) do
if Parts:IsA("BasePart") and (Parts ~= Side.PrimaryPart) then
local Weld = Instance.new("WeldConstraint") ;
Weld.Part0 = Parts ;
Weld.Part1 = Side.PrimaryPart ;
Weld.Parent = Parts ;
end ;
end ;
end ;
local function CheckRank(Player, GroupID, Prompt)
assert(Player ~= nil, string.format("Player: %s is not a player.", Player.Name))
assert(type(GroupID) == "number", "GroupID: GroupID is not a number.")
local DoorID = Prompt.Parent:GetAttribute("Rank") ;
if Player:GetRankInGroup(GroupID) >= DoorID then
return true ;
else
return false ;
end ;
end ;
local Door = {} ;
Door.__index = Door ;
function Door.Init()
local self = setmetatable({}, Door) ;
self.TweenInfo = TweenInfo.new(
1,
Enum.EasingStyle.Linear,
Enum.EasingDirection.Out
) ;
self.GroupID = 12903725 ;
if RunService:IsClient() then
self.Player = game.Players.LocalPlayer ;
self:PromptFired() ;
else
self:WeldPrimary() ;
PromptUsed.OnServerEvent:Connect(function(Player, Type)
self:Open(Type) ;
end)
end ;
return self ;
end ;
function Door:WeldPrimary()
for _, Prompt in pairs(CollectionService:GetTagged("DoorDetection")) do
local Type = Prompt.Parent ;
if Type.Name == "Door" then
Weld(Type.SideL) ;
end
if Type.Name == "DoubleDoor" then
Weld(Type.SideL) ;
Weld(Type.SideR) ;
end ;
end ;
end ;
function Door:PromptFired()
for _, Prompt in pairs(CollectionService:GetTagged("DoorDetection")) do
Prompt.ProximityPrompt.Triggered:Connect(function()
local Rank = CheckRank(self.Player, self.GroupID, Prompt) ;
if Rank then
PromptUsed:FireServer(Prompt.Parent)
else
game:GetService("StarterGui"):SetCore("SendNotification", {
Title = "Warning",
Text = "Not ranked high enough",
Icon = "rbxassetid://8877073449",
Duration = 2
}) ;
end ;
end) ;
end ;
end ;
function Door:Open(Type)
assert(Type:IsA("Model"), string.format("Side: %s is not a model.", Type.Name))
local CurrentState = Type:GetAttribute("Opened") ;
if Type.Name == "Door" and not CurrentState then
Type:SetAttribute("Opened", true) ;
TweenDoor(Type.SideL, self.TweenInfo, CFrame.new(-3.5, 0, 0)) ;
elseif Type.Name == "Door" and CurrentState then
Type:SetAttribute("Opened", false) ;
TweenDoor(Type.SideL, self.TweenInfo, CFrame.new(3.5, 0, 0)) ;
end ;
if Type.Name == "DoubleDoor" and not CurrentState then
Type:SetAttribute("Opened", true) ;
TweenDoor(Type.SideL, self.TweenInfo, CFrame.new(-3.5, 0, 0)) ;
TweenDoor(Type.SideR, self.TweenInfo, CFrame.new(3.5, 0, 0)) ;
elseif Type.Name == "DoubleDoor" and CurrentState then
Type:SetAttribute("Opened", false) ;
TweenDoor(Type.SideL, self.TweenInfo, CFrame.new(3.5, 0, 0)) ;
TweenDoor(Type.SideR, self.TweenInfo, CFrame.new(-3.5, 0, 0)) ;
end ;
end ;
return Door ;