-
Notifications
You must be signed in to change notification settings - Fork 186
OOP design on the RootCamera breaks several standards. #158
Description
The root camera is trying to do several functions at once, when in reality behavior can be broken into multiple reusable components. This makes modifying the RootCamera (and subsequent versions of cameras) very difficult.
Behaviors the RootCamera handles (which should be separated by Encapsulation)
Eventdisconnect and connection (Should be handled by aMaidclass).Inputacross the following device types- Gamepad
- Touch
- Mouse
- Mouse with MouseLock
- KeyBoard
- Camera
Offsetbased upon humanoid and character state
Breaking up this behavior
Each of these behaviors are interesting, but should not be linked as a core component of the RootCamera.
Base behavior
Rather, the RootCamera should only have the following APIs
function RootCamera:GetCameraLook()
function RootCamera:GetCameraZoom()
function RootCamera:GetCameraActualZoom()
function RootCamera:ViewSizeX() -- Note this method and the one below should start using the camera.ViewportSize
function RootCamera:ViewSizeY()
function RootCamera.new()
function RootCamera:RotateCamera(startLook, xyRotateVector)
function RootCamera:ScreenTranslationToAngle(translationVector)New API
function RootCamera:SetCamera()
function RootCamera:AddChild(ChildModifier)
function RootCamera:RemoveChild(ChildModifier)
function RootCamera:Destroy() -- Removes events, destroys childrenChildren/API suggestion
Currently, the RootCamera has one behavior, but we know this is going to change as ROBLOX goes on.
RootCameras should be extended via children, or some sort of plug-and-chug input or behavior handling items. For example, the current player's character is tracked, and behavior happens when it joins. A class HumanoidTrackingExtension would handle this behavior nicely. The RootCamera could then loop through these behavior classes and update them, et cetera. The following API could occur
function HumanoidTrackingExtension:IsInFirstPerson()
function HumanoidTrackingExtension:CalculateOffset()
function HumanoidTrackingExtension:HandleTransparency()
...
function HumanoidTrackingExtension:Destroy()This sort of behavior should also be done with the input, so input can easily be swapped in mode, and input mode is easy to track and reusable in other camera extensions, instead of creating an inextensible RootCamera that is not extendable. Note that I've suggested that MouseLock and Mouse and Keyboard all be handled differently because these are inherently different input types that change input behavior --> camera behavior.
Another example child would be a InputSystemExtension which selects which input mode to use. At this point, the InputSystemExtension would be able to switch the strategy of input based upon the existing camera mode. These children would interact directly with the RootCamera API calling methods, with the RootCamera knowing of them. This means the RootCamera has * few to no dependencies*
The following variables should also be camera variables
workspace.CurrentCamera --> self.CameraAllowing the camera and other small variables like this to be set means that
Effects of such a change
Although this is a very large refactoring, this also does a lot of things for you
- Lets the script be shorter
- By separating out the code into many modules and child-behaviors, the code is a lot more concise and clear
- Make it more understandable
- It's a lot easier to read 100 lines of code than 1000 lines of code
- Make it more reusable
- Components such as input can easily be reused or even extended to allow players to modify behavior. Making something such as a smoothly animated camera is much easier when you can modify the scrolling and movement APIs and not worry about input.
- If I wanted to create a smooth gliding camera right now, it would require a modification of the RootCamera, not an extension of it. Furthermore, other behaviors such as
TrackingorFollowingcameras are not easily implemented with my smoothly gliding camera.
- Reduce dependencies
- The RootCamera does not depend upon child components. This is good.