function raycast(n,F,C,a)local E,l,O=raycastRecursive(n,F,C,a,C.unit,dot(F,C.unit))if dot(l,C)>0 then l=-l end return E,F+O*C,l.unit,O end function raycastRecursive(n,F,C,a,E,l)if n.className=="\080\097\114\116"or n.className=="\083\101\097\116"or n.className=="\083\112\097\119\110\076\111\099\097\116\105\111\110"then local O=n.Size.magnitude/2 local i=dot(n.Position,E)-l if i+O>0 and(i-O<C.magnitude and(((i*E+F)-n.Position).magnitude<O and a(n)))then local a=n.Size/2 if n.Shape==Enum.PartType.Ball then local E,l=getLineSphereCollide(F,C,n.Position,a.x)if E<1 and E>=0 then return n,(E*C+F)-n.Position,E else return nil,Vector3.new(0,0,0),1 end elseif n.Shape==Enum.PartType.Block then local E=1 local l=n.CFrame-n.Position local O=l*Vector3.new(1,0,0)local i=l*Vector3.new(0,1,0)local f=l*Vector3.new(0,0,1)local A=-dot(O,C)local g=-dot(i,C)local p=-dot(f,C)local G,T,M,K,I,y=-1 local w=dot(O,F-n.Position)if A~=0 then G=(w-a.x)/A T=(w+a.x)/A if T<G then local n=G G=T T=n end else if math.abs(w)<a.x then T=1 G=0 else return nil,Vector3.new(0,0,0),1 end end local u=dot(i,F-n.Position)if g~=0 then M=(u-a.y)/g K=(u+a.y)/g if K<M then local n=M M=K K=n end else if math.abs(u)<a.y then K=1 M=0 else return nil,Vector3.new(0,0,0),1 end end local D=dot(f,F-n.Position)if p~=0 then I=(D-a.z)/p y=(D+a.z)/p if y<I then local n=I I=y y=n end else if math.abs(D)<a.z then y=1 I=0 else return nil,Vector3.new(0,0,0),1 end end if G<=K and(T>=M and(G<=y and(T>=I and(I<=K and y>=M))))then local F=O local C=G if M>C then C=M F=i end if I>C then C=I F=f end if C>=0 and C<1 then E=C elseif T>0 and(K>0 and(y>0 and C<0))then E=0 F=Vector3.new(0,0,0)end return n,F,E else return nil,Vector3.new(0,0,0),1 end else local E=1 local l=n.CFrame-n.Position local O=l*Vector3.new(1,0,0)local i=-dot(O,C)local f,A=-1 local g=dot(O,F-n.Position)if i~=0 then f=(g-a.x)/i A=(g+a.x)/i if A<f then local n=f f=A A=n end else if math.abs(g)<a.x then A=1 f=0 else return nil,Vector3.new(0,0,0),1 end end local p=l:pointToObjectSpace(C)*Vector3.new(0,1,1)local G=n.CFrame:pointToObjectSpace(F)*Vector3.new(0,1,1)local T,M=getLineSphereCollide(G,p,Vector3.new(0,0,0),a.y)if f<=M and(A>=T and M>0)then local F=O local C=f if T>C then C=T F=l*(G+p*C)end if C>=0 and C<1 then E=C elseif A>0 and(M>0 and C<0)then E=0 F=Vector3.new(0,0,0)end return n,F,E else return nil,Vector3.new(0,0,0),1 end return nil,Vector3.new(0,0,0),1 end end return nil,Vector3.new(0,0,0),1 elseif n.className=="\077\111\100\101\108"or n.className=="\087\111\114\107\115\112\097\099\101"or n.className=="\072\097\116"or n.className=="\084\111\111\108"then local O=n:GetChildren()local i=1 local f=Vector3.new(0,0,0)local A=nil for n=1,#O,1 do if O[n]~=nil then local g,p,G=raycastRecursive(O[n],F,C,a,E,l)if G<i then i=G A=g f=p end end end return A,f,i else return nil,Vector3.new(0,0,0),1 end end

function raycast(model, start, vector, brickFunction)
	local hit, normal, time = raycastRecursive(model, start, vector, brickFunction, vector.unit, dot(start, vector.unit))
	if (dot(normal, vector) > 0) then
		normal = -normal
	end
	return hit, start + time * vector, normal.unit, time
end
function raycastRecursive(model, start, vector, brickFunction, unitVec, startDist)
	if (model.className == "Part") or (model.className == "Seat") or (model.className =="SpawnLocation") then
		local range = model.Size.magnitude / 2
		local dist = dot(model.Position, unitVec) - startDist
		if (dist + range > 0) and (dist - range < vector.magnitude) and ((dist * unitVec + start - model.Position).magnitude < range) and brickFunction(model) then
			local halfSize = model.Size / 2
			if (model.Shape == Enum.PartType.Ball) then
				local time, timeMax = getLineSphereCollide(start, vector, model.Position, halfSize.x)
				if (time < 1) and (time >= 0) then
					return model, (time * vector + start - model.Position), time
				else
					return nil, Vector3.new(0, 0, 0), 1
				end
			elseif (model.Shape == Enum.PartType.Block) then
				local time = 1
				local cf = model.CFrame - model.Position
				local xvec = cf * Vector3.new(1, 0, 0)
				local yvec = cf * Vector3.new(0, 1, 0)
				local zvec = cf * Vector3.new(0, 0, 1)
				local xspd = -dot(xvec, vector)
				local yspd = -dot(yvec, vector)
				local zspd = -dot(zvec, vector)
				local xmin, xmax, ymin, ymax, zmin, zmax = -1
				local dotProd = dot(xvec, start - model.Position)
				if (xspd ~= 0) then
					xmin = (dotProd - halfSize.x) / xspd
					xmax = (dotProd + halfSize.x) / xspd
					if (xmax < xmin) then
						local swap = xmin
						xmin = xmax
						xmax = swap
					end
				else
					if (math.abs(dotProd) < halfSize.x) then
						xmax = 1
						xmin = 0
					else
						return nil, Vector3.new(0, 0, 0), 1
					end
				end
				local dotProd = dot(yvec, start - model.Position)
				if (yspd ~= 0) then
					ymin = (dotProd - halfSize.y) / yspd
					ymax = (dotProd + halfSize.y) / yspd
					if (ymax < ymin) then
						local swap = ymin
						ymin = ymax
						ymax = swap
					end
				else
					if (math.abs(dotProd) < halfSize.y) then
						ymax = 1
						ymin = 0
					else
						return nil, Vector3.new(0, 0, 0), 1
					end
				end
				local dotProd = dot(zvec, start - model.Position)
				if (zspd ~= 0) then
					zmin = (dotProd - halfSize.z) / zspd
					zmax = (dotProd + halfSize.z) / zspd
					if (zmax < zmin) then
						local swap = zmin
						zmin = zmax
						zmax = swap
					end
				else
					if (math.abs(dotProd) < halfSize.z) then
						zmax = 1
						zmin = 0
					else
						return nil, Vector3.new(0, 0, 0), 1
					end
				end
				if (xmin <= ymax) and (xmax >= ymin) and (xmin <= zmax) and (xmax >= zmin) and (zmin <= ymax) and (zmax >= ymin) then
					local normal = xvec
					local min = xmin
					if (ymin > min) then
						min = ymin
						normal = yvec
					end
					if (zmin > min) then
						min = zmin
						normal = zvec
					end
					if (min >= 0) and (min < 1) then
						time = min
					elseif (xmax > 0) and (ymax > 0) and (zmax > 0) and (min < 0) then
						time = 0
						normal = Vector3.new(0, 0, 0)
					end
					return model, normal, time
				else
					return nil, Vector3.new(0, 0, 0), 1
				end
			else	--	Cylinder
				local time = 1
				local cf = model.CFrame - model.Position
				local xvec = cf * Vector3.new(1, 0, 0)
				local xspd = -dot(xvec, vector)
				local xmin, xmax = -1
				local dotProd = dot(xvec, start - model.Position)
				if (xspd ~= 0) then
					xmin = (dotProd - halfSize.x) / xspd
					xmax = (dotProd + halfSize.x) / xspd
					if (xmax < xmin) then
						local swap = xmin
						xmin = xmax
						xmax = swap
					end
				else
					if (math.abs(dotProd) < halfSize.x) then
						xmax = 1
						xmin = 0
					else
						return nil, Vector3.new(0, 0, 0), 1
					end
				end

				local relVec = cf:pointToObjectSpace(vector) * Vector3.new(0, 1, 1)
				local relPos = model.CFrame:pointToObjectSpace(start) * Vector3.new(0, 1, 1)
				local rmin, rmax = getLineSphereCollide(relPos, relVec, Vector3.new(0, 0, 0), halfSize.y)
				if (xmin <= rmax) and (xmax >= rmin) and (rmax > 0) then
					local normal = xvec
					local min = xmin
					if (rmin > min) then
						min = rmin
						normal = cf * (relPos + relVec * min)
					end
					if (min >= 0) and (min < 1) then
						time = min
					elseif (xmax > 0) and (rmax > 0) and (min < 0) then
						time = 0
						normal = Vector3.new(0, 0, 0)
					end
					return model, normal, time
				else
					return nil, Vector3.new(0, 0, 0), 1
				end
				return nil, Vector3.new(0, 0, 0), 1
			end
		end
		return nil, Vector3.new(0, 0, 0), 1
	elseif (model.className=="Model") or (model.className=="Workspace") or (model.className=="Hat") or (model.className == "Tool") then
		local children=model:GetChildren()
		local time=1
		local normal=Vector3.new(0, 0, 0)
		local hit=nil
		for n = 1, #children do
			if children[n]~= nil then
				local newHit, newNormal, newTime = raycastRecursive(children[n], start, vector, brickFunction, unitVec, startDist)
				if (newTime < time) then
					time = newTime
					hit = newHit
					normal = newNormal
				end
			end
		end
		return hit, normal, time
	else
		return nil, Vector3.new(0, 0, 0), 1
	end
end