Skip to content
This repository was archived by the owner on Jun 11, 2020. It is now read-only.
This repository was archived by the owner on Jun 11, 2020. It is now read-only.

OOP design on the RootCamera breaks several standards. #158

@Quenty

Description

@Quenty

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)

  • Event disconnect and connection (Should be handled by a Maid class).
  • Input across the following device types
    • Gamepad
    • Touch
    • Mouse
    • Mouse with MouseLock
    • KeyBoard
  • Camera Offset based 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 children

Children/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.Camera

Allowing 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 Tracking or Following cameras are not easily implemented with my smoothly gliding camera.
  • Reduce dependencies
    • The RootCamera does not depend upon child components. This is good.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions