Camera Chasing Cursor

I’ve been looking at cameras recently, and I stumbled across a cool camera in Minecraft: Story Mode. The video attached below demonstrates the camera I’d like more information about.

Does anyone know what the name of this sort of camera would be, and how this sort of camera could be implemented in Roblox?

Seems like it would be a cool type of camera to use in cutscenes to give it a little bit of interactivity.

4 Likes

Oh, I love title screens that include this.

3 Likes

No idea what this is called, but it seems like this is basically what’s going on:

What's going on

The camera is in a fixed position and orientation, but moving the mouse around the screen makes it rotate a little bit in the direction of the mouses movement. This allows players to move the camera around to see more of the game world at a time, and also provides visual feedback to the player which I think makes it feel more like they’re “in” the game world. Depending on how much the player can pan the camera, it might also be used to let the player “discover” things that are initially out of sight.

Here’s how you might go about it:

Basics of implementation

For any given viewpoint, the overall location can be represented by one CFrame, and the “mouse panning” by another CFrame. If the camera is supposed to switch between different viewpoints, perhaps to show different “shots” as part of a cutscene, you can define each viewpoint while making the game rather than computing it at runtime, which makes things a lot easier.

Keeping track of many different viewpoints

I would do it by physically placing Parts around the game world and tagging them with something like “ViewpointPart”. Parts have their own CFrame property, and since you can actually see them it makes placing them in the game world easier than writing down coordinates. Just make them invisible or parent them to something else than Workspace when the game runs, so they don’t show up in game. I would have the “base” CFrame of each viewpoint be the same as this Parts CFrame. You might also want to limit how far the player can rotate the camera on a per-viewpoint basis, which you can accomplish by putting a CFrameValue object inside the part, and tagging it with something appropriate like “ViewpointMaxChange”. You can then lerp between the initial CFrame of the viewpoint and the initial CFrame changed by however much the maximum change is, depending on how close the players’ mouse is to the edge of the screen (you can do this by simply multiplying the Parts’ CFrame by the “offset” CFrame).

Interface

You’ll most likely want to be able to easily switch between any two viewpoints during the game. I would decouple this from the code that handles putting the camera at the correct CFrame, using BindableEvents and BindableFunctions to let other scripts tell a “ViewpointCamera” script to switch to another viewpoint, without worrying about how that’s done. I imagine an interface like this:

function SwitchToViewpoint(viewpointPart, lerpTime)
    --Smoothly moves the camera from one viewpoint to another
    --The target viewpoint is represented by viewpointPart
    --The camera takes lerpTime seconds to make the switch

function IsSwitching()
    --Returns wether the camera is currently in the process of switching to another viewpoint,
    --    represented with a bool
    --Necessary because you might not want players to be able to click on things (e.g. to open a container,           
    --    or switch to another viewpoint) while the camera is switching to another viewpoint
Me rambling about tangential topics

You might have a different script that handles clicking on things, showing what happens if something is clicked and such. Clicking on a door might move to another scene, so this script can then call the SwitchToViewpoint function. The specific viewpointPart and lerpTime might be represented in a data structure parented to the door itself, or perhaps even a modulescript that knows what should happen when the door is clicked, so your clicking script doesn’t need to know every detail of every scene. A lot of other things than just changing the viewpoint might happen, such as checking if the player has a key, spawning enemies, etc. For this reason, I would probably have a ModuleScript inside every clickable thing, which returns a function that is then called whenever a thing is clicked. This isn’t really about the viewpoint thing though, this is mostly just me rambling :stuck_out_tongue:

Details of implementation

As for the actual implementation, you can use UserInputService:GetMouseLocation to get the X and Y coordinates of the mouse on the screen. You can get “how close to the edge” the mouse is by dividing these coordinates by the size of the players’ screen. The only way I know of getting this is with ScreenGui.AbsoluteSize. This should give you two numbers between -1 and 1 (one for each axis) which you can use as an input to CFrame:lerp, to get the target CFrame that you want the camera to be at. To smoothly (as in, smoothly over time) move the camera from one viewpoint to another, use TweenService. You could also use this to lerp between the current CFrame and the target CFrame over time, so that the camera feels more smooth/less responsive. Regardless, you’ll want to update the target CFrame once every frame, using RunService.RenderStepped. My preferred way of exposing an interface to other scripts is with BindableEvents and BindableFunctions. Mos if not all of this should be handled on the client with LocalScripts, but if you want the server to be able to set the viewpoint, you’ll want to check out RemoteEvents and RemoteFunctions.

Let me know if you need more help with the details of implementing this, specific code examples, etc.

4 Likes

this is very helpful. thank you. I’m looking forward to giving this a go now I know how to go about it :blush: