-- UNIVERSAL PART SETTINGS local partThickness = 0.2 local collidableParts = false -- RAY PART SETTINGS local rayVisualColor = BrickColor.new("Bright red") local rayLifetime = 1 -- set to nil for infinity local rayTransparency = 0.5 -- REGION3 PART SETTINGS local region3PointColor = BrickColor.new("Bright blue") local region3PointLifetime = 1 local facingPoints = true -- rotates the points to face towards each other local acceptCFrames = true -- converts CFrames into positions if desired by using CFrame.Position -- REGION 3 BOX SETTINGS local region3BoxTransparency = 0.6 -- from 0 to 1, the transparency of the box when created local region3BoxColor = BrickColor.new("Baby blue") -- LINK BEAM SETTINGS local beamWidth = 1 -- default is 1 local faceCamera = false -- default is false local beamColor3 = Color3.fromRGB(255, 255, 255) -- Must be a Color3 value local beamTransparency = 0.5 -- default is 0.5 local customTexture = nil -- decal ID that is optional for the beam of your choice, can be nil local attachmentsVisible = false -- makes attachments visible if wanted local beamLifeTime = 2 -- set to nil for infinity -- WORLD ATTACHMENT LIFETIME SETTING local attachmentVisibilityResetTimer = 1 -- how long to turn back attachments back to their previous visible value, set to nil for never -- RECORD THE SETTINGS AND MAKE THEM CHANGEABLE: local settingsTable = { ["partThickness"] = partThickness, ["collidableParts"] = collidableParts, ["rayVisualColor"] = rayVisualColor, ["rayLifetime"] = rayLifetime, ["rayTransparency"] = rayTransparency, ["region3PointColor"] = region3PointColor, ["region3PointLifetime"] = region3PointLifetime, ["facingPoints"] = facingPoints, ["acceptCFrames"] = acceptCFrames, ["region3BoxTransparency"] = region3BoxTransparency, ["region3BoxColor"] = region3BoxColor, ["beamWidth"] = beamWidth, ["faceCamera"] = faceCamera, ["beamColor3"] = beamColor3, ["beamTransparency"] = beamTransparency, ["customTexture"] = customTexture, ["attachmentsVisible"] = attachmentsVisible, ["attachmentVisibilityResetTimer"] = attachmentVisibilityResetTimer, } -- CODE: local debris = game.Debris local debugger = {} local function getReferencePropertyForColor(value) return typeof(value) == "Color3" and "Color" or typeof(value) == "BrickColor" and "BrickColor" end local function createUsingMagnitude(from, to, mag, parentTo, transparency, color) local part = Instance.new("Part") part.Anchored = true part.CanCollide = settingsTable["collidableParts"] part.Transparency = transparency part.Size = Vector3.new(partThickness, partThickness, mag) part.CFrame = CFrame.new(from, to) * CFrame.new(0, 0, -mag/2) local referenceProperty = getReferencePropertyForColor(color) assert(type(referenceProperty) == "string", "Invalid color property argument. Must be Color3 or BrickColor!") part[referenceProperty] = color part.Parent = parentTo return part end function debugger:RayVisual(fromPosition, endPosition, magnitude) if not magnitude then magnitude = (fromPosition - endPosition).Magnitude end local rayVisual = createUsingMagnitude(fromPosition, endPosition, magnitude, workspace, settingsTable["rayTransparency"], settingsTable["rayVisualColor"]) local getRayLifetime = settingsTable["rayLifetime"] if getRayLifetime ~= nil then debris:AddItem(rayVisual, getRayLifetime) end end function debugger:RaycastFunc(ray, raycastFunctionName, ...) local part, pos, normal = workspace[raycastFunctionName](workspace, ray, ...) debugger:RayVisual(ray.Origin, pos) return part, pos, normal end function debugger:FindPartOnRaycast(ray, ignoreDescendants, ...) debugger:RaycastFunc(ray, "FindPartOnRaycast", ignoreDescendants, ...) end function debugger:Region3Visual(corner1, corner2) assert(typeof(corner1) ~= "Region3", "You must use the positions from the Region3 instead of a Region3. Use :Region3Box instead if you need to use a box of the Region3.") local assertVector3 = typeof(corner1) == "Vector3" and typeof(corner2) == "Vector3" if not settings["acceptCFrames"] then assert(assertVector3, "You must use Vector3 values.") else local typeofCorner1 = typeof(corner1) local typeofCorner2 = typeof(corner2) assert(typeofCorner1 == "Vector3" or typeofCorner1 == "CFrame", "You must use a CFrame or Vector3 value for the first parameter of :RayVisual.") assert(typeofCorner2 == "Vector3" or typeofCorner2 == "CFrame", "You must use a CFrame or Vector3 value for the first parameter of :RayVisual.") if typeofCorner1 == "CFrame" then corner1 = corner1.Position end if typeofCorner2 == "CFrame" then corner2 = corner2.Position end end local collidableValue = settingsTable["collidableParts"] local part1 = Instance.new("Part"); local part2 = Instance.new("Part") part1.Anchored, part2.Anchored = true, true part1.CanCollide, part2.CanCollide = collidableValue, collidableValue if not facingPoints then part1.Position = corner1.Position part2.Position = corner2.Position else part1.CFrame = CFrame.new(corner1.Position, corner2.Position) part2.CFrame = CFrame.new(corner2.Position, corner1.Position) end local region3Color = settingsTable["region3PointColor"] local colorProperty = getReferencePropertyForColor(region3Color) part1[colorProperty], part2[colorProperty] = region3Color, region3Color part1.Parent, part2.Parent = workspace, workspace local partLifetime = settingsTable["region3PointLifetime"] debris:AddItem(part1, partLifetime) debris:AddItem(part2, partLifetime) end function debugger:Region3Box(region3Value) assert(typeof(region3Value) == "Region3", "You must use a Region3 value for :Region3Box.") local part = Instance.new("Part") part.Anchored = true part.CanCollide = false part.Size = region3Value.Size part.CFrame = region3Value.CFrame part.Transparency = settingsTable["region3BoxTransparency"] part[getReferencePropertyForColor(region3PointColor)] = settingsTable["region3PointColor"] part.Parent = workspace end function debugger:Region3PointsValid(corner1, corner2) -- Region3.new(min, max) assert(typeof(corner1) == "Vector3", "Expected Vector3, got "..typeof(corner1)) assert(typeof(corner2) == "Vector3", "Expected Vector3, got "..typeof(corner2)) return (corner1.X < corner2.X and corner1.Y < corner2.X and corner1.Z < corner2.Z) end function debugger:BasicNumericTable(Table) local startingText = "{" for i = 1, #Table do startingText = startingText..tostring(Table[i])..", " end startingText = startingText.."}" print(startingText) end function debugger:LinkPartToPart(part1, part2, beamParent) local attachment1, attachment2 = Instance.new("Attachment"), Instance.new("Attachment") attachment1.CFrame = CFrame.new(0, 0, -part1.Size.Z/2) attachment2.CFrame = CFrame.new(0, 0, -part2.Size.Z/2) attachment1.Parent, attachment2.Parent = part1, part2 if settings["attachmentsVisible"] then attachment1.Visible, attachment2.Visible = true, true end if not beamParent or type(beamParent) ~= "userdata" then local random = math.random(1, 2) if random == 1 then beamParent = attachment1 else beamParent = attachment2 end end local beam = Instance.new("Beam") beam.Attachment0, beam.Attachment1 = attachment1, attachment2 beam.Transparency = settingsTable["beamTransparency"] local getBeamWidth = settingsTable["beamWidth"] beam.Width0, beam.Width1 = getBeamWidth, getBeamWidth beam.FaceCamera = settingsTable["faceCamera"] local textureID = settingsTable["customTexture"] if textureID or string.match(textureID, "[^%s]") then beam.Texture = customTexture end beam.Color = beamColor3 beam.Parent = beamParent local lifetimeForBeam = settingsTable["beamLifeTime"] if beamLifeTime ~= nil then debris:AddItem(beam, lifetimeForBeam) debris:AddItem(attachment1, lifetimeForBeam) debris:AddItem(attachment2, lifetimeForBeam) end end function debugger:AnimationIsPlaying(humanoid, animation) for _, v in pairs(humanoid:GetPlayingAnimationTracks()) do if animation:IsA("AnimationTrack") and v == animation then return true elseif animation:IsA("Animation") and v.Animation == animation then return true end end return false end function debugger:AllAttachmentsVisible() local Table local timer = settingsTable["attachmentVisibilityResetTimer"] if timer ~= nil then Table = {} end for _, v in pairs(workspace:GetDescendants()) do if v:IsA("Attachment") and v.Visbile ~= true then if Table then table.insert(Table, v) end v.Visible = true end end if Table then delay(timer, function() if #Table > 0 then for _, v in pairs(Table) do v.Visible = false end end end) end end function debugger:ChangeSettings(value) assert(type(value) == "table", "Changing settings requires a table") local boolean for i, v in pairs(value) do if settingsTable[i] then boolean = true settingsTable[i] = v end end if not boolean then warn("Table used to change settings did not have any values correlated to the settings. Possible typos or no values?") end end function debugger:ChangeSetting(settingName, settingNew) assert(settingName ~= nil, "Setting name parameter is nil.") assert(settingNew ~= nil, "New setting value parameter is nil.") local getSetting = settingsTable[settingName] assert(getSetting ~= nil, "Setting called "..settingName.." does not exist.") settingsTable[settingName] = settingNew end return debugger