The final piece of the camera system is comprised of the Unity-specific behavior, or all lifetime methods within the MonoBehaviour pipeline. The first part of the system described separating out concerns of our business logic from that which diverges the often chaotic View out on its own. In the end, we will end up with two uniquely functioning entities within timings of their own that Strange manages for us so we don’t have to worry about cluttering all spaces of our app into Unity scripts.

When the time comes that we need to adjust view related behavior, we have peace of mind that it already comes insulated for us so that any adverse effects do not pop up elsewhere and go unnoticed; so long as we are also properly unit testing, in the case that this does happen, it will be caught quickly as a regression.

Demo Scene

Download Sources

Provided along with this series is an updated *.unitypackage including all source and demo files. If you would like to just view the sources, they are also available and kept up-to-date on GitHub.

Mediator Setup

Setting up the Mediator, we need to inject our dependencies of the Model and View and listen for certain Signals that will be dispatched throughout the app.

Once the CameraStateSignal is dispatched, we will catch it here once we start listening for it to update Model state and perform the necessary View operation. In the demo, we check for either cinematic or character state; cinematic will start our example flythrough, character will simply clamp the camera to the target defined in the editor.

Waypoint Flythrough

When the camera switches to cinematic mode via the sequenced Signal, we will loop through all the waypoints set in the Model and through a coroutine, will interpolate between the waypoint’s from to to position and rotation over the specified duration. Technically, one could also move this coroutine into the View itself and send a finished Signal when completely done, however I felt it seemed better to keep in the Mediator because of the direct reliance on the Model. Later on, you will notice the View is kept to singly responsible, simple methods.

View Setup

It should be reiterated that the Mediator serves as a bridge between our business and view logic. Since the MonoBehaviour loop is volatile in nature, any unrelated segments that can be split out should be handled in the Mediator. Therefore, the remaining pieces the View is comprised of will look rather familiar to a Unity programmer:

Update Loop

Achieving a cinematic flythrough which switches to an ever-updating character clamped view will require implementation passed through an Update function; more specifically: LateUpdate, suggested by Unity as:

LateUpdate is called after all Update functions have been called. This is useful to order script execution. For example a follow camera should always be implemented in LateUpdate because it tracks objects that might have moved inside Update.

This is perfect for our case: a camera following a target, which will be controlled by player input or other components such a respawning or a moving platform, that the camera doesn’t necessarily care about how it’s moving, just that it keeps up with it.

Waypoint Flythrough

The first LateUpdate controlled behavior is the cinematic flythrough. We will constantly update the camera position and rotation with a smoothed linear or spherical interpolation.

Character Demo Controls

Once switching into the character mode, each LateUpdate will make sure the camera clamps, at a certain speed and forgiveness, both the position and rotation as well. For the demo, we secure this to a classic (30°/45°) isometric rotation at a certain distance (X/Z) and height (Y).

That pretty much sums up what we need for the Unity side. Not too complex, everything has a single responsibility, and we don’t clutter it with all the implementation details that could have been tossed in here that now reside with the middle-man, the Mediator. If that doesn’t convince you of the organizational benefits and simplicity of Strange, I’m not sure what will!

Demo Controls

Demo Controls

The demo features a set of controls that the user can adjust to see (in real time) how the camera operates and updates per frame. These settings include:

  • Mode: Cinematic Mode: List of waypoints that can be clicked to perform the animation again. Character Mode: Includes the following options:
  • Camera Distance: How far away (X/Z) the camera resides from the target.
  • Camera Height: How high up (Y) the camera sits from the target.
  • Camera Speed: The speed at which the camera updates relative to the target’s position.
  • LookAt Target: Whether or not the camera should always face the target’s position.
  • Hopefully this series has provided some insight into a real-life example of how powerful and beneficial an IoC abstraction of Unity can be with a framework such as Strange. I would love to revisit this series in the future to throw together a third part covering behavior testing this side of the testing pyramid, giving us 100% coverage.

    << View Part I of A Strange Camera System in Unity