How would I go about making a free cam script with boundaries?

I have already taken a show at doing this myself, but it works horribly, if not at all. Here is the free cam code I have:

UIS.InputBegan:connect(function(Input, GPE)
    	if not GPE then
    		if Input then
    			if Editing then
    				if EditCam == true and PlotRegion3 then
    					if Input.KeyCode == Enum.KeyCode.W then WDown = true end
    					if Input.KeyCode == Enum.KeyCode.A then ADown = true end
    					if Input.KeyCode == Enum.KeyCode.S then SDown = true end
    					if Input.KeyCode == Enum.KeyCode.D then DDown = true end
    				end
    			end
    		end
    	end
    end)

    UIS.InputEnded:connect(function(Input, GPE)
    	if not GPE then
    		if Input then
    			if Editing then
    				if EditCam == true and PlotRegion3 then
    					if Input.KeyCode == Enum.KeyCode.W then WDown = false end
    					if Input.KeyCode == Enum.KeyCode.A then ADown = false end
    					if Input.KeyCode == Enum.KeyCode.S then SDown = false end
    					if Input.KeyCode == Enum.KeyCode.D then DDown = false end
    				end
    			end
    		end
    	end
    end)

    RunService.RenderStepped:connect(function()
    	if EditCam then
    		if Editing then
    			if PlotRegion3 then
    				if WDown then
    					if CheckIfCamIsInRegion3(PlotRegion3) then
    						Cam.CFrame = Cam.CFrame + Vector3.new(-0.15,0,0)
    					else
    						Cam.CFrame = Cam.CFrame + Vector3.new(0.15,0,0)
    					end
    				end
    				if ADown then
    					if CheckIfCamIsInRegion3(PlotRegion3) then
    						Cam.CFrame = Cam.CFrame + Vector3.new(0,0,0.15)
    					else
    						Cam.CFrame = Cam.CFrame + Vector3.new(0,0,-0.15)
    					end
    				end
    				if SDown then
    					if CheckIfCamIsInRegion3(PlotRegion3) then
    						Cam.CFrame = Cam.CFrame + Vector3.new(0.15,0,0)
    					else
    						Cam.CFrame = Cam.CFrame + Vector3.new(-0.15,0,0)
    					end
    				end
    				if DDown then
    					if CheckIfCamIsInRegion3(PlotRegion3) then
    						Cam.CFrame = Cam.CFrame + Vector3.new(0,0,-0.15)
    					else
    						Cam.CFrame = Cam.CFrame + Vector3.new(0,0,0.15)
    					end
    				end
    			end
    		end
    	end
    end)

The freecam system itself works fine, but the problem is with the boundary system. When you would reach a bounary, your camera would glitch. Does anyone know a more efficient method?

EDIT: Some variables are missing from the code I gave, this is just a snippet of the full script because I don’t want to release the entire thing.

3 Likes

Hm. How about just doing

if  PlotRegion3 then
     local NewCFrame = Cam.CFrame * CFrame.new(((DDown and 1 or 0) - (ADown and  1 or 0)) * 0.15, 0, ((WDown and 1 or 0) - (SDown and 1 or 0)) * 0.15)
     if CheckCamIsInRegion3(PlotRegion3, NewCFrame) then -- edit function to not take cframe from cam but as argument
          Cam.CFrame = NewCFrame
     end
end

So…
Vectors specify location as X Y X. If you want to also hold angle you rather use cframes. Also if you want to make camera go forward or backward you should not use CFrame + Vector3 cuz it increses just the X Y Z location witheout angle. If you do CFrame + CFrame then you increase the location regarding the angle - if the rotation is 90* so object is looking at X then if you do CFrame(0, 0, 5) it won’t increase it by Vector3(0, 0, 5) but Vector3(5, 0, 0), cause Z means forward and the object faces at X

I’ll try fix that script before doing anything with it. The amount of errors lol

Huh. You’r current script also can be optimized - you use unneccesary region3 check 4 times when you dont need to. This function is really expensive so try to calculate new position and doing it once instead.

Sidenote: You can write code blocks like you do in discord to make them easier to read. Use 3 backticks (The ones near the top right of your keyboard) and then the name of the language (Lua). End your code block with 3 backticks as well.

```lua
-- code goes here
-- don't forget 3 backticks to finish off.

Nvm. Works. Thanksss. I was always using 2 side notes and I didn’t know that I have to do 3.

Or you can select the code and press the “</>” button at the top.

About that - not on pc.

Oh.

The problem still occurs, and your script doesn’t work too well. When you hit the border, the camera would get stuck and you cant move it at all.

EDIT: I know why it’s happening, just not how to fix it.

Anyways, I gtg for tonight. I’ll be on tomorrow.

Hm. Could you contact me on discord so I will take a better look on pc tomorrow? DevKurka#4093

With the original script, does the actual border checking work? (i.e the camera can’t actually go any further?)

Glitch as in what exactly? Stop working? Move around erratically?
How about camera interpolation? This can make movement of the camera a lot smoother and perhaps help if the problem itself is erratic movement.

Assuming that the minimum corner of your region3 is minCorner and its maximum corner is maxCorner, then this should be as simple as clamping the position of the camera after you update its position.

At the end of your RenderStepped loop:

local minCorner = < The min corner of your region 3 >
local maxCorner = < The max corner of your region 3 >
local camPos = Cam.CFrame.p
Cam.CFrame = CFrame.new(Vector3.new(), Cam.CFrame.lookVector) + Vector3.new(
    math.clamp(camPos.X, minCorner.X, maxCorner.X),
    math.clamp(camPos.Y, minCorner.Y, maxCorner.Y),
    math.clamp(camPos.Z, minCorner.Z, maxCorner.Z)
)

I also noticed that you’re not using DeltaTiming to move your camera. This means that players with lower frame rates would move slower. I would recommend using BindToRenderStep instead since callbacks bound to RenderStep receive a delta time (time since last frame). You can then multiply this deltaTime with the camera’s velocity at every step.

6 Likes

The RenderStepped event has this delta also, his event handler just isn’t using it. If the goal is constant, framerate-independent velocity, then yes, you want to use this.

The problem with the original code is the direction reversal when crossing the boundaries. That is always going to cause the camera to vibrate across the boundary point. The correct behavior is what @XAXA shows: to clamp the position of the camera to the boundary value and stop it there. Instead of a fixed step each frame, if the remaining distance to the boundary is less than the step size, just clamp the step to the remaining distance (or snap the position to the boundary value, these are equivalent).

1 Like

Thanks, I havn’t ever made anything like this, so it’s a first for me.

It worked, thanks!

2 Likes