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.
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
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.
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.
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).