Unity/ETC

[Unity] Android 빌드 시 Orientation 설정 변경

민트초밥 2023. 12. 26. 01:03

안드로이드 프로젝트 빌드 시 회 잠금 상태에서도 화면이 회전될 수 있게 하고 싶었다.

 

화면 회전 잠금 상태

 

 

 

Player Settings에 화면 회전에 대한 설정이 있어서 체크 후 빌드를 하면 Landscape 설정은 적용된다.

하지만 잠금 상태일 때 회전은 되지 않았다.

[Project Settings] - [Player] - [Resolution and Presentation]

 

 

 

apk 파일의 AndroidManifest.xml 파일을 확인해 보니 userLandscape로 설정되어 있어서 잠금상태 회전이 적용되지 않았다.

 

Android 개발자  |  Android Developers

애플리케이션의 시각적 사용자 인터페이스 일부를 구현하는 활동(Activity 서브클래스)을 선언합니다. 모든 활동은 매니페스트 파일의 {@code} 요소로 나타내야 합니다. 여기에 선언되지 않은 활동

developer.android.com

 

 

최신 유니티 버전(2023.3)에서는 user와 sensor를 선택할 수 있는 옵션이 있는데 이전 버전에서는 따로 기능이 없기 때문에 커스텀을 해야 한다.

 

심지어 유니티 버전마다 값이 달라서 똑같이 설정하고 빌드해도 2021.3.16f1은 userLandscape, 2019 버전에서는 sensorLandcape로 설정된다. (유니티 빌드 로직을 확인할 수 없어서 왜 그런지 모름....)

 

 

 

해결방법 (실패)

 

Custom Main Maniefest를 체크하면 AndroidManifest.xml 생성되면서 직접 수정할 수 있게 된다.

[Project Settings] - [Player] - [Resolution and Presentation]

 

 

<activity>에 android:screenOrientation="sensorLandscape" 를 추가

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools">
    <application>
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:theme="@style/UnityThemeSelector"
				  android:screenOrientation="sensorLandscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
</manifest>

 

 

빌드 후의 AndroidManifest.xml 파일을 확인했더니 sensorLandscape로 설정했음에도 다시 userLandscape로 변경됐다.

<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="30" android:compileSdkVersionCodename="11" android:installLocation="preferExternal" package="com.unity.player" platformBuildVersionCode="30" platformBuildVersionName="11">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true"/>
    <uses-feature android:glEsVersion="0x00030000"/>
    <uses-feature android:name="android.hardware.vulkan.version" android:required="false"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
    <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false"/>
    <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false"/>
    <application android:extractNativeLibs="true" android:icon="@mipmap/app_icon" android:label="@string/app_name">
        <activity android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:hardwareAccelerated="false" android:launchMode="singleTask" android:name="com.unity3d.player.UnityPlayerActivity" android:resizeableActivity="false" android:screenOrientation="userLandscape" android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
            <meta-data android:name="android.notch_support" android:value="true"/>
        </activity>
        <meta-data android:name="unity.splash-mode" android:value="0"/>
        <meta-data android:name="unity.splash-enable" android:value="true"/>
        <meta-data android:name="unity.launch-fullscreen" android:value="true"/>
        <meta-data android:name="unity.allow-resizable-window" android:value="false"/>
        <meta-data android:name="notch.config" android:value="portrait|landscape"/>
    </application>
</manifest>

 

 

 

 

해결방법 (성공)

 

빌드 시작 전에 콜백을 수신할 수 있는 함수가 있다.

 

Unity - Scripting API: Android.IPostGenerateGradleAndroidProject.OnPostGenerateGradleAndroidProject

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

 

빌드 시작전 AndroidManifest.xml 파일을 수정할 수 있는 코드를 추가

 

using UnityEngine;
using System.Xml;

#if UNITY_EDITOR
using UnityEditor.Android;

public class TestOrientation : IPostGenerateGradleAndroidProject
{
    public int callbackOrder { get => 0; }

    public void OnPostGenerateGradleAndroidProject(string path)
    {
        XmlDocument xmlDoc = new XmlDocument();

        var filePath = $"{path}/src/main/AndroidManifest.xml";

        xmlDoc.Load(filePath);

        var node = xmlDoc.SelectSingleNode("manifest/application");

        node.InnerXml = node.InnerXml.Replace("userLandscape", "sensorLandscape");

        xmlDoc.Save(filePath);
    }
}
#endif

 

 

android:screenOrientation="sensorLandscape"가 정상적으로 적용됐다.

<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="30" android:compileSdkVersionCodename="11" android:installLocation="preferExternal" package="com.unity.player" platformBuildVersionCode="30" platformBuildVersionName="11">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true"/>
    <uses-feature android:glEsVersion="0x00030000"/>
    <uses-feature android:name="android.hardware.vulkan.version" android:required="false"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
    <uses-feature android:name="android.hardware.touchscreen.multitouch" android:required="false"/>
    <uses-feature android:name="android.hardware.touchscreen.multitouch.distinct" android:required="false"/>
    <application android:extractNativeLibs="true" android:icon="@mipmap/app_icon" android:label="@string/app_name">
        <activity android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode" android:hardwareAccelerated="false" android:launchMode="singleTask" android:name="com.unity3d.player.UnityPlayerActivity" android:resizeableActivity="false" 
        android:screenOrientation="sensorLandscape" android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
            <meta-data android:name="android.notch_support" android:value="true"/>
        </activity>
        <meta-data android:name="unity.splash-mode" android:value="0"/>
        <meta-data android:name="unity.splash-enable" android:value="true"/>
        <meta-data android:name="unity.launch-fullscreen" android:value="true"/>
        <meta-data android:name="unity.allow-resizable-window" android:value="false"/>
        <meta-data android:name="notch.config" android:value="portrait|landscape"/>
    </application>
</manifest>

 

반응형