针对大屏设备和可折叠设备优化 Unity 游戏

1. 简介

在此 Codelab 中,您将学习如何针对大屏设备和可折叠设备优化 Unity Android 游戏。您将使用 Lost Crypt 示例项目来实现宽高比支持、扩大全屏利用率,并响应可折叠设备状态。

前提条件

  • 对 Unity 和 Android 开发有基本的了解。
  • 大屏 Android 设备,例如平板电脑或折叠屏手机。

学习内容

  • 如何实现对各种宽高比的支持。
  • 如何在游戏界面和相机设置中使用锚点,以自动调整为适合屏幕尺寸。
  • 如何使用 Android 的 Jetpack Window Manager 检测设备的折叠状态并调整布局。

所需条件

  • Unity Hub 和编辑器:已安装 Unity 2020 LTS 或 Unity 2022,且支持 Android build。
  • 硬件:大屏 Android 设备,例如平板电脑或折叠屏手机。
  • 如果您计划使用该技能,请使用智能体式开发平台,例如 Google Antigravity。

2. Agent Skill

(可选)您可以使用代理技能来评估 Unity 游戏项目。此技能可帮助您添加对可调整大小的支持,以及对大屏设备和可折叠设备的支持。如需了解详情,请参阅:GitHub

如需使用此技能,请执行以下操作:

  1. 将 SKILL.md 文件复制到您的代理目录。如需详细了解如何添加技能,请参阅 Google Antigravity 使用入门。
  2. 在智能体 IDE(例如 Antigravity)中,向智能体提出有关大屏设备、可折叠设备或尺寸调整的问题。
  3. 让代理添加对大屏幕和可折叠设备的支持。

3. 宽高比支持

为确保游戏在不同屏幕尺寸下都能正常显示,请先实现对各种宽高比的支持。您可以考虑调整相机或画布的宽高比,以更好地适应不同的屏幕。

  1. 确保您的应用使用全屏可调整大小的设置。
  2. 在您的 AndroidManifest.xml(位于 Assets/Plugins/Android/AndroidManifest.xml):
    1. 设置 android:resizeableActivity="true"。
    2. 设置 android:screenOrientation="fullSensor"。

例如:

<?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.unity.lostcryptlargescreenexample.LargeScreenPlayableActivity"
                  android:theme="@style/UnityThemeSelector"
                  android:screenOrientation="fullSensor"
                  android:launchMode="singleTask"
                  android:resizeableActivity="true"
                  android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
                  android:hardwareAccelerated="false">
            <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>
  1. 在 Unity 中检查 Build Settings 中的 Android 平台配置。

注意:支持各种宽高比是让游戏在平板电脑和可折叠设备上呈现出色效果的第一步。

4. 全屏利用率

在适应不同的宽高比后,请确保游戏使用整个屏幕,以提供更具沉浸感的游戏体验。

如需使用整个屏幕,请执行以下操作:

  1. 在游戏的界面和相机设置中使用锚点。这样一来,界面元素便可根据屏幕尺寸自动调整其位置。
  2. 打开示例项目中的 Anchoring 场景,了解界面画布锚定是如何设置的。
  3. 在锚定场景中,画布会更新为可识别安全框,并且移动控件会锚定到屏幕的各个角落。

为了保持主摄像头的宽高比,请动态调整摄像头的 pixelRect。CameraAspectLock.cs 脚本演示了如何响应屏幕方向变化以及如何将相机视图设为信箱模式:

[SerializeField]
private float minAspectRatio = 4f / 3f;

[SerializeField]
private float maxAspectRatio = 21f / 9f;

public void MaintainAspectRatio() {
    int viewWidth = Display.main.systemWidth;
    int viewHeight = Display.main.systemHeight;

    // 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;
    }

    // make sure to center the rect within the window
    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;
}

5. 可折叠设备支持

对于可折叠设备,您应根据设备的折叠姿态(例如 HALF_OPENED、FLAT)和屏幕尺寸动态调整游戏的布局。

  1. 使用 Android 的 Jetpack Window Manager 检测设备的状态。
  2. 在示例项目中,打开 HingeAware 场景。
  3. 此场景包含一个 ConfigurationManager MonoBehaviour,用于将 Android 的 Jetpack WindowManager 事件桥接到 Unity,并通过 UnityEvent 回调响应折叠状态。
  4. HingeSensor.cs 使用 com.unity.lostcryptlargescreenexample.HingeAngleSensor Java 插件读取铰链角度。

使用 ConfigurationManager

ConfigurationManager.cs 与自定义 Android activity 通信,并解析表示状态的 JSON 字符串。它会监听来自 Android Activity 的 onConfigurationChanged 和 onFoldChanged 回调。

[System.Serializable]
public class FoldInfo {
	public string orientation;
	public string state;
	public int isSeparating;
	public int boundsLeft;
	public int boundsTop;
	public int boundsRight;
	public int boundsBottom;
}

public void onFoldChanged(string strFoldInfo) {
	FoldInfo info = JsonUtility.FromJson<FoldInfo>(strFoldInfo);

	// Always call the refresh from the main Unity thread
	StartCoroutine(ExecuteOnMainUnityThread(ActionOnFoldChange, info));
}

您还可以使用 getFoldableState 属性同步查询状态:

public static string getFoldableState {
	get {
		if (Application.platform == RuntimePlatform.Android) {
			var foldingFeatureObject = foldablePlayerActivity.Call<AndroidJavaObject>("getFoldingFeature");
			if (foldingFeatureObject != null) {
				var state = foldingFeatureObject.Call<AndroidJavaObject>("getState");
				return state.Call<string>("toString");
			}
		}
		return "NONE";
	}
}

6. 利用 HingeSensor

部分可折叠设备具有实体铰链传感器,可提供精确的折叠角度(0 到 360 度)。您可以使用此功能来驱动游戏机制或调整相机。

在 HingeSensor.cs 中,Android 插件会初始化以读取硬件传感器。您还可以检查铰链是否已启用:

public class HingeSensor : IDisposable {
	AndroidJavaObject plugin;

	public static HingeSensor Start() {
		if (Application.platform == RuntimePlatform.Android) {
			return OnPlayer.Run(p => {
				var context = p.GetStatic<AndroidJavaObject>("currentActivity");
				var plugin = new AndroidJavaClass("com.unity.lostcryptlargescreenexample.HingeAngleSensor")
						.CallStatic<AndroidJavaObject>("getInstance", context);

				if (plugin != null) {
					plugin.Call("setupSensor");
					return new HingeSensor(plugin);
				}
				return null;
			});
		}
		return null;
	}

	public float GetHingeAngle() {
		return (Application.platform == RuntimePlatform.Android && plugin != null) ? plugin.Call<float>("getHingeAngle") : -1.0f;
	}

	public bool IsHingeEnabled() {
		return Application.platform == RuntimePlatform.Android && plugin != null && plugin.Call<int>("isHingeEnabled") > 0;
	}
}

注意:当应用暂停或销毁时,请务必在 HingeSensor 实例上调用 Dispose() 或 StopSensing(),以防止电池电量耗尽。

7. 创建 AAB 文件

如需在 Unity 编辑器中创建 AAB 文件,请按以下步骤操作:

  1. 在 Unity 编辑器中,依次点击文件 > build 设置。
  2. 选择 Build App Bundle ( Google Play )。如需了解详情,请参阅 Android Build Settings 参考。
  3. 点击 Build。
  4. 从 Unity 编辑器下载 AAB 文件。

创建内部测试版本

如需在 Play 管理中心内创建内部测试版本并添加测试人员,请执行以下步骤:

  1. 在 Google Play 管理中心内,选择一款游戏。
  2. 前往测试和发布页面(测试> 内部测试)。
  3. 点击上传,然后选择 AAB 文件。
  4. 在版本详细信息字段中,输入一个名称。
  5. 点击下一步,然后查看发布版本详情。
  6. 点击保存并发布。

8. 构建并运行项目

现在,您可以构建项目并在设备上进行测试了。

  1. 确保游戏已打开。
  2. 在 Play 管理中心内,前往文件 > 构建配置文件(或构建设置)。
  3. 如果您想上传到 Play 管理中心,请确保选中 Build App Bundle (Google Play);或者点击 Build and Run 以直接部署到已连接的设备。
  4. 对于可折叠设备,您应根据设备的折叠姿势(例如 HALF_OPENED、FLAT)和屏幕尺寸动态调整游戏布局。

9. 恭喜

恭喜!您已成功学习了如何让 Unity Android 游戏适配大屏设备和可折叠设备!

调查问卷

我们非常重视您对此 Codelab 的反馈。不妨花几分钟时间完成我们的调查问卷。