UE5 RTS Camera Rotation
RTS camera rotation is one of those features that instantly separates a rough prototype from something that feels intentionally designed. A camera that can move and zoom is useful, but once the player can rotate the view smoothly and reliably, the whole system starts feeling much more complete.
In this tutorial, you will build smooth RTS camera rotation in Unreal Engine 5 using Blueprints and Enhanced Input. You will also fix the zoom direction from the previous setup, clamp zoom distance so it does not become stupid, and then create a proper middle-mouse drag rotation system with clean pitch and yaw separation.
The result is a much more controlled RTS camera that feels predictable instead of messy.
GitHub project files: UE5 RTS Camera Tutorial Repository
Spring Arm documentation: Unreal Engine Spring Arm Docs
Enhanced Input documentation: Enhanced Input Guide
Blueprint documentation: Blueprint Visual Scripting
Subscribe for more Unreal Engine tutorials: Rambod YouTube Channel
What You Will Build
- A corrected zoom direction that feels natural with the mouse wheel
- Clamped zoom distance so the camera cannot zoom into nonsense values
- A 2D input action for camera rotation
- Middle mouse activation for intentional camera drag rotation
- Separate pitch logic on the Spring Arm
- Separate yaw logic on the RTS pawn actor
- Clamped pitch values to prevent ugly flips and broken angles
Why RTS Camera Rotation Matters
In many strategy games, the player needs more than just movement and zoom. Rotation matters because it helps with:
- reading terrain and elevation
- checking building placement from better angles
- improving spatial awareness during combat
- making the camera feel more modern and flexible
But rotation only feels good when it is controlled properly. Bad rotation systems are usually too loose, too easy to trigger accidentally, or they allow the camera to flip into broken angles.
That is why this setup uses middle mouse drag, pitch and yaw separation, and clamping.
What This Tutorial Improves Before Rotation
Before building rotation itself, there are two quick fixes worth doing to the zoom system:
- Fix the zoom direction so scroll input feels natural.
- Clamp the zoom distance so the camera cannot go too close or too far.
These are small upgrades, but they make the whole camera feel more intentional.
Step 1: Fix the Zoom Direction
Open your Input Mapping Context and find the zoom mapping.
On the zoom action mapping, add a:
Negate
modifier.
This flips the scroll direction so the zoom feels more natural. In most RTS-style camera setups, players expect scroll forward to zoom in and scroll backward to zoom out.
If your current setup feels backward, this is the correct fix.
Why the Zoom Direction Fix Matters
This sounds small, but wrong zoom direction feels annoying immediately. Players may not consciously explain it, but it feels off.
A basic camera system should not lose points over something this easy to correct.
Step 2: Clamp the Zoom Distance
Open:
BP_RTSPlayer
and find the zoom logic you already built for the Spring Arm.
After the float add node that calculates the new arm length, insert:
Clamp (Float)
Example values:
Min = 20
Max = 1000
Then feed the clamp result into:
Set Target Arm Length
This stops the camera from zooming too close into the pawn or too far into pointless distance.
Why Zoom Clamping Is Necessary
Without clamping, the Spring Arm length can keep growing or shrinking past sensible values. That usually leads to one of two bad results:
- the camera goes too close and becomes awkward or clips badly
- the camera goes too far and loses all practical usefulness
Clamping is not optional polish. It is a necessary guardrail.
Step 3: Create the Rotation Input Action
In your Input Actions folder, create a new Input Action named:
IA_RotationAction
Open it and set:
Value Type = Axis2D
Axis2D is the right choice because camera rotation needs two independent inputs:
- horizontal mouse movement for yaw
- vertical mouse movement for pitch
Why Axis2D Is the Right Input Type
Rotation is not a one-direction input. You are handling two channels of movement at once:
- X for left and right mouse movement
- Y for up and down mouse movement
Axis2D packages both into one vector, which makes the Blueprint logic cleaner and more direct.
Step 4: Bind Mouse X and Mouse Y
Open your Input Mapping Context again and add mappings for:
IA_RotationAction
Use:
- Mouse X
- Mouse Y
Since this is a 2D action, you will use modifiers to map the axis values correctly into the Vector2D output.
Step 5: Add Swizzle and Negate Modifiers
For the mouse mappings, apply the needed modifiers:
- Swizzle Input Axis Values
- Negate where needed
Example setup described in the workflow:
- Mouse Y uses a YXZ-style swizzle
- Mouse X uses an XZY-style swizzle
The exact modifier arrangement depends on how you want the axis values to map into the final Vector2D, but the main idea is simple: make sure mouse movement ends up on the correct vector channels and in the correct direction.
Why Swizzling Matters
If you skip swizzle modifiers, the input values may end up on the wrong vector component, or the direction can feel broken.
This is one of those Enhanced Input details that seems annoying until you understand it. Then it becomes obvious.
Bad swizzle setup makes the rotation feel wrong even if the Blueprint logic is technically correct.
Step 6: Create a RotationActivate Variable
In BP_RTSPlayer, create a Boolean variable named:
RotationActivate
Default value:
false
This variable will decide whether the camera is allowed to rotate at that moment.
The goal is to make rotation intentional, not always active. That is why the camera only rotates while middle mouse is held.
Why Middle Mouse Activation Is Better
Constant free rotation tied directly to mouse movement is bad for an RTS camera. It causes accidental camera movement and makes the system feel unstable.
By requiring middle mouse drag:
- rotation becomes deliberate
- normal cursor movement stays safe
- the control scheme feels more professional
This is the right design choice for this style of camera.
Step 7: Add Middle Mouse Pressed and Released Logic
In BP_RTSPlayer, add Middle Mouse Button input handling.
On:
Pressed
set:
RotationActivate = true
On:
Released
set:
RotationActivate = false
This creates the activation gate for the whole rotation system.
Step 8: Add the Rotation Action Event
In the Event Graph, add the Enhanced Input event for:
IA_RotationAction
From the Triggered execution pin, add a:
Branch
Use:
RotationActivate
as the condition.
That means the pitch and yaw logic only runs while middle mouse drag is active.
Step 9: Break the Vector2D Input
From the action value, use:
Break Vector2D
This gives you:
- X for horizontal mouse movement
- Y for vertical mouse movement
These two values will now drive separate parts of the rotation system.
Why Pitch and Yaw Should Be Handled Separately
Mixing pitch and yaw into one shared rotation path is how camera logic becomes a mess.
A cleaner design is:
- pitch changes the Spring Arm rotation
- yaw changes the actor rotation
That separation gives you more control and avoids weird compound rotation behavior.
Step 10: Build the Pitch Logic
Drag in a reference to the:
Spring Arm
Get its current rotation and break the rotator.
Take the current pitch and add the Y value from the rotation input.
Then use:
Clamp (Float)
Example pitch range:
Min = -80
Max = -10
Then build a new rotator and apply it back to the Spring Arm.
Why Pitch Must Be Clamped
If you do not clamp pitch, the camera can tilt into terrible angles:
- too flat to read the battlefield
- too vertical to feel useful
- possibly flipping into ugly perspectives
The clamp keeps the camera inside a practical RTS viewing range.
Step 11: Apply the Spring Arm Rotation
After creating the new pitch value, use:
Set World Rotation
or the equivalent Spring Arm rotation setter in your current setup.
Keep the unchanged yaw from the Spring Arm where appropriate and set roll to zero unless you explicitly want roll behavior.
For this camera, roll is unnecessary noise.
Step 12: Build the Yaw Logic
Now handle horizontal rotation on the RTS pawn itself.
Get:
Actor Rotation
Break the rotator, then take the current yaw and add the X value from Break Vector2D.
Optionally clamp the yaw to a range like:
-360 to 360
Then create a new rotator and set the actor rotation.
Why Yaw Belongs on the Actor
The overall left-right orbiting feel of the RTS camera is best controlled by rotating the actor itself. That keeps the whole camera rig turning around the world in a clean way.
If pitch and yaw both live on the same component without clear separation, you get harder-to-maintain logic and more chances for weird camera behavior.
Step 13: Keep Roll at Zero
Whether you are making the new rotator for pitch or yaw, keep:
Roll = 0
An RTS camera usually has no reason to roll. Roll just makes the camera look sloppy or cinematic in the wrong way.
How the Full Rotation System Works
The complete logic is:
- Middle mouse pressed sets RotationActivate to true.
- Middle mouse released sets RotationActivate to false.
- IA_RotationAction fires with mouse movement.
- A branch checks RotationActivate.
- Break Vector2D splits the input into X and Y.
- Y updates Spring Arm pitch with clamp.
- X updates actor yaw.
This is clean and easy to reason about. That matters.
Step 14: Test the Rotation in the Editor
Press Play and test the system:
- use the mouse wheel to confirm zoom direction feels correct
- check that zoom now respects the clamp range
- hold middle mouse and drag left and right for yaw
- hold middle mouse and drag up and down for pitch
- confirm the pitch stays inside the clamp range
If everything is wired correctly, the camera should now feel much more complete.
What the Final Result Should Feel Like
When the system is working properly:
- zoom direction feels natural
- zoom cannot break the camera by going too close or too far
- rotation only happens when intentionally activated
- pitch feels controlled and limited
- yaw feels smooth and stable
That is the difference between a camera that technically rotates and a camera that actually feels usable.
Common Problem: Rotation Feels Inverted
If dragging the mouse feels reversed in one axis:
- check your Negate modifier
- check your swizzle setup
- invert the relevant value before applying it
This is usually not a logic failure. It is just a direction setup issue.
Common Problem: Rotation Fires Without Middle Mouse
If the camera rotates even when middle mouse is not held:
- check the RotationActivate variable
- check the middle mouse pressed and released logic
- check the branch before the pitch and yaw calculations
The branch gate is what makes the system deliberate instead of annoying.
Common Problem: Camera Flips or Tilts Too Far
If the camera behaves badly when dragging vertically:
- check the pitch clamp values
- make sure the Spring Arm rotation is the part being updated for pitch
- make sure roll is staying at zero
This is exactly why pitch clamping exists.
Common Problem: Zoom Still Feels Bad
If zoom works but still feels wrong:
- adjust the zoom speed multiplier
- adjust the min clamp
- adjust the max clamp
- confirm the Negate modifier is applied correctly
Small tuning changes make a big difference in camera feel.
Why This Design Is Strong
This setup works well because it separates responsibilities cleanly:
- zoom uses the Spring Arm length
- pitch uses Spring Arm rotation
- yaw uses actor rotation
- middle mouse controls activation
That is a better design than mixing everything into one giant rotation chain.
What You Can Improve Later
Once this version works, possible upgrades include:
- rotation smoothing
- custom sensitivity variables
- zoom-dependent pitch ranges
- camera collision handling
- terrain-follow integration
- edge scrolling and map boundaries
But first, get the raw rotation system stable. That is what matters now.
Conclusion
In this tutorial, you fixed the zoom direction, clamped zoom distance, created a 2D rotation input action, mapped mouse X and mouse Y using Enhanced Input modifiers, added middle mouse drag activation, separated pitch and yaw into clean Blueprint paths, and clamped pitch so the RTS camera stays stable.
That gives you a much more complete and professional RTS camera foundation in Unreal Engine 5.
Download the project files: UE5 RTS Camera Tutorial GitHub Repository
Subscribe for the next RTS camera tutorial: Subscribe to Rambod on YouTube
Resources
Frequently Asked Questions
How do I rotate an RTS camera in Unreal Engine 5?
A clean approach is to use an Axis2D input action, enable rotation only while middle mouse is held, apply vertical input to Spring Arm pitch, and apply horizontal input to actor yaw.
Why separate pitch and yaw?
Separating them makes the camera easier to control and easier to debug. Pitch belongs on the Spring Arm, while yaw works well on the actor itself.
Why use middle mouse drag for rotation?
It prevents accidental rotation and makes the camera feel more deliberate and professional.
Why do I need pitch clamping?
Pitch clamping prevents the camera from flipping or rotating into useless angles that break the RTS view.
How do I fix inverted zoom in UE5?
Add a Negate modifier to the zoom mapping or invert the zoom input value in your Blueprint logic.
Why should zoom be clamped too?
Clamping prevents the camera from zooming too close into the pawn or too far away from the playable view.
Continue RTS Camera Series
Back to RTS Camera Series playlist • Lesson 5 of 8
Recommended resource
Recommended for this tutorial
Useful tools selected for this workflow topic.