unity 安卓适配刘海屏,水滴屏,异性屏

Posted 阿尼阿兹(⊙_⊙)?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity 安卓适配刘海屏,水滴屏,异性屏相关的知识,希望对你有一定的参考价值。

手机厂商一群弄潮儿,每次都能玩出新花样,各种奇形怪状的手机屏幕,为了增加玩家的沉浸感,我们开发游戏的话必须对异性屏幕进行适配。

一般安卓方法适配其实网上有很多方案了,主流的一套还是谷歌官方的接口,挖孔屏

首先是安卓p版本(apilv 28)以下的适配

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
    
        String result = getNotchByManufacturer();
           
        return;
    
public static String getNotchByManufacturer()
    
        Context context = UnityPlayer.currentActivity;
        String manufacturer = Build.MANUFACTURER.toLowerCase();

        String result = MANU_NONE;
        if(TextUtils.equals(manufacturer, "huawei"))
        
            if (hasNotchInHuawei(context))
                result = NOTCH_TYPE_HUAWEI;
        
        else if(TextUtils.equals(manufacturer, "xiaomi"))
        
            if (hasNotchInMIUI(context))
                result = NOTCH_TYPE_MIUI;
        
        else if(TextUtils.equals(manufacturer, "oppo"))
        
            if (hasNotchInOppo(context))
                result = NOTCH_TYPE_OPPO;
        
        else if(TextUtils.equals(manufacturer, "vivo"))
        
            if (hasNotchInVivo(context))
                result = NOTCH_TYPE_VIVO;
        
        else if(TextUtils.equals(manufacturer, "smartisan"))
        
            if (hasNotchInSmart(context))
                result = NOTCH_TYPE_SMART;
        
        else
            result = ApiUnsupported;

        return result;
    

一般手机厂商都会给适配方案的

<meta-data
 android:name="notch.config"
 android:value="portrait|landscape"/>

使用该接口。在 Application 下增加一个 meta-data,是否使用耳朵区域

华为:https://devcenter-test.huawei.com/consumer/cn/devservice/doc/50114
小米:https://dev.mi.com/console/doc/detail?pId=1293
Oppo:https://open.oppomobile.com/service/message/detail?id=61876
Vivo:https://dev.vivo.com.cn/documentCenter/doc/103
 

public static boolean hasNotchInMIUI(Context context)
    
        try
        
            return SystemProperties.getInt("ro.miui.notch", 0) == 1;
        
        catch(Exception e)
        
            e.printStackTrace();
        
        return false;
    

    /**
     * OPPO
     *
     * @param context Context
     * @return hasNotch
     */
    public static boolean hasNotchInOppo(Context context)
    
        return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
    

    /**
     * VIVO
     * <p>
     * android.util.FtFeature
     * public static boolean isFeatureSupport(int mask);
     * <p>
     * 参数:
     * 0x00000020表示是否有凹槽;
     * 0x00000008表示是否有圆角。
     *
     * @param context Context
     * @return hasNotch
     */
    private static int VIVO_NOTCH = 0x00000020;//是否有刘海
    private static int VIVO_FILLET = 0x00000008;//是否有圆角
    public static boolean hasNotchInVivo(Context context)
    
        boolean hasNotch = false;
        try
        
            ClassLoader cl = context.getClassLoader();
            Class FtFeature = cl.loadClass("android.util.FtFeature");
            Method method = FtFeature.getMethod("isFeatureSupport", int.class);
            hasNotch = (boolean) method.invoke(FtFeature, VIVO_NOTCH);
        
        catch (Exception e)
        
            e.printStackTrace();
        
        return hasNotch;
    

    /**
     * HUAWEI
     * com.huawei.android.util.HwNotchSizeUtil
     * public static boolean hasNotchInScreen()
     *
     * @param context Context
     * @return hasNotch
     */
    public static boolean hasNotchInHuawei(Context context)
    
        boolean hasNotch = false;
        try 
            ClassLoader cl = context.getClassLoader();
            Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("hasNotchInScreen");
            hasNotch = (boolean) get.invoke(HwNotchSizeUtil);
         catch (Exception e) 
            e.printStackTrace();
        
        return hasNotch;
    


    public static boolean hasNotchInSmart(Context context)
    
        boolean hasNotch = false;
        try
        
            Class<?> DisplayUtilsSmt = Class.forName("smartisanos.api.DisplayUtilsSmt");
            Method isFeatureSupport = DisplayUtilsSmt.getMethod("isFeatureSupport", int.class);
            hasNotch = (boolean) isFeatureSupport.invoke(DisplayUtilsSmt, 0x00000001);
            return hasNotch;
        
        catch (Exception e)
        
            e.printStackTrace();
        
        return hasNotch;
    

安卓p以上的话,谷歌提供了接口去获取是否支持切口屏幕,并且返回切口的位置大小

 protected static boolean isNotchEnable(Activity activity)
    
        DisplayCutout displayCutout = activity.getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
        if(displayCutout == null || displayCutout.getBoundingRects() == null || displayCutout.getBoundingRects().size() == 0)
            return false;
        
        return true;
    

    @TargetApi(Build.VERSION_CODES.P)
    protected static int[] getNotchInfo(Activity activity)
    
        int[] notchSize = new int[]0,0;
        DisplayCutout displayCutout = activity.getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
        List<Rect> boundingRects = displayCutout.getBoundingRects();
        if(boundingRects.size() != 0)
        
            Rect rect = boundingRects.get(0);
            notchSize[0] = rect.width();
            notchSize[1] = rect.height();
        
        return notchSize;
    

这些其实网上有很多教程已经说过了,说一下我遇到的问题吧,

首先是,unity需要勾选安全区域外渲染

不然还是会有缺口,然后,安卓xml里面需要设置

 max_aspect 代表屏幕比例哈,2400/1080 = 2.222;

在适配vivo时遇到个问题,他默认不打开刘海区域,需要在mainactivity 的oncreate加入全面屏

 @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 允许内容去延伸进刘海区
private static void SetWindowLayoutInDisplayCutoutMode(Activity act)
	
		WindowManager.LayoutParams lp = act.getWindow().getAttributes();
		lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
		act.getWindow().setAttributes(lp);
	

 一般刘海适配的方案,在游戏里面就是吧ui缩放,位移,这里面有个回答不错

如何使用unity的ugui适配iPhoneX的齐刘海屏幕? - 知乎

他采取的策略是锚点向中靠拢.

我们游戏是横屏的,我做的是检查屏幕选择,然后挖孔的一方位移.主要使用ScreenOrientation.LandscapeLeft

和Screen.orientation类

if self._isleftOrientation ~= Screen.orientation then
		self:RefreshUIWithNotch()
		self._isleftOrientation = Screen.orientation
	end

关于锚点还是锚边,不同的策略

AnchorMin和AnchorMax相等的话,就是锚点,直接AnchorPos.x - notchSizeX就行了

如果是stretch的,会随屏幕改变大小,anchorPos.x =AnchorPos.x + notchSizeX * (1 - beginPivot.x)

大概就是这样吧

好家伙,iphone已经不满足张雨绮屏幕了,开始水滴屏了,iPhone我们的策略是iPhone 平台直接写死大小,ios平台rawset(self, "_notchSize", Vector2(70, 200))

               

Android 屏幕适配异形屏适配 ① ( 异形屏类型:刘海屏水滴屏挖孔屏 | 沉浸式布局刘海屏适配 | 华为手机异形屏适配注意点 )

文章目录


屏幕适配参考文档 :


异形屏适配参考文档 :


异形屏适配难点是 需要针对 不同的手机厂商 , 不同的 Android 系统版本 进行适配 ;





一、异形屏类型:刘海屏、水滴屏、挖孔屏



Android 手机除了正常屏幕之外 , 还存在异形屏 , 这些屏幕也需要进行适配 ;

异形屏有 刘海屏、水滴屏、挖孔屏 3 3 3 种类型 ;

  • 刘海屏 : 在屏幕上方中间位置 , 有一块矩形刘海 ;

  • 水滴屏 : 在屏幕上方中间位置有一个水滴状摄像头 ;

  • 挖孔屏 : 屏幕上方不规则的挖孔 , 一般是摄像头位置 ;





二、沉浸式布局刘海屏适配



如果使用 沉浸式布局 , 具体的布局只在 耳朵区刘海 的下面 , 上部分的耳朵区 没有实际的布局组件 , 空着 ;

如果 Android 的 Activity 组件 不是全屏 的 , 那么 耳朵区的内容是状态栏 ;

如果 Activity 组件是 全屏的 , 那么就需要将耳朵区设置成沉浸式背景 ; 在 耳朵区 , 将 沉浸式的背景 填充到该区域 ;





三、华为手机异形屏适配注意点



华为手机的 刘海屏 的 刘海 和 耳朵区 是可以设置为黑屏状态的 ; 华为手机可以设置 启用刘海 , 也可以关闭刘海 ;

  • 如果关闭了刘海 , 则 不启用异形屏适配 ;

  • 如果 开启了刘海 , 才进行适配 ;

以上是关于unity 安卓适配刘海屏,水滴屏,异性屏的主要内容,如果未能解决你的问题,请参考以下文章

Android 屏幕适配异形屏适配 ① ( 异形屏类型:刘海屏水滴屏挖孔屏 | 沉浸式布局刘海屏适配 | 华为手机异形屏适配注意点 )

unity屏幕适配

unity — 屏幕适配(异形屏)

Android刘海屏水滴屏全面屏适配详解大厂直通车!

Android 刘海屏适配

Android 屏幕适配异形屏适配 ② ( 需要异形屏适配情况 | 需要异形屏适配的 Android 系统版本 | 刘海屏状态判定 | 异形屏适配调试 - 华为云调试 )