「Unity3D」在Unity中使用C#控制显示Android的状态栏

Unity打包的Android默认都是全屏,如果想要在真机上显示状态栏,就需要额外设置,有两种方式:

  • 第一种,使用Android的Java代码去控制,然后以插件的方式放到Unity中,被C#调用。
  • 第二种,使用Unity封装的C#代码,直接调用Android上的Java代码,去控制。

本文采用第二种方法,简单快捷,但会有几个坑,全部避开之后才能正确显示,先给正确代码,再指出踩坑点------只有一个函数,直接运行即可,内部精确控制,可以自定义。

cs 复制代码
private void ShowStatusBar()
{
    #if UNITY_ANDROID && !UNITY_EDITOR
    Screen.fullScreen     = false;
    using var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    using var activity    = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

    activity.Call
    (
        "runOnUiThread", new AndroidJavaRunnable
        (
            () =>
            {
                // WINDOW_FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS |
                // WINDOW_FLAG_FORCE_NOT_FULLSCREEN         | 
                // WINDOW_FLAG_LAYOUT_IN_SCREEN             | 
                // WINDOW_FLAG_TRANSLUCENT_STATUS
                var flags             = unchecked((int) 0x80000000) | 0x00000800 | 0x00000100 | 0x04000000;
                // VIEW_SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                // SYSTEM_UI_FLAG_LIGHT_STATUS_BAR (black text and icons)
                var uiOptions         = 0x00000400 | 0x00002000;        

                // the outer unityPlayer and activity will be disposed by other thread
                using var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
                using var activity    = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");                        
                using var window      = activity.Call<AndroidJavaObject>("getWindow");
                using var view        = window.Call<AndroidJavaObject>("getDecorView");

                // 0xAARRGGBB
                // window.Call("setStatusBarColor",  unchecked((int) 0xFF000000));
                window.Call("setFlags", flags,       unchecked((int) 0xFFFFFFFF));
                view  .Call("setSystemUiVisibility", uiOptions);
            }
        )
    );
    #endif
}   

需要注意的地方,在于:

  1. Screen.fullScreen = false------需要设置,否则状态栏会自动隐藏。

  2. runOnUiThread------需要控制Android UI的调用,在UI线程中执行。

  3. window.setFlags ------设置布局,view.setSystemUiVisibility------设置外观。

  4. unchecked((int) 0x80000000)------这个越界int类型了,C#向Java传递会有问题,需要控制一下溢出。

  5. unityPlayeractivity------在匿名函数中需要重新获取,外部的会在外层函数结束时释放资源,内部的在UI线程中执行,所以不能用闭包捕获外层的使用。

  6. setFlags 的第二个mask 参数------这个0xFFFFFFFF 会越界int类型,需要unchecked一下。

多布 局与外观 的控制,查看WINDOW_FLAG_SYSTEM_UI_FLAG 的设定,添加到flagsuiOptions即可,注意int类型的越界处理。

相关推荐
SmalBox1 小时前
【节点】[Adjustment-WhiteBalance节点]原理解析与实际应用
unity3d·游戏开发·图形学
那个村的李富贵1 小时前
Unity打包Webgl后 本地运行测试
unity·webgl
nnsix2 小时前
Unity OpenXR开发HTC Vive Cosmos
unity·游戏引擎
nnsix2 小时前
Unity OpenXR,扳机键交互UI时,必须按下扳机才触发
unity·游戏引擎
nnsix3 小时前
Unity XR 编辑器VR设备模拟功能
unity·编辑器·xr
老朱佩琪!3 小时前
Unity访问者模式
unity·游戏引擎·访问者模式
不定时总结的那啥3 小时前
Unity实现点击Console消息自动选中预制体的方法
unity·游戏引擎
nnsix3 小时前
Unity OpenXR 关闭手柄的震动
unity·游戏引擎
CreasyChan4 小时前
Unity 中的反射使用详解
unity·c#·游戏引擎·游戏开发
Jessica巨人4 小时前
Shader显示为黑色
unity·shader