So i have this funny local script here which loops through a folder…
local WindowsModuleRequirer = require(script.System.MainModule)
ActiveRooms = script.ROOMS_FOLDER.Value
local ImageQuality = 50
local DefaultRadius = 100
local Player = game.Players.LocalPlayer
if not Player.PlayerGui:FindFirstChild("FAKE_WINDOWS") then
local GUI_Folder = Instance.new("Folder")
GUI_Folder.Name = "FAKE_WINDOWS"
GUI_Folder.Parent = Player.PlayerGui
end
while task.wait(1) do
for a , Room in pairs(ActiveRooms:GetChildren()) do
if Room:FindFirstChild("WINDOWS") then
for Room, WindowInRoom in ipairs(Room.WINDOWS:GetChildren()) do
local WindName = WindowInRoom.FAKE_WINDOW_DISPLAY:FindFirstChild("WINDOW_ROOM_TYPE")
local Visibility = WindowInRoom.FAKE_WINDOW_DISPLAY:FindFirstChild("Visibility")
if WindName and WindName:IsA("StringValue") then
local Controller = WindowsModuleRequirer.Setup(DefaultRadius, WindName.Value)
if (WindowInRoom.FAKE_WINDOW_DISPLAY.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).Magnitude < DefaultRadius then
local Exists = false
for a, b in ipairs(Player.PlayerGui.FAKE_WINDOWS:GetChildren()) do
if b.Adornee ~= WindowInRoom.FAKE_WINDOW_DISPLAY then
Exists = false
else
Exists = true
end
end
if not Exists then
local AddedWindow = Controller:AddWindow(WindowInRoom.FAKE_WINDOW_DISPLAY,ImageQuality)
if Visibility and Visibility:IsA("NumberValue") then
Controller:SetAllTransparency(Visibility.Value)
else
Controller:SetAllTransparency(0.5)
end
task.wait()
AddedWindow:ToggleRunning(true)
else
warn("does exist already")
end
end
end
end
end
if Room:FindFirstChild("BIG_WINDOWS") then
for Room, WindowInRoom in ipairs(Room.BIG_WINDOWS:GetChildren()) do
local WindName = WindowInRoom.FAKE_WINDOW_DISPLAY:FindFirstChild("WINDOW_ROOM_TYPE")
local Visibility = WindowInRoom.FAKE_WINDOW_DISPLAY:FindFirstChild("Visibility")
if WindName and WindName:IsA("StringValue") then
local Controller = WindowsModuleRequirer.Setup(DefaultRadius, WindName.Value)
if (WindowInRoom.FAKE_WINDOW_DISPLAY.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).Magnitude < DefaultRadius then
local Exists = false
for a, b in ipairs(Player.PlayerGui.FAKE_WINDOWS:GetChildren()) do
if b.Adornee ~= WindowInRoom.FAKE_WINDOW_DISPLAY then
Exists = false
else
Exists = true
end
end
if not Exists then
local AddedWindow = Controller:AddWindow(WindowInRoom.FAKE_WINDOW_DISPLAY,ImageQuality)
if Visibility and Visibility:IsA("NumberValue") then
Controller:SetAllTransparency(Visibility.Value)
else
Controller:SetAllTransparency(0.5)
end
task.wait()
AddedWindow:ToggleRunning(true)
else
warn("does exist already")
end
end
end
end
end
end
end
and then here is the modulescript
local services = {
run = game:GetService("RunService"),
players = game:GetService("Players"),
gui = game:GetService("GuiService"),
light = game:GetService("Lighting")
}
local modules = script.Parent:WaitForChild("Modules")
local rooms = script.Parent.Parent:WaitForChild("Rooms")
local utils = require(modules:WaitForChild("Utilities"))
local types = require(modules:WaitForChild("Types"))
local player = services.players.LocalPlayer
local XZ = Vector3.new(1, 0, 1)
local YZ = Vector3.new(0, 1, 1)
local UNIT_NZ = Vector3.new(0, 0, -1)
local Y_SPIN = CFrame.fromEulerAnglesXYZ(0, math.pi, 0)
local data = {}
data.__index = data
local windowObject = {}
windowObject.__index = windowObject
function data.Setup(Radius:number, RoomsType:string?):types.Controller
assert(typeof(Radius)=="number", "radius must be a number.")
assert(typeof(RoomsType)=="string" or not RoomsType,"roomsType must be a string or nil.")
local self = setmetatable({},data)
self.Disconnect = Instance.new("BindableEvent")
self.MaxRadius = Radius
if RoomsType then
local roomFolder = rooms:FindFirstChild(RoomsType)
assert(roomFolder,"Invalid rooms type: ",RoomsType)
self.Rooms = roomFolder:GetChildren()
else
self.Rooms = {}
for _,v in pairs(rooms:GetDescendants()) do
if not v:IsA("Model") then
continue
end
table.insert(rooms,v)
end
end
local function renderFrame()
local camera = workspace.CurrentCamera
if not camera then
return
end
local windowObjects = {}
for _,windowData in pairs(self.Windows) do
table.insert(windowObjects,windowData.Base)
end
local camFrame = camera.CFrame
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = windowObjects
local foundObjects = workspace:GetPartBoundsInRadius(camFrame.Position,self.MaxRadius,params)
if not foundObjects then
return
end
for _,windowData in pairs(self.Windows) do
if not windowData.Running then
continue
end
local object = windowData.Base
local otherCamera = windowData.Camera
if not object or not otherCamera then
local find = table.find(self.Windows,object)
if not find then
continue
end
table.remove(self.Windows,find)
continue
end
local find = table.find(foundObjects,object)
if not find then
continue
end
local distance = (object.Position-camFrame.Position).Magnitude
if distance>=self.MaxRadius-1 then
windowData.Gui:Destroy()
continue
end
local surface,surfaceSize = utils.getSurfaceInfo(object)
local relative = surface:ToObjectSpace(camFrame)
if relative.Z>0 then
windowData.Gui:Destroy()
continue
end
local screenPosition,cameraRelative = utils.worldToScreenPoint(camera,surface)
local cameraRelativeRotation = Vector3.new(cameraRelative:ToOrientation())
local isBehind = math.abs(math.deg(cameraRelativeRotation.Y))<(1500/camera.FieldOfView+18)--some cheap math
if isBehind then
windowData.Gui:Destroy()
continue
end
local screenSize = utils.worldToScreenSize(camera,surface.Position,surfaceSize.Magnitude)
--print(screenPosition)
local isInside = utils.isCircleVisible(screenPosition,screenSize/2,camera)
if not isInside then
windowData.Gui:Destroy()
continue
end
windowData.Viewport.ImageTransparency = 0 --utils.lerp((distance/(self.MaxRadius-1)),1,windowData.Visibility)
windowData.Gui.Enabled = true
local origin = windowData.RoomOrigin
local newCamCF = origin*Y_SPIN*relative
local data = utils.computeCamData(
newCamCF,
origin*Y_SPIN,
surfaceSize,
camera
)
for property,value in pairs(data) do
otherCamera[property] = value
end
end
end
self.Windows = {}
if workspace.CurrentCamera then
self.MainRunner = workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):Connect(renderFrame)
end
self.SecondaryRunner = workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()
if not workspace.CurrentCamera then
self.MainRunner:Disconnect()
return
end
self.MainRunner = workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):Connect(renderFrame)
end)
return self
end
function data:AddWindow(WindowPart:BasePart,Quality:number?):types.WindowObject
local self:types.self = self
local newData = {}
local seed:number = math.floor(math.cos(WindowPart.Position.Magnitude)*100000)
local random:Random = Random.new(seed)
local currentAmbient = services.light.Ambient
local surface = Instance.new("SurfaceGui")
surface.Name = "FAKE_WINDOW_GUI"
local IdentifyValue = Instance.new("ObjectValue")
IdentifyValue.Value = WindowPart
IdentifyValue.Parent = WindowPart
surface.Parent = player.PlayerGui:WaitForChild("FAKE_WINDOWS")
surface.ResetOnSpawn = false
surface.Adornee = WindowPart
surface.Face = Enum.NormalId.Front
surface.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
surface.PixelsPerStud = Quality or 1024
surface.ClipsDescendants = true
surface.LightInfluence = 0
surface.MaxDistance = self.MaxRadius
local camera = Instance.new("Camera")
camera.Parent = surface
camera.CameraType= Enum.CameraType.Scriptable
local viewport = Instance.new("ViewportFrame")
viewport.Parent = surface
viewport.CurrentCamera = camera
viewport.Size = UDim2.fromScale(1,1)
viewport.Position = UDim2.fromScale(0,0)
viewport.AnchorPoint = Vector2.zero
viewport.BackgroundTransparency = 1
viewport.ImageTransparency = 0
viewport.LightColor = script.LightColor.Value
viewport.LightDirection = -services.light:GetSunDirection()
viewport.Ambient = script.Ambient.Value --Color3.new((currentAmbient.R+1)/2,(currentAmbient.G+1)/2,(currentAmbient.B+1)/2)
local newRoom = self.Rooms[random:NextInteger(1,#self.Rooms)]:Clone()
newRoom.Parent = viewport
newData.Camera = camera
newData.Base = WindowPart
newData.RoomOrigin = newRoom.PrimaryPart.CFrame
newData.Viewport = viewport
newData.Running = true
newData.Visibility = 0
newData.Gui = surface
newRoom.PrimaryPart:Destroy()
table.insert(self.Windows,newData)
local self = setmetatable({},windowObject)
self.connections = {}
self._data = newData
self.self = self
table.insert(self.connections,services.light.LightingChanged:Connect(function(sky)
if sky then
return
end
local currentAmbient = services.light.Ambient
viewport.LightDirection = -services.light:GetSunDirection()
viewport.Ambient = Color3.new((currentAmbient.R+1)/2,(currentAmbient.G+1)/2,(currentAmbient.B+1)/2)
end))
return self
end
function windowObject:ToggleRunning(Enabled:boolean?)
local self:types.windowSelf = self
if typeof(Enabled)~="boolean" then
Enabled = not self._data.Running
end
local Enabled:boolean = Enabled::boolean
self._data.Running = Enabled
end
function windowObject:ToggleVisible(Enabled:boolean?)
local self:types.windowSelf = self
if not self.Viewport then
return warn("Viewport not found.")
end
if typeof(Enabled)~="boolean" then
Enabled = not self.Viewport.Visible
end
local Enabled:boolean = Enabled::boolean
self.Viewport.Visible = Enabled
end
function windowObject:SetTransparency(Transparency:number)
local self:types.windowSelf = self
assert(typeof(Transparency)=="number", "amnt must be a number.")
self._data.Visibility = Transparency
self._data.Gui.LightInfluence = Transparency/2
self._data.Gui.Brightness = 10*(1-Transparency)
end
function windowObject:Disconnect()
local self:types.windowSelf = self
local find = table.find(self.self.Windows,self._data)
if not find then
return warn("Already disconnected.")
end
table.remove(self.self.Windows,find)
for _,connection:RBXScriptConnection in pairs(self.connections) do
connection:Disconnect()
end
end
function data:RunOnAll(handler:(self:{_data:types.WindowInfo, self:types.self},any)->(),...:any)
local self:types.self = self
for _,data:types.WindowInfo in pairs(self.Windows) do
handler({_data = data,self = self},...)
end
end
function data:Disconnect()
local self:types.self = self
if not self.MainRunner.Connected then
return
end
self.MainRunner:Disconnect()
self.SecondaryRunner:Disconnect()
self.Disconnect:Fire()
end
function data:ChangeMaxRadius(Radius:number)
local self:types.self = self
self.MaxRadius = Radius
self:RunOnAll(function(self2)
local data:types.WindowInfo = self2._data
data.Gui.MaxDistance = Radius
end)
end
function data:ToggleAllRunning(Enabled:boolean?) self:RunOnAll(windowObject.ToggleRunning,Enabled) end
function data:ToggleAllVisible(Enabled:boolean?) self:RunOnAll(windowObject.ToggleVisible,Enabled) end
function data:SetAllTransparency(Transparency:number) self:RunOnAll(windowObject.SetTransparency,Transparency) end
function data:DisconnectWindows()self:RunOnAll(windowObject.Disconnect) end
local data:{Setup: typeof(data.Setup)} = data
return data
and the problem is that i want the GUI objects to destroy if you lok away or are too far away (more than max radius). can someone edit the scripts so i know how to do that?