Mobile Setup
This document covers RCC's mobile input system: on-screen buttons for throttle / brake, on-screen steering wheel, joystick, or gyroscope steering, plus the tooling and UI prefabs you need to ship a vehicle game on iOS or Android.
If you've already installed RCC on desktop and got the demo scenes working, mobile setup is mostly about flipping a few switches and adding the right UI canvas.
Enabling Mobile Mode
Open RCC_Settings.asset. Find Mobile Controller Enabled and check it. This single setting flips the input source from the Input Manager to RCC's mobile input pipeline.
When mobile is on:
RCC_InputManagerreads inputs fromRCC_MobileButtons(a static class) instead of from the Input System.- The mobile UI canvas auto-shows its touch widgets (which are hidden on desktop).
- Keyboard / gamepad input is ignored on mobile platforms.
You can leave mobile enabled in the editor as well — the on-screen buttons will appear and work with mouse clicks, useful for testing the mobile UI without deploying to a device.
Picking a Steering Style
RCC_Settings has a Mobile Controller enum with four options:
| Option | What the Player Does | Best For |
|---|---|---|
| Touch Screen | Press buttons on the left and right of the screen for steering. | Casual / arcade games. |
| Gyro | Tilts the device left/right to steer. | Immersive racing on phones. |
| Steering Wheel | Rotates an on-screen wheel by touching and dragging. | Realistic feel without external hardware. |
| Joystick | Drags a virtual joystick to steer (also handles throttle/brake direction). | Open-world / GTA-style games. |
You can change the option live in code:
RCC.SetMobileController(RCC_Settings.MobileController.Gyro);
Or set the default in RCC_Settings.asset. Players can switch between styles via your settings menu by exposing the option in your UI.
Adding the Mobile UI Canvas
Drop the RCC_Canvas (AIO).prefab into your scene. It lives at:
Assets/RealisticCarControllerV4/Prefabs/UI/RCC_Canvas (AIO).prefab
This canvas contains every mobile widget RCC provides:
- Left side: throttle button.
- Right side: brake button.
- Lower middle: handbrake button.
- Upper right: gear shift up / down buttons.
- Upper left: HUD (speedometer, RPM gauge, gear indicator).
- Center steering (configurable): wheel / joystick / or hidden if using gyro / touch buttons.
- Bottom edge: extra buttons (camera, lights, indicators, reset).
The canvas auto-detects platform via Application.isMobilePlatform. On desktop, the touch widgets stay hidden so you can see the HUD without the buttons cluttering the screen. On mobile (or in the editor with mobile enabled), the buttons appear.
If you only want certain widgets — e.g., you've built your own HUD but want to use RCC's joystick — you can copy individual widget prefabs from inside the AIO canvas.
Tuning Sensitivity
In RCC_Settings.asset, three fields control mobile input feel:
UI Button Sensitivity
How quickly the throttle / brake ramps to full when you press the button. Higher = faster ramp. Default 10. Lower if your game wants gradual acceleration (cruising / scenic driving). Higher if you want instant response (arcade).
UI Button Gravity
How quickly throttle / brake returns to zero when you release. Default 10. Same logic — higher = snappier release.
Gyro Sensitivity
Multiplier on gyroscope steering. Default 2. Higher = a smaller tilt produces a bigger steering input. Set based on your target audience — kids might want lower (less twitchy), arcade players might want higher.
You can tune these live in code at runtime:
RCC_Settings.Instance.UIButtonSensitivity = 15f;
RCC_Settings.Instance.gyroSensitivity = 1.5f;
These changes persist for the current Play session only (because RCC_Settings clones itself in Play mode).
Per-Widget Configuration
Each widget on the mobile canvas has its own component you can configure. The most useful ones:
Touch Buttons (RCC_UI_Controller)
The throttle and brake buttons use RCC_UI_Controller. Each has:
- Sensitivity — overrides the global UI Button Sensitivity for this button.
- Gravity — overrides the global gravity.
- Pressed Color / Highlight Color — visual feedback colors.
Joystick (RCC_UI_Joystick)
If you're using the joystick mode, the RCC_UI_Joystick component on the joystick widget has:
- Drag Sensitivity — multiplier on drag distance.
- Snap Back — whether the joystick returns to center on release.
Steering Wheel (RCC_UI_SteeringWheelController)
The on-screen wheel widget:
- Max Steer Angle — maximum rotation (in degrees) the wheel can be turned to.
- Snap Back Speed — how fast the wheel returns to center when released.
- Snap Back Threshold — minimum rotation that holds before snap-back kicks in.
Gyroscope Steering
Gyro mode uses Input.gyro.attitude (or the new Input System equivalent on supported devices). The user holds the phone landscape and tilts it left/right to steer.
For a good gyro experience:
- Calibrate the resting position on game start (have a "Calibrate" button in your settings).
- Don't enforce a maximum tilt — let the player tilt as much as they want.
- Dead-zone the center — small tilts shouldn't move the steering, only larger tilts should. This is what makes the gyro feel "snappy."
If gyro steering feels too sensitive or laggy, adjust RCC_Settings.gyroSensitivity.
Hiding Specific Widgets
If you don't want, say, the gear shift buttons (because your game is automatic-only):
- Expand
RCC_Canvas (AIO).prefabin the Hierarchy. - Find the gear shift up / down buttons in the canvas.
- Disable them (uncheck the GameObject's active state).
Don't delete them — disabling is reversible if you later decide to enable manual transmissions. Deleting means re-adding from the original prefab.
Performance on Mobile
Mobile performance matters more than desktop. A few RCC-specific tips:
Disable Particle Effects
RCC_Settings.dontUseAnyParticleEffects = true disables exhaust smoke, dust particles, sparks. The biggest performance win on low-end mobile.
Disable Skidmarks
RCC_Settings.dontUseSkidmarks = true disables skidmark rendering. Skidmarks accumulate over time and the mesh can get large in long sessions.
Vertex Lights Instead of Pixel Lights
In RCC_Settings, enable:
useHeadLightsAsVertexLights = trueuseBrakeLightsAsVertexLights = trueuseReverseLightsAsVertexLights = trueuseIndicatorLightsAsVertexLights = true
Vertex lighting is much cheaper than pixel lighting. The headlights will look less crisp, but on a phone screen the difference is minor.
Reduce Wheel Count
If your vehicles use more than 4 wheels (trucks, 6-wheelers), each extra wheel costs a raycast and friction computation per frame. Stick to 4 wheels per vehicle when possible.
LOD Vehicles
Use RCC_LOD to disable wheel updates on far-away vehicles. The visible mesh stays, but the physics simplifies.
Lower Fixed Timestep
RCC_Settings.fixedTimeStep = 0.04 (25 Hz) instead of the default 0.02 (50 Hz) cuts physics work in half. The vehicle won't be as crisp at high speed, but on mobile the trade is usually worth it.
Touch Input Gotchas
Multitouch
The mobile UI handles multitouch correctly — the player can press throttle + brake + handbrake simultaneously. If you've added your own touch widgets, use EventSystem.current.IsPointerOverGameObject() to check if a touch is over UI before treating it as a world-space touch.
Touch Coordinate Space
Mobile touch coordinates are in screen pixels (origin bottom-left, X right, Y up). If you query touches yourself (e.g., for a "tap to honk" gesture), remember to convert via Camera.ScreenToWorldPoint.
Notch / Safe Areas
Modern phones have notches and rounded corners. Use Unity's Screen.safeArea API to lay out the mobile UI so buttons don't end up under the notch. The shipped AIO canvas uses anchor-based layout that mostly handles this, but custom UIs need explicit safe-area handling.
Building for iOS / Android
Standard Unity build pipeline. A few RCC-specific things:
- Make sure Active Input Handling is set to Both or Input System Package (New).
- Make sure the Build Target is iOS or Android (Player Settings → Platform).
- For Android, ensure the minimum API level supports your gyroscope / device features (API 21 / Android 5.0 covers most modern phones).
- For iOS, set the Camera Usage description if your game uses AR features (RCC itself doesn't).
After building, deploy to a real device for testing — the editor's mouse-emulation of touch doesn't catch every issue (multitouch behavior, accelerometer values, etc.).
Testing the Mobile UI in the Editor
The mobile UI works in the editor with mouse clicks if Mobile Controller Enabled is on in RCC_Settings. The throttle and brake buttons respond to left-mouse-press, the joystick responds to drag, the wheel responds to drag.
For gyroscope testing, you need a real device — the editor doesn't simulate accelerometer input by default. (You can install Unity Remote on a phone to forward gyro data to the editor, but it's flaky.)
Common Mobile Issues
"Touch buttons don't appear"
Either Mobile Controller Enabled is off, or the RCC_Canvas (AIO) prefab isn't in the scene. Add both.
"Buttons appear but don't respond"
The scene needs an EventSystem. Unity auto-adds one when you create a UI canvas, but if you've deleted it, add it back: GameObject → UI → Event System.
"Steering is reversed in gyro mode"
The device's natural orientation is interpreted differently on iOS vs Android. Some games expose a "Invert Steering" toggle to handle this. You can implement it by negating inputs.steerInput before passing it to the controller.
"Steering wheel rotation is jittery"
The wheel widget reads touch deltas every frame — if the device's frame rate is unstable, the wheel can jitter. Lower Drag Sensitivity to smooth it out.
"The HUD is too small / too big on my phone"
The canvas uses Canvas Scaler in Scale With Screen Size mode. Open the canvas's Canvas Scaler component and adjust the Reference Resolution and Match values for your target device.
Building Your Own Mobile UI
If RCC's mobile UI doesn't fit your art style, you can replace it entirely. The contract is simple — your UI must write into RCC_MobileButtons.mobileInputs each frame:
RCC_MobileButtons.mobileInputs.throttleInput = myButton.value;
RCC_MobileButtons.mobileInputs.brakeInput = myBrakeButton.value;
RCC_MobileButtons.mobileInputs.steerInput = myJoystick.horizontalValue;
// etc.
As long as Mobile Controller Enabled is on in RCC_Settings, RCC will read these values. Your custom UI is just another writer to the same static struct.
Next Steps
- 16 — Input System — the desktop input pipeline.
- 21 — RCC Settings Deep Dive — all mobile settings.
- 15 — Audio System — audio performance tips for mobile.