In diesem Leitfaden erfahren Sie, wie Sie Ihr Spiel an verschiedene Android-Formfaktoren anpassen.
Lies zuerst den Artikel Unterstützung für die Größenänderung auf großen Bildschirmen. Moderne Spiele für Android sollten sich an alle Bildschirmgrößen anpassen, ohne auf Systemkompatibilitätsebenen angewiesen zu sein. So behältst du immer die Kontrolle darüber, wie dein Spiel angezeigt wird, und dein Spiel bietet ein erstklassiges Spielerlebnis, auch auf Formfaktoren wie XR oder Geräten, bei denen ein Bildschirm nicht gedreht werden kann.
Führen Sie dazu die folgenden Aufgaben aus:
- Deaktivieren Sie die Letterbox-Darstellung des Systems und implementieren Sie Ihre eigene Letterbox-Darstellung in der Engine.
- Der Letterbox-Bereich sollte nutzbar und thematisch passend sein.
- Berücksichtige Designaspekte, die erforderlich sind, damit dein Spiel von 21:9 über 1:1 bis hin zu 9:21 skaliert werden kann.
Befehle zum Testen
Prüfe beim Erstellen und Testen deines Spiels, ob es Letterboxen selbst rendert. Außerdem solltest du dein Spiel so konfigurieren, dass es im Hoch- und Querformat angezeigt wird, da Geräte wie Fernseher und Displays in Autos nicht aus ihrer Standardausrichtung gedreht werden können.
Mit dem Befehl adb shell cmd window set-letterbox-style kannst du prüfen, ob deine Spiel-Engine System-Letterboxing verwendet. Mit dem folgenden Befehl werden beispielsweise die System-Letterboxen hellgrün dargestellt und Ihrem Spiel wird ein Eckenradius hinzugefügt. So ist leicht zu erkennen, ob Ihr Spiel in den Kompatibilitätsmodus des Betriebssystems wechselt:
adb shell "cmd window set-letterbox-style --backgroundType solid_color --backgroundColor '#00FF00' --cornerRadius 30 --isEducationEnabled false"
Wenn Sie eine Ausrichtung für Tests erzwingen möchten, verwenden Sie adb shell cmd window user-rotation lock. So können Sie simulieren, wie sich Ihr Spiel auf einem Gerät verhält, das App-Überschreibungen für die Ausrichtung nicht berücksichtigt, oder nachvollziehen, was Nutzer auf einem XR- oder PC-ähnlichen Gerät sehen, auf dem Fenster unabhängig von der Geräteausrichtung im Hoch- oder Querformat angezeigt werden können.
Versetzen Sie Ihr Gerät zuerst in einen Zustand, in dem Sie die App-Ausrichtung überschreiben können:
adb shell cmd window set-ignore-orientation-request true
adb shell cmd window fixed-to-user-rotation enabled
Als Nächstes testen Sie, wie sich das Spiel im Querformat verhält:
adb shell cmd window user-rotation lock 1
Testen Sie dann, wie sich das Spiel im Hochformat verhält:
adb shell cmd window user-rotation lock 0
Setzen Sie Ihr Gerät auf die OEM-Konfiguration zurück, indem Sie es neu starten oder die folgenden Befehle ausführen:
adb shell cmd window reset-letterbox-style
adb shell cmd window fixed-to-user-rotation default
adb shell cmd window user-rotation free
adb shell cmd window set-ignore-orientation-request reset
Warum sollte das System-Letterboxing deaktiviert werden?
Die Letterbox-Darstellung wird immer vom System gesteuert. Wenn du die Bildschirmgröße ermittelst und den Anzeigebereich selbst verwaltest, kannst du Probleme wie verlorene Eingaben vermeiden, die auftreten, wenn Eingaben außerhalb des Spielbereichs erfolgen. Du kannst auch Elemente, die nicht zum Gameplay gehören, bis zum Bildschirmrand erweitern, auch wenn die Spielinhalte in der Mitte fixiert bleiben. Durch Systemkompatibilitätsmodi kann ein Spiel verfügbar gemacht werden, aber es liegt an Ihnen als Spieleentwickler, Ihr Spiel für Ihre Spieler zu optimieren.
Beispielimplementierung für Letterbox
Bei den meisten Game-Engines können Sie festlegen, wo eine Kamera auf dem Bildschirm gerendert wird. Wenn du deine eigene Letterbox-Darstellung implementieren möchtest, miss das Seitenverhältnis des gerenderten Bereichs und passe das Clipping-Rechteck für den nicht verwendeten Bereich an, anstatt das Spiel vom System mit Letterbox-Darstellung anzeigen zu lassen. Im folgenden Beispiel wird eine Kamera auf das Rendern in einem begrenzten Seitenverhältnis beschränkt, während UI-Kameras oder -Durchgänge auf die volle logische Bildschirmgröße erweitert werden können:
Unity
[SerializeField] private float minAspectRatio = 4f / 3f; [SerializeField] private float maxAspectRatio = 21f / 9f; private Camera _camera; private void Awake() { _camera = GetComponent<Camera>(); } public void MaintainAspectRatio() { int viewWidth = Screen.width; int viewHeight = Screen.height; // 1. Calculate screen aspect ratio float scaleScreen = viewWidth / (float)viewHeight; Rect rect = _camera.pixelRect; // 2. Scale to the fullest of the lower between width or height if (scaleScreen > maxAspectRatio) { // use height, lock width to max at aspect scale rect.width = viewHeight * maxAspectRatio; rect.height = viewHeight; } else if (scaleScreen < minAspectRatio) { // use width, lock height to min at aspect scale rect.width = viewWidth; rect.height = viewWidth / minAspectRatio; } else { // within allowed aspect ratio range, use full screen rect.width = viewWidth; rect.height = viewHeight; } rect.x = Mathf.Floor((viewWidth - rect.width) * 0.5f); rect.y = Mathf.Floor((viewHeight - rect.height) * 0.5f); Debug.Log("camera view width = " + rect.width + " height = " + rect.height + " x = " + rect.x + " y = " + rect.y); // 3. Commit the new size to the camera so that it takes effect _camera.pixelRect = rect; }
C++ (Vulkan)
/** * @brief Calculates a bounded-aspect-ratio gameplay viewport and scissor * rectangle and records them directly into a Vulkan command buffer. * * @note Requires `VK_DYNAMIC_STATE_VIEWPORT` and `VK_DYNAMIC_STATE_SCISSOR` to * be enabled on the bound graphics `VkPipeline`. * * @param command_buffer Active `VkCommandBuffer` in the recording state. * @param window_width Full physical window or swapchain width in pixels. * @param window_height Full physical window or swapchain height in pixels. * @param min_aspect_ratio Minimum allowed aspect ratio (`width / height`). * @param max_aspect_ratio Maximum allowed aspect ratio (`width / height`). */ void MaintainAspectRatio(VkCommandBuffer command_buffer, uint32_t window_width, uint32_t window_height, float min_aspect_ratio, float max_aspect_ratio) { if (command_buffer == VK_NULL_HANDLE || window_width == 0 || window_height == 0 || min_aspect_ratio <= 0.0f || max_aspect_ratio < min_aspect_ratio) { return; } // 1. Calculate screen aspect ratio. const float view_width = static_cast<float>(window_width); const float view_height = static_cast<float>(window_height); const float scale_screen = view_width / view_height; // 2. Scale to the fullest of the lower between width or height. float rect_width = view_width; float rect_height = view_height; if (scale_screen > max_aspect_ratio) { // Use height, lock width to max at aspect scale (pillarbox). rect_width = std::floor(view_height * max_aspect_ratio); rect_height = view_height; } else if (scale_screen < min_aspect_ratio) { // Use width, lock height to min at aspect scale (letterbox). rect_width = view_width; rect_height = std::floor(view_width / min_aspect_ratio); } else { // Within allowed aspect ratio range, use full screen. rect_width = view_width; rect_height = view_height; } const float rect_x = std::floor((view_width - rect_width) * 0.5f); const float rect_y = std::floor((view_height - rect_height) * 0.5f); // 3. Commit the new viewport and scissor to the command buffer so that // subsequent gameplay draw calls are transformed and clipped to this region. const VkViewport viewport = { .x = rect_x, .y = rect_y, .width = rect_width, .height = rect_height, .minDepth = 0.0f, .maxDepth = 1.0f, }; const VkRect2D scissor = { .offset = { .x = static_cast<int32_t>(rect_x), .y = static_cast<int32_t>(rect_y), }, .extent = { .width = static_cast<uint32_t>(rect_width), .height = static_cast<uint32_t>(rect_height), }, }; vkCmdSetViewport(command_buffer, 0, 1, &viewport); vkCmdSetScissor(command_buffer, 0, 1, &scissor); }
Eine detaillierte Anleitung für Unity finden Sie im Codelab Unity-Spiele für große Bildschirme und faltbare Geräte optimieren.
Große und kleine Bildschirmgrößen verarbeiten
Auf kleineren Bildschirmen wie Smartphones und den äußeren Displays von faltbaren Geräten ist die beste Nutzererfahrung möglicherweise ein Spiel, das auf das Hoch- oder Querformat beschränkt ist. Bei größeren Bildschirmen wie Tablets, Chromebooks, Displays im Auto oder den inneren Displays von Foldables ist es weniger wünschenswert oder sogar unmöglich, das Gerät zu drehen. Das größere physische Display sorgt jedoch dafür, dass das Spiel auch in anderen Seitenverhältnissen spielbar bleibt.
Um Spielern die bestmögliche Erfahrung zu bieten, solltest du die Bildschirmgröße zur Laufzeit ermitteln und die Drehung bei Bedarf einschränken. Gleichzeitig solltest du Spielern mehr Flexibilität bieten, wenn die Bildschirmgröße zunimmt. Android betrachtet sw600dp als idealen Grenzwert, also eine kleinste Breite von 600 dichteunabhängigen Pixeln (600 dp).
Dies korreliert mit WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND. Verwenden Sie computeMaximumWindowMetrics, um die verfügbare Bildschirmgröße in Konfigurationen mit mehreren Displays zu prüfen.
Wenn du das in deinem Spiel unterstützen möchtest, musst du alle Ausrichtungen in deinem Manifest unterstützen und dann sowohl in onCreate() als auch in onConfigurationChanged() die kleinste Breite auswerten und die Ausrichtungssperre entsprechend festlegen:
Entfernen Sie statische Ausrichtungssperren in Ihrem Manifest und deklarieren Sie die Verarbeitung von Konfigurationsänderungen:
<activity android:name=".MainActivity" android:resizeableActivity="true" android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|density|keyboard|keyboardHidden" />Fügen Sie die erforderlichen Importe hinzu:
import android.content.pm.ActivityInfo import android.content.res.Configuration import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.window.core.layout.WindowSizeClass import androidx.window.layout.WindowMetricsCalculator import kotlin.math.minSowohl
onCreateals auchonConfigurationChangedverarbeiten:override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) applyAdaptiveOrientationPolicy() // ... } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) applyAdaptiveOrientationPolicy() // ... }Aktualisiere die angeforderte Ausrichtung basierend auf der kleinsten Bildschirmbreite und sperre kompakte Bildschirme auf die bevorzugte Designausrichtung deines Spiels:
private fun applyAdaptiveOrientationPolicy() { // compute the smallest screen bound in dp val maxMetrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this) val minDimensionPx = min(maxMetrics.bounds.width(), maxMetrics.bounds.height()) val displaySmallestWidthDp = minDimensionPx / maxMetrics.density val targetOrientation = if (displaySmallestWidthDp >= WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) { // Large display (>= 600dp): allow free rotation in any orientation ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED } else { // Compact display (< 600dp): lock to your game's preferred orientation // (use SCREEN_ORIENTATION_SENSOR_LANDSCAPE for landscape-first games) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT } // Guard against redundant setter calls to avoid configuration change loops if (requestedOrientation != targetOrientation) { requestedOrientation = targetOrientation } }
Häufige Probleme vermeiden
Wenn du eine Reihe von Seitenverhältnissen und Ausrichtungen unterstützt, bietest du deinen Spielern die bestmögliche Nutzererfahrung. Im Gegensatz zu Smartphones sind größere Displays oft entweder im Quer- oder im Hochformat fixiert. In einigen Fällen ist der Bildschirm fast quadratisch. Auf diesen größeren Geräten nutzen Spieler oft Multitasking, während sie dein Spiel spielen. Wenn du den Platz auf dem Bildschirm optimal nutzt, kannst du mehr Spieler häufiger und für längere Spielsitzungen ansprechen.
In den folgenden Abschnitten finden Sie Lösungen, mit denen sich Ihr Spiel auf allen Formfaktoren wie ein Premium-Spiel anfühlt und nicht wie ein Smartphone-Spiel, das in einen Bildschirm eingebettet ist, der nicht zu einem Smartphone gehört.
Kameras mit Seitenverhältnis-Erkennung
Wenn ein Bildschirm in 3D-Spielen zu hoch ist, haben Spieler möglicherweise das Gefühl, das Spiel durch einen schmalen Schlitz zu sehen. Wenn er zu breit ist, verpassen Spieler möglicherweise geplante Interaktionen. Wie bei 2D-Spielen können Sie einen „empfohlenen Bildbereich“ immer sichtbar halten. Der folgende Code wechselt zwischen einem horizontalen und einem vertikalen Sichtfeld, je nachdem, wie das aktive Seitenverhältnis im Vergleich zu einem Referenzseitenverhältnis von 1920 × 1080 ist. So kann ein Designer ein Spiel für ein 1080p-Display entwickeln und sicher sein, dass alles, was innerhalb dieses Referenzrahmens entworfen wurde, sichtbar bleibt:
Unity
[SerializeField] private Camera _camera; [SerializeField] private float _referenceWidth = 1920f; [SerializeField] private float _referenceHeight = 1080f; [SerializeField] private float _referenceVerticalFov = 60f; public float ReferenceAspectRatio => _referenceWidth / Mathf.Max(0.0001f, _referenceHeight); private void Awake() { if (_camera == null) { _camera = GetComponent<Camera>(); } } // Built-in Render Pipeline callback. In URP, subscribe to // RenderPipelineManager.beginCameraRendering or call UpdateFov() on resize. private void OnPreCull() { UpdateFov(); } public void UpdateFov() { if (_camera == null || _camera.orthographic) { return; } float referenceAspect = ReferenceAspectRatio; float currentAspect = _camera.aspect; if (currentAspect <= 0.0001f) { return; } float targetVerticalFov; if (currentAspect >= referenceAspect) { // Viewport is wider than (or equal to) the reference safe area targetVerticalFov = _referenceVerticalFov; } else { // Viewport is skinnier than the reference safe area float referenceHorizontalFov = Camera.VerticalToHorizontalFieldOfView(_referenceVerticalFov, referenceAspect); targetVerticalFov = Camera.HorizontalToVerticalFieldOfView(referenceHorizontalFov, currentAspect); targetVerticalFov = Mathf.Clamp(targetVerticalFov, 1f, 179f); } if (!Mathf.Approximately(_camera.fieldOfView, targetVerticalFov)) { _camera.fieldOfView = targetVerticalFov; } }
C++ (Vulkan)
/** * @brief Calculates an aspect-aware Vulkan perspective projection matrix using * GLM that keeps a reference safe area (e.g., 1920x1080) visible across * aspect ratios. * * @note Uses `glm::perspectiveZO` for Vulkan's `[0, 1]` depth range and * inverts `projection[1][1]` for Vulkan's top-left (`+Y` down) clip space. * * @param viewport_width Active gameplay viewport width in pixels. * @param viewport_height Active gameplay viewport height in pixels. * @param reference_width Authored safe-area reference width in pixels. * @param reference_height Authored safe-area reference height in pixels. * @param reference_vertical_fov Authored vertical FOV in degrees (e.g., 60.0f). * @param near_plane Near clipping plane distance (`zNear > 0.0f`). * @param far_plane Far clipping plane distance (`zFar > zNear`). * @return Aspect-aware `glm::mat4` perspective projection matrix for Vulkan. */ glm::mat4 CalculateAspectAwareProjectionMatrix( float viewport_width, float viewport_height, float reference_width = 1920.0f, float reference_height = 1080.0f, float reference_vertical_fov = 60.0f, float near_plane = 0.1f, float far_plane = 100.0f) { if (viewport_width <= 0.0001f || viewport_height <= 0.0001f) { return glm::mat4(1.0f); } // 1. Compare the active viewport aspect ratio against the reference safe // area. const float reference_aspect = reference_width / std::max(0.0001f, reference_height); const float current_aspect = viewport_width / viewport_height; float target_vertical_fov_rad = glm::radians(reference_vertical_fov); if (current_aspect >= reference_aspect) { // Viewport is wider than (or equal to) the reference safe area (Hor+). target_vertical_fov_rad = glm::radians(reference_vertical_fov); } else { // Viewport is skinnier than the reference safe area (Vert+): // Convert reference vertical FOV -> reference horizontal FOV -> new // vertical FOV at current_aspect so the safe area is never cropped. const float tan_half_horiz = std::tan(target_vertical_fov_rad * 0.5f) * reference_aspect; target_vertical_fov_rad = 2.0f * std::atan(tan_half_horiz / current_aspect); target_vertical_fov_rad = std::clamp( target_vertical_fov_rad, glm::radians(1.0f), glm::radians(179.0f)); } // 2. Build the Vulkan [0, 1] depth perspective matrix and flip +Y clip space. glm::mat4 projection = glm::perspectiveZO( target_vertical_fov_rad, current_aspect, near_plane, far_plane); projection[1][1] *= -1.0f; return projection; }
Vollständig interaktive Briefkästen
Einige Spiele haben einen festen Spielbereich, der oft auf genretypischen Designüberlegungen basiert, z. B. das feste Feld eines vertikalen Shoot-'em-up oder das Flip-Screen-Scrolling für eine Retro-Ästhetik.
Skaliere bei diesen Spielen den Gameplay-Bereich so, dass eine Achse des Spiels immer maximiert ist, um den Gameplay-Bereich auszufüllen. Welche Achse maximiert wird, kann sich je nach relativem Seitenverhältnis des Spiels und den Displaygrenzen ändern.
Verankere HUD- und UI-Elemente am sicheren Rand des Bildschirms: Vermeide Aussparungen, platziere aber interaktive Elemente wie virtuelle Steuerelemente, Gesundheitsbalken und Minikarten so weit wie möglich außerhalb des Gameplay-Bereichs. So wird der interaktive Teil des Spiels auf dem gesamten Bildschirm angezeigt und Spieler können auf Formfaktoren wie Tablets und Foldables bequem spielen, ohne ihre Finger übermäßig strecken zu müssen.
Schließlich sollte der Letterbox-Bereich thematisch oder diegetisch passend gestaltet werden. Du kannst Rahmen verwenden, die zur Farbpalette oder zum Tile-Set auf dem Bildschirm passen, einen virtuellen Tisch oder Bildschirm für Brett- oder Retrospiele oder erweiterte Minikarten und dekorative Grafiken.
Im folgenden Beispiel wird das Spiel für die meisten Seitenverhältnisse in voller Größe gerendert. Wenn das Seitenverhältnis schmaler als 4:3 ist, wird eine thematisch gefärbte Skybox gerendert. UI-Elemente wie Steuerelemente werden weiterhin am Bildschirmrand platziert:
|
|
Nebel des Krieges
Viele Spieleentwickler befürchten, dass Spieler durch extreme vertikale oder horizontale Seitenverhältnisse einen unfairen Vorteil erlangen könnten. Beispielsweise könnte ein Spieler in einem kompetitiven Spiel wie einer Multiplayer Online Battle Arena (MOBA) einen sehr vertikalen Bildschirm verwenden, um einen tiefen Einblick in die Lane eines Gegners zu erhalten.
Bei Top-Down-Strategie- und Simulationsspielen können Sie einen Nebel des Krieges rendern:
- Rendern Sie die Geometrie erst, wenn der Spieler sie sehen kann.
- Rendern Sie Geometrie, die der Spielercharakter nicht aktiv sehen kann, als gedimmt und ohne dynamische Elemente.
- Rendert nur Gegner, Sammelobjekte und andere dynamische Objekte, die der Spielercharakter aktiv diegetisch sehen kann.
Wenn du diese Technik mit vollständig interaktiven Letterboxen kombinierst und deine UI bis zum Bildschirmrand renderst, erhält der Spieler ein Erlebnis, das sowohl ausgereift als auch beabsichtigt wirkt, ohne dass du die Levelstruktur oder die Teambalance neu gestalten musst.
Wenn dieses Spiel auf einen größeren Bildschirm erweitert wird, ohne dass ein Nebel des Krieges vorhanden ist, werden Teile der Karte sichtbar, die der Spieler nicht sehen sollte:
|
|
Durch das Rendern eines Nebels des Krieges und das Ausblenden dynamischer Elemente wie Gegner und Gegenstände bleibt das Spiel fair, während der gesamte für das Spiel verfügbare Frame verwendet wird:
|
|
Geometrie ausblenden
Viele Spiele, insbesondere im Bereich der rundenbasierten Strategie, verwenden eine Technik, die dem im vorherigen Abschnitt beschriebenen Nebel des Krieges ähnelt, und rendern keine Geometrie, die der Spieler entweder nicht entdeckt hat oder mit der er während eines bestimmten Setpieces nicht interagieren kann.
Wenn ein erweitertes Sichtfeld Teile deines Sets oder deiner Zwischensequenz offenbaren würde, die der Spieler nicht sehen soll, kannst du bestimmte Teile der Szene auf eine saubere Weise maskieren. So erzielst du denselben praktischen Effekt wie mit einem Letterbox-Format, ohne dass ein fester statischer Rand wahrgenommen wird.
Im folgenden Beispiel wird das Spiel auf ein größeres Seitenverhältnis erweitert, wodurch eine Zombiehorde außerhalb der Burgmauern sichtbar wird:
|
|
Stattdessen können Sie die Geometrie des Levels außerhalb der Grenzen des aktuellen Spielbereichs weglassen:
|
|
Diegetische Grenzen
In immersiven 3D-Spielen, in denen ein erweitertes Sichtfeld zu einem Wettbewerbsvorteil in Ego- oder Third-Person-Multiplayer-Spielen führen oder nicht autorisierte Bereiche von Spielen mit festem Set offenlegen kann, solltest du diegetische Elemente in das Spiel einbauen, um das Sichtfeld zu begrenzen, anstatt dich auf ein rechteckiges Letterbox-Format zu verlassen. Beispiele:
- Das Cockpit eines Fahrzeugs wie eines Autos oder Flugzeugs
- Das Innere eines Helms
- Eine Vignette, die den Rand des Sichtfelds eines Spielers anzeigt
UI- und HUD-Elemente sollten sich weiterhin bis zum Bildschirmrand erstrecken oder in die diegetischen Grenzen integriert werden. Es ist ideal, sie dynamisch zu gestalten. Diese diegetischen Elemente können auch Spielern helfen, die unter Motion Sickness leiden – insbesondere bei XR-Formfaktoren. Sie bieten eine Hilfe zur Barrierefreiheit im Internet und tragen dazu bei, die Komplexität neuer Seitenverhältnisse zu verringern.
Vermeiden Sie es, das Spiel auf einer Oberfläche innerhalb einer nicht interaktiven statischen Szene zu rendern. Dieser Ansatz ist zwar besser als das Rendern von schwarzen Balken für Letterboxen und Pillarboxen, aber Spieler bemerken statische Ränder schnell und können frustriert sein, wenn ihre Lieblingsspiele auf anderen Formfaktoren als Smartphones in einem Bereich in Smartphone-Größe gerendert werden.
|
In diesem Beispiel wird ein Spiel, das für ein Standard-Smartphone-Display entwickelt wurde, auf einem simulierten Fernseher mit einem skeuomorphen Gamepad gerendert, um das quadratischere Seitenverhältnis zu berücksichtigen, das auf den inneren Displays von faltbaren Geräten üblich ist:
|
Bei einigen 3D-Spielen muss das Sichtfeld möglicherweise aus Gründen der Fairness oder des Designs eingeschränkt werden. Es ist besser, das Sichtfeld durch ein Cockpit, einen Helm oder eine andere diegetische Metapher einzuschränken, als schwarze Balken zu verwenden:
|
Zusätzliche Ressourcen
- Unity-Spiele für alle Formfaktoren optimieren
- Spiel mit allen Formfaktoren kompatibel machen
- Natürliche Eingabe auf allen Formfaktoren aktivieren
- Geräteausrichtung mit Vulkan-Vorrotation verarbeiten