function Invisicam.Update(l)local w={}Behaviors[Mode](w)local Z={}local M={Character}local function I(l)Z[l]=true if not SavedHits[l]then SavedHits[l]=l.LocalTransparencyModifier end end for l,w in pairs(w)do repeat local l=CameraCast(w,M)if l then I(l)for l,w in pairs(l:GetChildren())do if w:IsA("\068\101\099\097\108")or w:IsA("\084\101\120\116\117\114\101")then I(w)end end table.insert(M,l)end until not l end for l,w in pairs(SavedHits)do local M=l.LocalTransparencyModifier if Z[l]then if M<FADE_TARGET then l.LocalTransparencyModifier=math.min(M+FADE_RATE,FADE_TARGET)end else if M>w then l.LocalTransparencyModifier=math.max(w,M-FADE_RATE)else SavedHits[l]=nil end end end end function Invisicam.SetMode(w,l)AssertTypes(l,"\110\117\109\098\101\114")for w,Z in pairs(MODE)do if Z==l then Mode=l return end end error("\073\110\118\097\108\105\100 \109\111\100\101 \110\117\109\098\101\114")end function Invisicam.SetCustomBehavior(w,l)AssertTypes(l,"\102\117\110\099\116\105\111\110")Behaviors[MODE.CUSTOM]=l end

function Invisicam:Update()
	-- Make a list of world points to raycast to
	local castPoints = {}
	Behaviors[Mode](castPoints)
	
	-- Cast to get a list of objects between the camera and the cast points
	local currentHits = {}
	local ignoreList = {Character}
	local function add(hit)
		currentHits[hit] = true
		if not SavedHits[hit] then
			SavedHits[hit] = hit.LocalTransparencyModifier
		end
	end
	for _, worldPoint in pairs(castPoints) do
		repeat
			local hitPart = CameraCast(worldPoint, ignoreList)
			if hitPart then
				add(hitPart)
				for _, child in pairs(hitPart:GetChildren()) do
					if child:IsA('Decal') or child:IsA('Texture') then
						add(child)
					end
				end
				table.insert(ignoreList, hitPart) -- Next ray will go through this part
			end
		until not hitPart
	end
	
	-- Fade out objects that are in the way, restore those that aren't anymore
	for hit, originalFade in pairs(SavedHits) do
		local currentFade = hit.LocalTransparencyModifier
		if currentHits[hit] then -- Fade
			if currentFade < FADE_TARGET then
				hit.LocalTransparencyModifier = math.min(currentFade + FADE_RATE, FADE_TARGET)
			end
		else -- Restore
			if currentFade > originalFade then
				hit.LocalTransparencyModifier = math.max(originalFade, currentFade - FADE_RATE)
			else
				SavedHits[hit] = nil
			end
		end
	end
end

function Invisicam:SetMode(newMode)
	AssertTypes(newMode, 'number')
	for modeName, modeNum in pairs(MODE) do
		if modeNum == newMode then
			Mode = newMode
			return
		end
	end
	error("Invalid mode number")
end

function Invisicam:SetCustomBehavior(func)
	AssertTypes(func, 'function')
	Behaviors[MODE.CUSTOM] = func
end
