Table of Contents

Using the Public API

The OrbitalCameraSystem has many public properties which can be set from other scripts/components in your project. These would primarily be used to allow a player to change the settings on the camera system, based on their preferences. You would need to implement your own preferences menu if you wish the player to be able to fx. invert camera movement, or toggle edge-scrolling on/off.

The script also has a bunch of Public Methods that can be called from other scripts. These will primarily be used to animate the camera to a new position. This animation might be triggered by a cutscene, or a special event in your game (like a fire or a wedding). It could also be a result of the user clicking on a minimap or pressing a Go to home button.

In this section I'll give some examples of how to use the public methods.

Communicating with the OrbitalCameraSystem

To be able to invoke methods on the OrbitalCameraSystem, you'll need a reference to this script in your other script. The easiest way to achieve this is to create a Serializable private field, and just drag your scene's OrbitalCam into that slot. If this is not possible, consider using dependency injection or use GetComponentInParent on Camera.main to get the OrbitalCameraSystem component.

Note

If using the GetComponentInParent approach, it would be advisable to cache a reference to the component in a variable during Awake or Start.

Public Properties

The Public Properties are visible in the documentation. Their names correspond to the fields in All Controls Explained.

Movement, Rotation & Zoom

The following methods can be used to instantly set the camera to a new position, rotation, or zoom distance:

Instant change

Animated change

The following methods can be used to animate the camera to a new position, rotation, or zoom distance:

Note

The second argument is the animation time in seconds. This is optional, and will otherwise use the default animation time set in the Speeds controls section.

Multiple animations of different types can be executed simultaneously (fx. a movement and a zoom animation). If custom timing is provided, they will all use the timing provided last. All animations will thus end at the same time.

Multiple animations of the same type cannot be executed simultaneously. Only the last one will be applied. To string together multiple animations with a delay in between, you would need to use a Coroutine or similar asynchronous approach.

Animation Timing

The default animation time is set in the Speeds section of the OrbitalCameraSystem.

The animation time can also be controlled on each of the animation methods. It's always the second argument, optional, and given as a float. If none is given, the default is used.

Easing

Each animated method also takes an optional EasingType as its third argument:

  • EasingType.Linear: constant velocity.
  • EasingType.EaseIn: accelerates from rest.
  • EasingType.EaseOut: decelerates to rest.
  • EasingType.EaseInOut: accelerates then decelerates (smoothstep). This is the default.

State snapshot

Capture the camera state (position, Y-rotation, tilt, and zoom distance) into an OrbitalCameraState struct. Restore the snapshot later to recreate the same view, instantly. The struct is [Serializable] and works with JsonUtility, so you can also use it for save/load.

Note

Follow target is not saved with the snapshot. Transform references don't survive serialization, so save the target's identity yourself (a unit ID, a scene GUID) and call SetFollowTarget after SetState once you've resolved the transform on load.

See the Save and Load example and the View Presets example.

Special Feature: Follow a target

Special Feature: Pause player input

It enables or disables every InputAdapter in the camera's children in one call. Use it during cutscenes or scripted sequences when you don't want the player to interfere. The scripted camera methods still work. Re-enable with SetInputEnabled(true) when the sequence finishes.

The camera runs on real (unscaled) time, so pausing your game with Time.timeScale = 0 does not stop camera control - that's deliberate, players might expect to look around a paused RTS. If you want the camera frozen too, call SetInputEnabled(false) on pause and SetInputEnabled(true) on resume, and avoid issuing animated API calls while paused unless you actually want them to play.

See the Pause Player Input example.

Interaction state and events

You can read what the player is currently doing with the camera, and get notified when a drag starts or ends. This is what the Custom Cursors component uses to swap the cursor, but you can use it for anything, fx. a sound while panning, a hint that fades in the first time someone orbits, or hiding your UI while a drag is happening.

State you can read at any time:

  • IsDragPanning - true while the player is dragging to pan. It stays false while a follow target is set, since pan input is ignored then.
  • IsDragOrbiting - true while dragging to rotate and tilt.
  • IsEdgeScrolling and EdgeScrollDirection - whether the pointer is in an edge-scroll margin, and which way it's pushing. The direction is a Vector2 with each axis being -1, 0, or 1, so the diagonals are covered too.
  • IsZoomTransitioning and ZoomDirection - whether the zoom is currently changing, and which way. ZoomDirection is positive when zooming out, negative when zooming in.
  • PointerScreenPosition and IsPointerPositionAvailable - the pointer position in screen pixels, from whichever input is active (mouse or touch).

Events for the start and end of a drag:

Subscribe in OnEnable and unsubscribe in OnDisable, as you would with any C# event.

Note

If you disable input mid-drag with SetInputEnabled(false), the matching ...Ended event still fires, so you won't get stuck thinking a drag is still going.

Examples