Unity-WebGL适配手机横屏

文章目录[x]
  1. 0.1:方案一
  2. 0.2:方法二

方案一


强制横屏,通过代码控制css,让整个body逆时针旋转90度

> 总结:可以实现旋转效果,但是unity的canvas触摸的方向没有更改。比如鼠标上下移动,但unitywebgl逻辑识别成水平移动。
// 初始化横屏
    // 利用 CSS3 旋转 对根容器逆时针旋转 90 度
    var detectOrient = function () {
      var width = document.documentElement.clientWidth,
        height = document.documentElement.clientHeight,
        $wrapper = document.getElementsByTagName('body')[0],
        style = "";
      if (width >= height) { // 横屏
        style += "width:" + width + "px;"; // 注意旋转后的宽高切换
        style += "height:" + height + "px;";
        style += "-webkit-transform: rotate(0); transform: rotate(0);";
        style += "-webkit-transform-origin: 0 0;";
        style += "transform-origin: 0 0;";
        console.log(1)
      } else { // 竖屏
        style += "width:" + height + "px;";
        style += "height:" + width + "px;";
        style += "-webkit-transform: rotate(90deg); transform: rotate(90deg);";
        // 注意旋转中点的处理
        style += "-webkit-transform-origin: " + width / 2 + "px " + width / 2 + "px;";
        style += "transform-origin: " + width / 2 + "px " + width / 2 + "px;";
        console.log(2)
      }
      $wrapper.style.cssText = style;
    }
    setTimeout(() => {
      window.onresize = detectOrient;
      detectOrient();
    }, 400)
>参考资料:
>https://blog.csdn.net/weixin_44461275/article/details/121978732

方法二


调用H5的API:window.screen.orientation.lock('landscape-primary')
>总结:效果好,但不是所有浏览器都支持。比如微信内置的浏览器

  1. 在unity中新建一个文件夹Plugins,新建文件orientationdetector.jslib
    var OrientationDetectorLib = {
        $JS_OrientationDetectorLib_Context: {},
    
        JS_OrientationDetectorLib_Init: function (eventHandler) {
            JS_OrientationDetectorLib_Context.eventHandler = eventHandler;
            JS_OrientationDetectorLib_Context.cnv = document.querySelector('canvas');
            if (window.screen && screen.orientation) {
                window.addEventListener('orientationchange', function () {
                    window.onresize = function () {
                        window.onresize = null;
                        if (JS_OrientationDetectorLib_Context.eventHandler) {
                            Module.dynCall_vi(JS_OrientationDetectorLib_Context.eventHandler, window.screen.orientation.angle);
                        }
                    };
                });
                return 0;
            } else {
                return -1;
            }
        },
    
        JS_OrientationDetectorLib_GetOrientation: function () {
            if (window.screen && screen.orientation) {
                return window.screen.angle;
            } else {
                return -1;
            }
        },
    
        JS_OrientationDetectorLib_FullScreen: function () {
            if (JS_OrientationDetectorLib_Context.cnv)
                JS_OrientationDetectorLib_Context.cnv.requestFullscreen();
        },
    
        JS_OrientationDetectorLib_ExitFullScreen: function () {
            if (JS_OrientationDetectorLib_Context.cnv)
                document.exitFullscreen();
        },
    
        JS_OrientationDetectorLib_Lock: function () {
            _JS_OrientationDetectorLib_FullScreen();
            setTimeout(function () {
                window.screen.orientation.lock('landscape-primary').then(function() {
                    console.log('lock success');
                    JS_OrientationDetectorLib_Context.isScreenLock = true;
                }).catch(function() {
                    console.log('could not lock');
                });
            }, 0);
        },
    
        JS_OrientationDetectorLib_Unlock: function () {
            if (JS_OrientationDetectorLib_Context.isScreenLock) {
                screen.orientation.unlock();
                JS_OrientationDetectorLib_Context.isScreenLock = false;
            }
        }
    };
    
    autoAddDeps(OrientationDetectorLib, '$JS_OrientationDetectorLib_Context');
    mergeInto(LibraryManager.library, OrientationDetectorLib);

    2.在unity中新建一个脚本MobileOrientationDetector.cs

    using AOT;
    using System;
    using System.Runtime.InteropServices;
    using UnityEngine;
    using UnityEngine.Events;
    
    public class MobileOrientationDetector : MonoBehaviour
    {
        public delegate void dlgOrientationChange(int angle);
        public static event dlgOrientationChange OnOrientationChange;
        
        [DllImport("__Internal")]
        private static extern int JS_OrientationDetectorLib_Init(Action<int> eventHandler);
    
        [DllImport("__Internal")]
        private static extern int JS_OrientationDetectorLib_GetOrientation();
    
        [DllImport("__Internal")]
        private static extern void JS_OrientationDetectorLib_FullScreen();
        
        [DllImport("__Internal")]
        private static extern void JS_OrientationDetectorLib_ExitFullScreen();
    
        [DllImport("__Internal")]
        private static extern void JS_OrientationDetectorLib_Lock();
    
        [DllImport("__Internal")]
        private static extern void JS_OrientationDetectorLib_Unlock();
    
    
        [MonoPInvokeCallback(typeof(Action<int>))]
        private static void onOrientationChange (int angle)
        {
            OnOrientationChange.Invoke(angle);
        }
    
        //初始化
        public static void Init()
        {
            var res = JS_OrientationDetectorLib_Init(onOrientationChange);
            if (res == -1)
            {
                throw new Exception("This device does not support Screen Orientation API");
            }
        }
        //获取屏幕旋转角度
        public static int GetOrientation()
        {
            var angle = JS_OrientationDetectorLib_GetOrientation();
            return angle;
        }
    
        //竖屏全屏
        public static void FullScreen()
        {
            JS_OrientationDetectorLib_FullScreen();
        }
    
        //退出全屏
        public static void ExitFullScreen()
        {
            JS_OrientationDetectorLib_ExitFullScreen();
        }
    
        //横屏全屏
        public static void ScreenLock()
        {
            JS_OrientationDetectorLib_Lock();
        }
    
        //退出横屏
        public static void ScreenUnlock()
        {
            JS_OrientationDetectorLib_Unlock();
        }
    }

    3.使用的时候首先调用初始化方法

    > 参考资料
    > https://github.com/gtk2k/UnityWebGLOrientationDetectSample
    >https://stackoverflow.com/questions/60501159/how-to-force-landscape-mode-when-using-mobile-browser-unity-webgl
    线上测试地址:http://webgl.horse7.cn/webgl    使用手机测试

    博客编辑器太难用了~~~ 格式跟markdown的差别很大

点赞
  1. mio宝说道:

    EntryPointNotFoundException: JS_OrientationDetectorLib_Init
    MobileOrientationDetector.Init () (at Assets/Scripts/MobileOrientationDetector.cs:46)
    Test.Start () (at Assets/Scripts/Test.cs:59)
    怎么搞

    1. yuan说道:

      你也在搞这个吗?我有个笨方法是旋转相机,就是感觉做起来奇怪

      1. Alan Alan说道:

        我现在觉得旋转相机是最实用的,UI也做两套,根据横屏竖屏去加载不同的ui。

        1. yuan说道:

          确实,刚开始我用你的第一种方法觉得很方便,可是做交互的时候就会出现点击位置没发生变化的问题,当时我还想了种方案就是UI用h5写,3D用unity搞,然后用h5和unity进行交互 0.0

  2. yuan说道:

    我使用第一种方式Unity的Canvas的Button的UI发生了旋转,但是点击位置没变0.0

发表回复

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像