How to check if camera is within a region

I’m not entirely sure how to check if the players camera is within a certain range of a part. I’m trying to create an effect where if you walk close to a building, music slowly starts to become louder, and as you walk away it fades out. I’ve got it setup to detect if the camera is in water to create a pitch shift in the sounds, however, I’m unsure about parts.

while wait() do
	local Position = Camera.CFrame.Position
	
	local Min = Vector3.new(Position.X + Offset, Position.Y + Offset, Position.Z + Offset)
	local Max = Vector3.new(Position.X - Offset, Position.Y - Offset, Position.Z - Offset)
	
	local Region = Region3.new(Max, Min)
	Region = Region:ExpandToGrid(4)
	if Region then
		-- Check if player is in water
		local Material = workspace.Terrain:ReadVoxels(Region, 4)
		for i, v in pairs(SoundService:GetDescendants()) do
			if v:IsA('EqualizerSoundEffect') or v:IsA('PitchShiftSoundEffect') then
				v.Enabled = Material[1][1][1] == Enum.Material.Water
			end
		end
		
		-- Check if player is close to the nightclub
		for _, v in pairs(Regions:GetChildren()) do
		
		end
	end
end

‘Regions’ is a folder, containing at the moment just this part -


Not sure if this is the best practice. My idea was to check if the camera was within this part and thus do the music stuff

5 Likes

Hello @NinjoOnline!

The way you can check if the Camera is within a Part is using Magnitude, the way I actually did it was I got the Camera.CFrame.Position then I added a while loop in the LocalScript to constantly check if the Camera is still close/within the given part. If it was I printed that it was within the Part.

Now, if you would like to check the Part material, you can use Part.Material and check if it is the desired material, then you would run a different function from others.

I hope my reply helped, if there is any problems with my answer or if you are confused on something then please let me know and I will be more than willing to assist further. Below you can find the script I made to further help you with your issue.

Cheers and take care,
Bruce

CameraMagnitude.rbxl (18.0 KB)

1 Like

Doesn’t seem to work consistently :confused:

If I keep moving around it might print a few times here and there

But it isn’t a constant flow of prints while the camera is inside

For regions in specific you can check if the camera position is within the min and max bounds of the part. For exampe using the the function from this post, you should be able to just do something like:


function IsInRegion(Pos,A,B)
 return (Pos.X < math.max(A.X,B.X) and Pos.X > math.min(A.X,B.X)) and (Pos.Y < math.max(A.Y,B.Y) and Pos.Y > math.min(A.Y,B.Y)) and (Pos.Z < math.max(A.Z,B.Z) and Pos.Z > math.min(A.Z,B.Z))
end

local Camera = game.Workspace.CurrentCamera
local Min ----   For parts Min is  Part.CFrame * -(Part.Size * .5)
local Max ----   For parts Max is Part.CFrame * (Part.Size * .5)

while true do
 wait(.1)
  if IsInRegion(Pos,Min,Max) then
	print("Camera is within Region!")
  end
end

For parts in specific one way you can detect if the camera is inside the part especially if they need to be rotated, (if they don’t, then just checking the min and max is more efficient ) is by using some vector projection to check if the camera’s position is within the part, by using what’s described on a StackOverFlow post, here :

local function PointInPart(Point,Cube)
	local Size = Cube.Size * .5
	local CF = Cube.CFrame
	local B1 = CF * Vector3.new(Size.X, -Size.Y, -Size.Z)
    local B2 = CF * -Size
    local B3 = CF *  Vector3.new(-Size.X, -Size.Y, Size.Z)
    local T1 = CF * Vector3.new(Size.X, Size.Y, -Size.Z)
 	
	Point = CFrame.new(Cube.Position):VectorToObjectSpace(Point)

	local DirX = B1 - B2
   	local SizeX = DirX.Magnitude 
	DirX = DirX/DirX.Magnitude 

	local DirY = B3 - B2
	local SizeY = DirY.Magnitude 
	DirY= DirY/SizeY
	
	local  DirZ = T1 - B1
	local SizeZ = DirZ.Magnitude
	DirZ = DirZ/SizeZ
	
	local DirVec = Point - Cube.Position

	local X = math.abs(DirVec:Dot(DirX) * 2) <= SizeX
	local Y = math.abs(DirVec:Dot(DirY) * 2) <= SizeY
	local Z = math.abs(DirVec:Dot(DirZ) * 2) <= SizeZ
  return  X and Y and Z
end

local Camera = game.Workspace.CurrentCamera
local Region = game.Workspace.Region

while true do
 wait(.1)
  if PointInPart(Camera.CFrame.Position, Region) then
	print("Camera is within Part!")
  end
end

Edit: Because i’m guessing your regions don’t move you can cache the size and position results for later use


5 Likes

That’s exactly what putting a sound in a part is for.

Hey @NinjoOnline,

I apologise for my unhelpful solution before. I did some researching, and I was able to find a very good alternative, I did not create the Script, all credits go to the rightful owner below. I think you might be interested in the answer I found on a seperate website, and, I think you may find it very helpful. You can find it below alongside the place I put it to use in to fix your issue!

Let me know if I can assist you with anything further,
Bruce

CheckCamera.rbxl (18.2 KB)

1 Like

now how exactly do i see if its out of the part?

Well, you would use a boolean statement for that. Assuming you went purely based off of the answer that the other user wrote inside of that scripting helpers post, you could do something like below to check. I hope this helped.

function PointInPart(point, part)
	point = part.CFrame:pointToObjectSpace(point)
	return math.abs(point.X) <= part.Size.X / 2
		and math.abs(point.Y) <= part.Size.Y / 2
		and math.abs(point.Z) <= part.Size.Z / 2
end

game:GetService("RunService").RenderStepped:Connect(function()
	local cameraInPart = PointInPart(workspace.CurrentCamera.CoordinateFrame.p, game:GetService("Workspace"):WaitForChild("YourPartNameHere"))

	if cameraInPart then
		print("The Camera is inside of the part!")
	else
		print("The Camera is not inside of the part!")
	end
end)

forgot i asked this, either way thanks. i’ve instead just checked if the partname is nil. but either way i really appreciate it.

No problem, feel free to mark this thread as solved if help is no longer required so other users can find the solution if they run into the same question.

1 Like