7.7 KiB
7.7 KiB
Camera Screen Adaptation System
Adapts your 2D orthographic camera to different aspect ratios while keeping gameplay/UI elements aligned to screen edges. Includes a reference marker for target content width and utilities for edge anchoring.
Table of Contents
- What This Solves
- Architecture at a Glance
- Quick Start (Code-First)
- Components
- Common Case Studies
- Tips & Best Practices
- Troubleshooting / FAQ
- Paths & Namespaces
- Change Log
What This Solves
- Consistent horizontal framing across devices: a fixed target world-space width always fits the screen.
- Stable world-space margins from the physical screen edges for placing HUD/world elements.
- Works with both a regular
CameraandCinemachine'sCinemachineCamera.
Architecture at a Glance
- Reference:
ScreenReferenceMarkerdefinestargetWidthand world-space margins (topMargin,bottomMargin,leftMargin,rightMargin). - Adapter:
CameraScreenAdaptercomputes orthographic size fromtargetWidthand aspect and applies it to the controlled camera. EmitsOnCameraAdjusted. - Anchoring:
EdgeAnchorpositions objects relative to the computed screen edges using the same marker margins.
Quick Start (Code-First)
Create and Wire Components in Code
using AppleHillsCamera;
using UnityEngine;
public class CameraAdaptationBootstrap : MonoBehaviour
{
[SerializeField] private Camera mainCamera; // assign in inspector or find at runtime
private void Awake()
{
// 1) Create/locate the marker
var markerGO = new GameObject("ScreenReferenceMarker");
var marker = markerGO.AddComponent<ScreenReferenceMarker>();
marker.targetWidth = 16f; // your desired world-space width
marker.topMargin = 1f; // tune margins for your HUD
// 2) Set up the adapter on your camera
var adapter = mainCamera.gameObject.AddComponent<CameraScreenAdapter>();
adapter.referenceMarker = marker;
adapter.adjustOnStart = true;
adapter.adjustOnScreenResize = true;
// 3) Anchor a sample HUD object to the top edge
var hud = GameObject.CreatePrimitive(PrimitiveType.Quad);
var anchor = hud.AddComponent<EdgeAnchor>();
anchor.referenceMarker = marker;
anchor.anchor = EdgeAnchor.AnchorEdge.Top;
anchor.additionalOffset = 0.25f; // extra spacing from the top margin
anchor.continuousUpdate = true; // keep tracking when aspect changes
}
}
Manual Recalculate / Listen for Changes
using AppleHillsCamera;
using UnityEngine;
public class CameraAdaptationHooks : MonoBehaviour
{
[SerializeField] private CameraScreenAdapter adapter;
private void OnEnable()
{
// Listen when the camera size is applied
adapter.OnCameraAdjusted += OnAdjusted;
}
private void OnDisable()
{
adapter.OnCameraAdjusted -= OnAdjusted;
}
public void ForceRecalculateNow()
{
adapter.AdjustCamera();
}
private void OnAdjusted()
{
Debug.Log("Camera adjusted to match target width.");
// Reposition custom elements if you don’t use EdgeAnchor
}
}
Components
ScreenReferenceMarker
Defines the reference sizes and margins used by both the adapter and anchors.
Key fields:
targetWidth(float): world-space width that should fully fit the viewport.topMargin,bottomMargin,leftMargin,rightMargin(float): world-space distances from the corresponding screen edges.- Scene gizmos: visualizes width line, screen rectangle, and margin guides in the editor.
Typical setup:
- Place at the world-space center of your playable area or camera focus.
- Tune margins to match your HUD/world layout needs.
CameraScreenAdapter
Computes and applies orthographic size to a Camera or CinemachineCamera so that the screen horizontally fits targetWidth.
Highlights:
- Fields:
referenceMarker,adjustOnStart,adjustOnScreenResize. - Event:
OnCameraAdjustedfires after a size update. - Works with built-in
Camera(must be orthographic) or withCinemachineCamera.
Formula:
orthoSize = (targetWidth / 2f) * (Screen.height / Screen.width).
Public helpers:
AdjustCamera()— recalculate and apply now.GetControlledCamera()— returns the underlyingCamerainstance.
EdgeAnchor
Anchors a Transform to a chosen screen edge using the same marker margins.
Common fields (names based on code):
referenceMarker(ScreenReferenceMarker)anchor(EdgeAnchor.AnchorEdge):Top,Bottom,Left,RightadditionalOffset(float): extra spacing beyond the margincontinuousUpdate(bool): update every frame and on camera adjustments
Usage tips:
- Use
continuousUpdatefor elements that must track aspect changes at runtime. - Combine with local offsets/parenting for precise UI/HUD placements in world space.
Common Case Studies
HUD Top Bar (safe top margin)
- Set
marker.topMarginto the vertical padding you want from the top edge. - Add
EdgeAnchorto your top bar root:
anchor.anchor = EdgeAnchor.AnchorEdge.Top;
anchor.additionalOffset = 0.1f; // small breathing room
- Keep
continuousUpdate = truefor device rotation/platform switches.
Side Buttons (left/right margins)
- For a left button column:
anchor.anchor = EdgeAnchor.AnchorEdge.Left;
anchor.additionalOffset = 0.2f;
- Mirror for right side with
Right. - Adjust
marker.leftMargin/rightMarginto push them inward safely.
Cinemachine Virtual Camera
- Add
CameraScreenAdapterto the GameObject withCinemachineCamera. - The adapter detects Cinemachine and writes to
Lens.OrthographicSize. - Everything else (margins and
EdgeAnchor) works the same.
Tips & Best Practices
- Pick a
targetWidththat matches the core gameplay area horizontally; verify extremes (16:9, 19.5:9, 4:3). - Prefer
EdgeAnchorfor HUD/world labels instead of manual scripts—anchors auto-update on resize and onOnCameraAdjusted. - For one-off bespoke layouts, listen to
OnCameraAdjustedand move objects yourself. - Ensure regular cameras are set to
orthographic; the adapter warns if not.
Troubleshooting / FAQ
- My camera didn’t change size:
- Ensure
referenceMarkeris assigned. - For built-in
Camera, confirmorthographicis enabled. - If using Cinemachine, verify the component is
CinemachineCameraon the same GameObject.
- Ensure
- Anchored objects are offset oddly:
- Check
additionalOffsetand your object’s pivot/bounds. - Verify marker margins and that the marker sits at the world center you expect.
- Check
- It works in Play but gizmos look wrong in Scene:
- Scene gizmos approximate using Scene/Game view sizes; rely on Play Mode for truth.
Paths & Namespaces
- Scripts:
Assets/Scripts/AppleHillsCamera/ScreenReferenceMarker.csCameraScreenAdapter.csEdgeAnchor.cs
- Namespace:
AppleHillsCamera
Change Log
- v1.1: Added Table of Contents, code-first snippets, case studies, and aligned terms with actual APIs (
OnCameraAdjusted, Cinemachine support). - v1.0: Original overview and setup guide.