Skip to the content.

Impossible Odds Logo Impossible Odds - Tactical Camera

The Impossible Odds Tactical Camera package provides a plugin camera system for smoothly navigating your environments in both a top-down tactical view as well as up-close action scenes.

You can expect to find the following set of features in this plugin:

You can view a quick demo video of this plugin below.

Impossible Odds - Tactical Camera

Prerequisites & installation

The most straight forward option to grab the latest published package available from Github here. This will include the required C# Toolkit as well.

Another installation option is to use Unity’s package manager. Add the following git-tracked URLs to your project:

Quick Camera Setup

If you want to get started quickly without being bothered with all the details, then follow these few steps:

  1. Add the TacticalCamera component to your Camera GameObject. This will also add a CharacterController component to it.
  2. Apply settings by picking a TacticalCameraSettings data object from your project. You can play around with the different values to make it feel/behave differently. The package comes with one already defined for you to use.
  3. Finally, add the TacticalCameraInputProvider component to it and assign it to the TacticalCamera component. Feel free to adjust the key bindings in a way that you see fit.
  4. Optionally, add some bounds in which the camera is allowed to operate and assign it to the TacticalCamera component. The TacticalCameraBoxBounds component restricts it to an axis-aligned box.

That’s it!

Quick Camera Setup

Note: remember to check out the tooltips in the inspector if something is not clear!

Detailed Camera Setup

The Tactical Camera plugin has a central component that does all the heavy lifting: TacticalCamera. It will also add a CharacterController component on there which it uses to detect collisions as well as move smoothly over any terrain and objects.

The component requires a few additional data objects to operate correctly:

Optionally, the camera can also be equipped with a component that restricts its area of operation so that it can’t move outside of your game world.

Tactical Camera Component

Input Provider

The input provider for the Tactical Camera instructs where the camera should go to and where to look at. Input is of course very project-dependent and there is no “one size fits all”-solution, e.g. mouse & keyboard versus gamepad versus touch screen, etc. That’s why this camera is designed to be driven using an interface-component rather than forcing a single solution on you. However, a sample implementation of an input provider is given by the TacticalCameraInputProvider component. It’s designed for use with mouse and keyboard and allows you to assign which keys and axes should be used to control the movement and rotation.

Input Provider

Note: remember to check out the tooltips in the inspector if something is not clear!

Input Provider - Advanced

The ITacticalCameraInputProvider interface is the key to hooking the Tactical Camera system in your custom input code. Either have your input object implement this interface as well to pass it along to the Tactical Camera directly, or provide an abstraction layer for this interface in your input code.

The interface expects you to implement the following features:

Note: the ITacticalCameraInputProvider interface in itself does not define which particular input method is used, e.g. moving using the keyboard versus the mouse cursor against the edge of the screen. The implementing class should define which methods are supported by way of returning appropriate values.

Settings

The Tactical Camera’s behaviour is driven by a data object that tells it how fast it can move and rotate, as well as how smooth it comes to a standstill and how its movement is affected by altitude. The TacticalCameraSettings is the ScriptableObject that holds this data. It can be created through the Unity create menu: Assets → Create → Impossible Odds → Tactical Camera → new Tactical Camera Settings.

You can adjust the values in this object to suit the environment the camera will operate in, but sensible default values have already been set for a small-to-medium sized map. This object operates using value ranges and animation curves. The choice for using animation curves allows to visually define how a specific value should fade out, or how a value should transition from one end to the other, e.g. the movement speed versus the altitude of the camera.

The settings object also allows to set some world-interaction values which might be of particular interest for performance reasons:

Settings

Note: remember to check out the tooltips in the inspector if something is not clear!

Settings - Advanced

Compared to the input provision, this implementation of settings is immediately usable in a broad set of projects. Nonetheless, if you want to further alter or customize the behavior, the ITacticalCameraSettings interface is what you should look into.

This interface will ask you to implement the following:

Most of these properties are self-explanatory, but the purpose of the of evaluation methods might not be immediately clear. Each of these methods take a float value as input in the range of [0, 1]. The output of these methods can be exactly the same as their input value in case a linear transition is desirable, but it can also be transformed to create a more pleasant looking/feeling result, e.g. a smooth roll-off in case of fading, or an ease-in, ease-out in case of transitions. In the implementation of TacticalCameraSettings, this is done by evaluating animation curves which naturally lend themselves to this.

Area of Operation

In most situations it’s desirable to restrict the camera to a specific area so that it can’t wander off in areas not meant for the players to visit. The Tactical Camera can equipped with some bounds that force it to be in a particular area.

How such an area is defined is very project-dependent and could become a complex matter. For example, polygonal level bounds in case the map is not just a square, or a fog-of-war restriction where undiscovered pieces of the map may not be accessible yet.

To give a basic form of restriction already, the TacticalCameraBoxBounds component can restrict the Tactical Camera’s position to an axis-aligned box. Whenever it tries to leave the area, its position is reset to the nearest valid location inside the box.

Box Bounds

Area of Operation - Advanced

To have the Tactical Camera be restricted to more complex areas, have your restriction tool implement the ITacticalCameraBounds interface. This has a single Apply method which will get called by the Tactical Camera once it has done moving.

Your implementation of this Apply method should check whether the camera is still in a valid location, and if not, place it somewhere that is. Preferably this would be the closest valid point inside to minimise the distance which would otherwise create weird visual jumps.

Dependency Injection

The external resources the Tactical Camera system requires to operate can all be assigned through Unity’s inspector view or through your own scripts. Additionally, you can also have them delivered by the Dependency Injection framework from the Impossible Odds C# Toolkit. It allows you to inject resources and values into objects that require them to operate, which makes managing resources in your project easier.

The TacticalCamera component’s properties for the input provider, settings and bounds are all marked for injection in case you prefer to work using this system as well.

Gotcha’s

When using the Tactical Camera system you might run into a few limits of the system as well. You’ll find them listed here:

Example

Check out the demo scene for a complete setup and demonstration of how the camera behaves in different circumstances. This scene is setup using the dependency injection method, i.e. the resources the camera needs are injected upon Start from the TacticalCameraDemo component.

Unity Version

Developed and tested on Unity 2019.4 LTS.

License

This package is provided under the MIT license.