FairyGUI-Unity 异形屏适配

本文中会修改到FairyGUI源代码,涉及两个文件Stage和StageCamera,需要对Unity的屏幕类了解。

在网上查找有很多的异形屏适配操作,但对于FairyGUI相关的描述操作很少,这里我贴出一下自己在实际应用中的异形屏UI适配操作。

原理

获取当前设备的屏幕安全区域并设置为UI的正常显示尺寸,通过屏幕安全区域和实际分辨率修改UI背景的位置和尺寸。注意UI在设计中将溢出处理设置为默认“可见”。

关键方法:SetXY(x,y);SetSize(width,height)

打开Stage脚本,在构造函数中找到方法:

SetSize(Screen.width, Screen.height)

通过方法可以看到默认直接设置屏幕的宽高,将其修改为屏幕安全区域的宽高,这里我做了对称处理:

var safeArea = Screen.safeArea;
int safeAreaWidth = Mathf.CeilToInt(safeArea.width - safeArea.x);
int safeAreaHeight = safeArea.height;
SetSize(safeAreaWidth, safeAreaHeight);

打开StageCamera脚本,将OnEnable方法中的默认屏幕尺寸修改为安全区域的尺寸。

OnScreenSizeChanged(Screen.width, Screen.height);

修改为:

OnScreenSizeChanged(_safeAreaWidth, _safeAreaHeight);

 将Update中的屏幕分辨率检测也一同修改为安全区域分辨率检测:

if (screenWidth != Screen.width || screenHeight != Screen.height)OnScreenSizeChanged(Screen.width, Screen.height);

修改为:

if (screenWidth != _safeAreaWidth || screenHeight != _safeAreaHeight)OnScreenSizeChanged(_safeAreaWidth, _safeAreaHeight);

之后在UI界面中,将背景的位置和大小修改为屏幕实际分辨率和安全区域外的位置。

SetXY(-Screen.safeArea.x,Screen.safeArea.y)
SetSize(Screen.width,Screen.height)

完整代码参考

Stage修改后的构造方法

/// <summary>
/// 
/// </summary>
public Stage(): base()
{_inst = this;soundVolume = 1;_updateContext = new UpdateContext();_frameGotHitTarget = -1;_touches = new TouchInfo[5];for (int i = 0; i < _touches.Length; i++)_touches[i] = new TouchInfo();bool isOSX = Application.platform == RuntimePlatform.OSXPlayer|| Application.platform == RuntimePlatform.OSXEditor;if (Application.platform == RuntimePlatform.WindowsPlayer|| Application.platform == RuntimePlatform.WindowsEditor|| isOSX)touchScreen = false;elsetouchScreen = Input.touchSupported && SystemInfo.deviceType != DeviceType.Desktop;//在PC上,是否retina屏对输入法位置,鼠标滚轮速度都有影响,但现在没发现Unity有获得的方式。仅判断是否Mac可能不够(外接显示器的情况)。所以最好自行设置。devicePixelRatio = (isOSX && Screen.dpi > 96) ? 2 : 1;_rollOutChain = new List<DisplayObject>();_rollOverChain = new List<DisplayObject>();_focusOutChain = new List<DisplayObject>();_focusInChain = new List<DisplayObject>();_focusHistory = new List<Container>();_cursors = new Dictionary<string, CursorDef>();//根据开关修改UI实际的分辨率if (GF.Main.Inst.enableSafeArea)//加一个启用安全区的开关{var safeArea = Screen.safeArea;int safeAreaWidth = Mathf.CeilToInt(safeArea.width - safeArea.x);int safeAreaHeight = Mathf.CeilToInt(safeArea.height + safeArea.y);SetSize(safeAreaWidth, safeAreaHeight);}elseSetSize(Screen.width, Screen.height);this.cachedTransform.localScale = new Vector3(StageCamera.DefaultUnitsPerPixel, StageCamera.DefaultUnitsPerPixel, StageCamera.DefaultUnitsPerPixel);StageEngine engine = GameObject.FindObjectOfType<StageEngine>();if (engine != null)UnityEngine.Object.Destroy(engine.gameObject);this.gameObject.name = "Stage";this.gameObject.layer = LayerMask.NameToLayer(StageCamera.LayerName);this.gameObject.AddComponent<StageEngine>();this.gameObject.AddComponent<UIContentScaler>();this.gameObject.SetActive(true);UnityEngine.Object.DontDestroyOnLoad(this.gameObject);EnableSound();Timers.inst.Add(5, 0, RunTextureCollector);SceneManager.sceneLoaded += SceneManager_sceneLoaded;
}

StageCamera的修改后完整代码

private Rect _safeArea;
private int _safeAreaWidth, _safeAreaHeight;
void OnEnable()
{_safeArea = Screen.safeArea;_safeAreaWidth = Mathf.CeilToInt(_safeArea.width - _safeArea.x);_safeAreaHeight = _safeArea.height;cachedTransform = this.transform;cachedCamera = this.GetComponent<Camera>();if (this.gameObject.name == Name){main = cachedCamera;isMain = true;}if (Display.displays.Length > 1 && cachedCamera.targetDisplay != 0 && cachedCamera.targetDisplay < Display.displays.Length)_display = Display.displays[cachedCamera.targetDisplay];if (_display == null){if (GF.Main.Inst.enableSafeArea)//加一个启用安全区的开关{OnScreenSizeChanged(_safeAreaWidth, _safeAreaHeight);}elseOnScreenSizeChanged(Screen.width, Screen.height);}elseOnScreenSizeChanged(_display.renderingWidth, _display.renderingHeight);
}
void Update()
{if (_display == null){if (GF.Main.Inst.enableSafeArea)//加一个启用安全区的开关{if (screenWidth != _safeAreaWidth || screenHeight != _safeAreaHeight)OnScreenSizeChanged(_safeAreaWidth, _safeAreaHeight);}else{if (screenWidth != Screen.width || screenHeight != Screen.height)OnScreenSizeChanged(Screen.width, Screen.height);}}else{if (screenWidth != _display.renderingWidth || screenHeight != _display.renderingHeight)OnScreenSizeChanged(_display.renderingWidth, _display.renderingHeight);}
}

UI界面中设置背景组件名为“_Loader_Bg”的位置和大小。注意UI在设计中将溢出处理设置为默认“可见”。

if ( _Loader_Bg != null)
{_Loader_Bg.SetXY(-Screen.safeArea.x,Screen.safeArea.y);_Loader_Bg.SetSize(Screen.width,Screen.height);
}

以上是对FairyGUI在设计横版游戏时对异形屏的适配操作,竖版游戏也是同理操作。如果对你有帮助,那就好!有问题也可以留言指出!感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/56395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫逆向实战案例(五)——YRX竞赛题第五题

题目&#xff1a;抓取全部5页直播间热度&#xff0c;计算前5名直播间热度的加和 地址&#xff1a;https://match.yuanrenxue.cn/match/5 cookie中m值分析 首先打开开发者工具进行抓包分析&#xff0c;从抓到的包来看&#xff0c;参数传递了查询参数m与f&#xff0c;同时页面中…

C++数据结构学习——双向循环链表

双向循环链表特点 **双向链接&#xff1a;**每个节点都包含两个指针&#xff0c;一个指向前一个节点&#xff08;前驱节点&#xff09;&#xff0c;另一个指向后一个节点&#xff08;后继节点&#xff09;。这种双向连接使得在链表中可以轻松地在两个方向上遍历节点。 **循环…

uniapp scrollview 滚动最新位置

uniapp 效果是模拟发送聊天信息&#xff0c;需要scrollview在收到新消息时滚动到底部最新的位置 项目是vue2的&#xff0c;代码如下 // 第一种 高度固定值 scrollToBottom(selector) {this.$nextTick(() > {const dom uni.createSelectorQuery().in(this).select(selecto…

手机自动无人直播,实景无人直播真的有用吗?

继数字人直播之后&#xff0c;手机自动直播开始火热了起来&#xff0c;因为其门槛低&#xff0c;成本低&#xff0c;一部手机一个账号就可以实现直播&#xff0c;一时深受广大商家的好评。那么&#xff0c;手机自动无人直播究竟是如何实现自动直播的呢&#xff1f; 在传统的直…

【Golang】什么是内存逃逸?

文章目录 要从C/C谈起Golang的内存逃逸 要从C/C谈起 在C/C中&#xff0c;局部变量被分配到栈区&#xff0c;一旦当前函数执行完毕&#xff0c;局部变量占用的内存也将被释放&#xff0c;因此以下代码无法将数组的内容传递出去。 int *getArray() {int array[7] {1, 2, 3, 4,…

什么是数据中心IP,优缺点是什么?

如果根据拥有者或者说发送地址来分类的话&#xff0c;可以将代理分为三类&#xff1a;数据中心ip,住宅ip,移动ip 本文我们来了解数据中心ip的原理以及他们的优势劣势&#xff0c;才能选择适合自己的代理。 一、什么是数据中心ip代理&#xff1f; 数据中心ip是由数据中心拥有…

victoriametrics获取指标情况脚本

get_job.sh脚本 #!/bin/bash #获取所有的job list&#xff0c;循环获取vm的job指标推送量&#xff0c;累加整个x月份的指标推送量#线下 #ip_port"x.x.x.x:80" #线上 ip_port"x.x.x.x:80"get_jobcurl -sG "http://$ip_port/select/0/prometheus/api/v…

浏览器输入一个URL之后发生了什么?

URL解析DNS解析TCP连接TSL连接HTTP请求TCP挥手接收并解析响应 URL 解析 主要分为&#xff1a; 协议&#xff0c;eg http,https域名或者ip地址&#xff0c;eg www.baidu.com 域名相对于ip地址来说&#xff0c;更方便人们记忆&#xff0c;但是实际的网络传输中使用的是ip地址 端…

一、使用maven新建springboot

1. 新建maven项目 2. 修改pom.xml文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http:…

SSM框架和Spring Boot+Mybatis框架的性能比较?

SSM框架和Spring BootMybatis框架的性能比较&#xff0c;没有一个绝对的答案&#xff0c;因为它们的性能受到很多因素的影响&#xff0c;例如项目的规模、复杂度、需求、技术栈、团队水平、测试环境、测试方法等。因此&#xff0c;我们不能简单地说哪个框架的性能更好&#xff…

widnows 制作winpe启动盘

下载 官网 大白菜官网,大白菜winpe,大白菜U盘装系统, u盘启动盘制作工具 点击装机版&#xff0c;进行下载&#xff0c;等待下载完成 安装 解压 双击exe运行 插入u盘 识别到的u盘 点击【一键制作成usb启动盘】 点击确定&#xff0c;等待制作完成 重启电脑&#xff0c;选择从…

机器学习深度学习——NLP实战(自然语言推断——微调BERT实现)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——针对序列级和词元级应用微调BERT &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文…

LeetCode5:最长回文子串、LeetCode647:回文子串

文章目录 LeetCode647&#xff1a;回文子串题目示例提示解题思路解题代码复杂度 LeetCode5:最长回文子串题目示例提示解题思路解题代码复杂度 总结 LeetCode647&#xff1a;回文子串 题目 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字…

Module not found: Error: Can‘t resolve ‘vue-pdf‘ in ‘xxx‘

使用命令npm run serve时vue项目报错&#xff1a; Module not found: Error: Cant resolve vue-pdf in xxx 解决方案&#xff1a; 运行命令&#xff1a; npm install vue-pdf --save --legacy-peer-deps 即可解决。 再次顺利执行npm run serve

webrtc在js里的实现

WebRTC&#xff08;Web Real-Time Communication&#xff09;是一项开放的浏览器技术&#xff0c;它允许浏览器之间建立点对点&#xff08;peer-to-peer&#xff09;连接&#xff0c;实现音频、视频、文件的传输和通信。它的实现一般需要使用JavaScript语言。 在JavaScript中&…

Linux系统USB摄像头测试程序(四)_视频旋转及缩放

下面的程序实现了视频的旋转及缩放&#xff0c;窗口中点击鼠标左键视频向左旋转&#xff0c;点击鼠标右键视频向右旋转并且视频缩小了二分之一。程序中首先把yvyv422转换成了RGB24&#xff0c;然后利用opencv进行了旋转和缩放&#xff0c;其后用sdl2进行了渲染。使用了ffmpeg、…

问道管理:市盈率市净率两个指标含义怎么算?

市盈率和市净率是出资领域常用的两个目标&#xff0c;用于评价公司的估值和出资的报答状况。本文将从多个视点剖析这两个目标的含义和计算方法&#xff0c;帮助读者更好地了解和运用它们。首先&#xff0c;市盈率&#xff08;P/E ratio&#xff09;是用来衡量公司股票价格与每股…

程序运行的马甲:进程(1/7)

一个可执行文件被加载到内存中运行时&#xff0c;它在内存空间的分布如图所示&#xff1a; 在内存中有专门的堆栈空间&#xff0c;函数的局部变量是保存在栈中的&#xff0c;使用 malloc 申请的动态内存是在堆空间中分配的&#xff0c;它们是程序运行时比较特殊的两块内存区域&…

从上帝视角俯瞰vue2路由(简单易懂)

文章目录 路由原理&#xff08;hash&#xff09;路由安装和使用&#xff08;vue2&#xff09;路由跳转路由的传参和取值嵌套路由路由守卫完整代码 路由原理&#xff08;hash&#xff09; 单页应用的路由模式有两种 哈希模式&#xff08;利用hashchange 事件监听 url的hash 的…

php图片批量压缩并同时保持清晰度

php图片压缩可以通过GD库来实现。以下是一个使用GD库进行图片压缩的示例代码&#xff1a; // 原始图片路径 $sourceImage path/to/source/image.jpg; // 压缩后保存的路径及文件名 $compressedImage path/to/compressed/image.jpg; // 压缩后的图片质量&#xff08;1-100&…