Fast-Camera-Systems
Probably the most optimized and fastest Camera you’ll find written for the Roblox engine. Pretty easy to use. Might write up an article explaining the math (if I’m not lazy)…
Get The Module Here!
Github
rbxm
FastCameraSystem.rbxm (13.5 KB)
Model
Fast-Camera-System - Roblox
Camera Modes
Over-The-Shoulder
Top-Down-Camera
Isometric-Camera
Side-Scrolling-Camera
Follow-Mouse
Usage
After downloading the rbxm file, drag it into StarterCharacterScripts.
Code is designed to be pretty self-documenting so documentation is pretty excessive.
local Module = require(script:WaitForChild("CameraSystem")) -- CameraModes should be placed under this.
Module.EnableTopDownCamera() -- Functions are pretty self-documenting
Module.EnableShiftLockCamera() -- etc
Camera mode settings can be adjusted in the Configs
module if needed. Alternatively, if you have other ideas on ways of using my modules, then you can pass the needed configurations through function parameters.
Functions
EnableShiftLockCamera()
DisableShiftLockCamera()
EnableIsometricCamera()
DisableIsometricCamera()
EnableTopDownCamera()
DisableTopDownCamera()
EnableSideScrollingCamera()
DisableSideScrollingCamera()
FollowMouse()
StopFollowingMouse()
FaceCharacterToMouse()
StopFacingMouse()
HeadFollowCamera() -- (Experimental)
StopHeadFollowCamera()
Incentive
Over recent weeks, I’ve spent some time carefully deriving the math for faster cameras that I thought I would like to contribute to the community. As you should know from your game-dev adventures, camera design itself is essential to designing top-quality games. You want to do as much as you can to give your player that immersive feeling they deserve. The math behind cameras can be pretty math-heavy which is something important to consider as that math is coordinated per frame. This is pretty important to take into consideration for performance tolling games or tactical games where FPS is crucial. Currently, the current Roblox camera module doesn’t ideally achieve the speeds it should target. It’s often been looked at as a threshold to performance-needing games and from personal experience of my own performance-heavy mechanics. Optimization itself is compensation for expensive applications-- it’s the path to future-proofing. Thus, with the incentive of building a high-performant camera but also to provide practical camera functionality to the programmers who often find camera math to be challenging.
Design
Purely math-based cameras designed from scratch. Intended to be lightweight and flexible for future-proofing. All the math I wrote is carefully optimized in consideration of modern architectures and in consideration to lower-end architectures like ARM. For those who crave all the slightest optimizations possible, I made a separate CameraModes module (FastCameraModes) but I leave my cautions as readability is sacrificed considerably.
The challenge posed for deriving and writing a fast camera:
- GC footprint: Luau’s GC (garbage collector) is notorious when it comes to cleaning up userdata creation or even table creations that may result in GC Assist instructions which will halt Luau scripts for this extra work needing to be done by the GC.
- Consideration of Luau->C/C++ bridge invocations: Biggest bottleneck Roblox games face. It is extremely expensive to bridge data between C++ and Luau often making calculations in Luau much faster than they could be in C++.
- Optimizing Expensive Calculations: Considering cases where components could cancel out other components and finding shortcut calculations.
- Numerical Stability: Unfortunately, calculations in C++ have more precision than Luau but this is negligible, however, it is important to take into consideration of errors that may stem from this thus designing math to be more numerically robust is something that should always be noted.
- Consideration of current compiler optimizations: It is important to make sure for example that upvalues should stay constant, otherwise, the compiler won’t be able to cache function closures which is a reasonable performance loss. If we can’t cache closures and avoid this, then it is best to cache function constants as upvalues otherwise.
- Further target hardware considerations such as cache locality and branch prediction: Although from the perspective of Luau, the impact is minimal however we can still considerably influence this. When possible, division is avoided and multiplication is favored by multiplying ratios (1/x) instead as this is still faster on ARM but doesn’t hurt other architectures however bypass delays are also taken into consideration as inverse division leads to interleaving integer and floating operations.