Naturally, just locking the camera will not get the effect you are searching for, but a good start is to look into the CameraType property of Camera.
By default, it is set to Enum.CameraType.Custom. You can try using Enum.CameraType.Scriptable as a good start.
Or, if you want to maintain the properties of the default Camera, you can use RenderStepped, an event in RunService, and override the CoordinateFrame property.
RenderStepped triggers every frame per client, so that means that if you hook up Camera transitions to RenderStepped they will happen smoothly based upon client frame rate.
Do be aware that if you use this RenderStepped method with Enum.CameraType.Custom, you need to allocate all positional changes to the Camera to CameraOffset, a property in Humanoid, and give all orientation changes to CoordinateFrame. Recall that you can derive rotation of some CFrame cf with cf - cf.pand derive position of some CFrame cf with cf.p. Assuming that the variable camera points to the client's camera, and the variable humanoidRootPart points to the client's HumanoidRootPart, and the variable humanoid points to the client's Humanoid, and the variable cf points to your target CFrame value, your function will look something like this to apply the Camera manipulation...
local cameraRootFrame = humanoidRootPart.CFrame:toWorldSpace(CFrame.new(0, 1.5, 0))
humanoid.CameraOffset = cameraRootFrame:toObjectSpace(cf).p
camera.CoordinateFrame = CFrame.new(camera.CoordinateFrame.p):toWorldSpace(cf - cf.p)
I do however believe that the best approach is to use Enum.CameraType.Scriptable. If you do that, you can completely avoid using the CameraOffset and just set CFrame manually. However, if you don't feel confident enough with CFrame to try this out on your own, you should try the above method.
Hope this was somewhat useful. Regardless, you should practice this on your own and experiment to get the most out of this!
Edit: Oh yes, and there is this really nice Camera method named Interpolate. I feel that Interpolate sacrifices control in favor of ease-of-use, but if it fulfills your goal then you should go ahead and take a shot at using it (and yes, it is really easy to use)!