admin管理员组

文章数量:1570220

在开发中有时候会碰到需要展示tips说明信息的功能,比如打开道具列表,点击相应的道具并展示该道具的属性等详细信息,这时就有可能会出现tips的UI超出屏幕边界的问题。

因此这里做一个自适应的道具tips

首先需要设计tips的UI。

因为需要UI随着文本的长度自适应,确保始终能够显示全部的文本信息,因此Text的RectTransform也需要随着文本高度自动增加height,这里就会用到preferredHeight。

同时在Text自适应后,其外部的背景bg也需要根据Text来自动改变。

为了满足以上的两个需求,这里设计Tips的prefab为如下结构:

 

 

从以上结构可知,Tips相对于TipsBg是自适应的,并且保持上下左右完全对称。注意这里设置TipsBg的pivot为“0,1”,默认以鼠标点击位置为起点来显示tips

  

这样的结构就可以实现一个效果:当改变TipsBg的RectTransform的宽高时,由于Tips的sizeDelta会始终保持如上的数值不变,因此Tips的宽高也会自动的改变,。

所以只需要在运行时改变TipsBg的RectTransform的宽高即可。

那么如何设置TipsBg的宽高呢?

当为Text设置文本内容后,text.preferredHeight指的是针对该内容,组件Text希望RectTransform能够提供的height。如果rect.height == text.preferredHeight,则该文本可以完全显示出来

这样就可以计算出TipsBg期望的高度:

float yHeight = tipsTxt.preferredHeight + Mathf.Abs(tipsTxtRect.sizeDelta.y);   //获取tipsTxt的理想height,并计算tipsBg的目标height
tipsBgRect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, yHeight);

默认情况下不需要改变TipsBg的宽度,所以宽度暂时不需要重新设置

注意:在设置RectTransform的宽高时使用UGUI自带的方法:SetSizeWithCurrentAnchors。该方法会以UI当前的pivot为起点来设置宽高,并且在设置完成后会自动根据当前的anchors分布来调整RectTransform面板中的显示数据。

而且在获取UI对象的position时也是该UI的pivot在世界空间下的坐标,而不是该UI四个anchor交叉点的坐标。

基于pivot这样的特性,在设置TipsBg的position时,就可以在改变pivot的基础上,直接将鼠标点击位置赋值给TipsBg,而不需要另外计算TipsBg超出边界的数值,从而计算TipsBg的目标position。

在设置完TipsBg的宽高后就有可能会出现tips边界超出屏幕的问题,

那么如何检测该tips是否超出了屏幕边界并调整位置呢?

基于pivot的特性,直接把鼠标位置赋值给TipsBg.position,因此就可以很容易计算出UI是否超出了屏幕边界:

//通过设置TipsBg的pivot,而不是position,来避免超出屏幕边界
if (Input.mousePosition.x + tipsBgRect.rect.width <= Screen.width)  //默认向右显示
	tipsBgPivot.x = 0;           //当该UI在X轴上的最大值依然在屏幕以内时
else
	tipsBgPivot.x = 1;

if (Input.mousePosition.y - tipsBgRect.rect.height >= 0) //默认向下显示
	tipsBgPivot.y = 1;
else
	tipsBgPivot.y = 0;

运行时效果如下:红点处为鼠标点击位置

通过改变TipsBg的pivot来调整UI位置,使其不超出屏幕边界

虽然以上方法可以避免一部分超出边界的情况,但如果文本过长,屏幕过小,调整之后依然会超出边界,该如何呢?

首先需要获取UI对象四个角的坐标值:

本文标签: 屏幕边界道具位置功能