参考
Unity进阶技巧 - RectTransform详解
Unity——RectTransform详解
屏幕适配实用技巧
揭秘!anchoredPosition的几何意义!
localPosition与anchoredPosition转化之瞎猫找死耗子
首先为了让大家更好的理解内容,我在Unity中创建了两个UI控件,一个Plane控件,作为父对象,一个Image控件,最为子对象,如下图:
Pivot我们可以暂且称它为中心轴(这个翻译不太准确,但为了便于理解,先这么叫着),它是一个X,Y值范围是0到1的点,这个点的会在Anchor(锚点)计算位置的时候会使用到,下面用一张图来解释Pivot点的位置
旋转、大小和缩放修改发生在主轴Pivot点周围,因此Pivot的位置会影响旋转、调整大小或缩放的结果。
关于Anchor锚点可能接触过UI的朋友都了解一些,但是Unity中Anchor应该称它为锚框更为合理,因为它是由两个锚点(Min,Max)组成的一个矩形,当然也可以组成一个点(两个点重合)
当然上图是两个锚点重合的情况,所以看上去是一个点,下面我们利用两个锚点不重合的情况来说明一下:
在了解了Pivot和Anchor分别是什么后,我们就来看看Unity是如何使用这个两个东西来控制UI的布局
我们先来看看两个锚点重合时的情况,这种情况是我们最常用也是最容易理解的方式
总结下第1种情况的特点就是:子物体的大小不会随着父物体的大小变化而变化,但是位置会根据Pivot点到Anchor点的距离一致的原则发生对应的变化
当两个锚点(AnchorMin和AnchorMax)不重合时,两点就会确定一个矩形,这个矩形就是我们的锚框,如下图中的绿框就是我们的锚框区域
同理,如上图所示,Unity以锚框的右上角为原点(0,0),然后红框的Right和Top两个数确定红框的右上角的在坐标系中的位置,原地和红框的右上角的点确定一段距离(即上图的绿色箭头),不管黑框如何边框,这段距离都保持不变
在黑框大小和位置变化的时候,Unity会保证红框的左下角到锚框的左下角距离不变,同时红框的右上角到锚框的右上角距离不变,来确定红框的相对位置和大小,看下图来感受一下变化:
注意上图中红框左下角到黑框左下角的距离,以及红框右上角到黑框右上角的距离,他们都是不变的
快速设置Anchor,加快捷键能同时设置pivot或position
unity中的ui元素是有严格的父子关系的,子物体的位置是根据父物体的变化而变化的,而子物体和父物体联系的桥梁就是Anchor。之所以anchorMax和anchorMin的值是小数,是因为其表征的是该点所在位置占父物体大小的比例。
所谓的绝对布局,就是出现锚点的情况,此时的recttransform面板中的属性变成PosX,PosY,PosZ,Width,Height,这五个属性,首先说说Width和Height,在绝对布局的情况下无论分辨率是多少,父物体多大,该UI元素的大小是恒定的,如下图所示
所谓相对布局,就是出现锚框的情况。在这种情况下UI元素的四个角,距离四个对应的锚点的距离是不变的,在这种情况下RectTransform的属性又变为了Left,Top,Right,Bottom,PosZ,其中的PosZ表征的是该元素到父物体在Z轴上的偏移,利用这个值可以调整UI元素的显示顺序,不过我用的不多,这里不作太多讨论。剩下的四个值应该很好理解了,就是UI元素的每一条边距离父物体的每一条边的距离。
anchoredPosition根据名字的含义,我们大概可以猜出他是根据anchor锚点得出来个一个位置属性,他本身是一个点,如果在AnchorMin和AnchorMax是重合的情况下,anchoredPosition就是表示锚点到Pivot的位置,如下图所示:
但是如果AnchorMin和AnchorMax不重合的时候,anchoredPosition就比较复杂了,在这种情况下,Unity会根据Pivot、AnchorMin和AnchorMax计算出一个锚点,然后在通过Pivot和锚点来得出anchoredPosition的位置
offsetMin和offsetMax这两个属性比较好理解,其中offsetMin表示物体(本文中的红框)左下角相对AnchorMin的偏移,offsetMax表示物体右上角相对AnchorMax的偏移
sizeDelta就是offsetMax - offsetMin的值,即物体左下角到右上角的变量,如下图所示:
自学备用,如有问题欢迎及时指正,我会尽快改正。
(版本unity 201829f1)
本篇记录 Unity UGUI canvas 中的各项参数设置和效果,还是那句话自学备用,如有问题欢迎指正,我会尽快改正。
新建的Canvas拥有Rect Transform,Canvas,Canvas Scaler 以及 Graphic Raycaster 这几个组件。Rect Transform此时为灰色,在Scene视图中不能对Canvas进行 *** 作。Rect Transform 下一行英文“Some values driven by Canvas” ——Canvas驱动一些值。
此设置时,Canvas会填满整个屏幕,并将Canvas下面所有的UI元素置于屏幕的最上层,Canvas将一直覆盖场景中普通的3D GameObject。
启用pixelPerfect可以使元素看起来更清晰并防止模糊。勾选不启用抗锯齿(还在实验中,暂无截图)。
Canvas深度,数值越大,显示的优先级就越高,也就是数值大的Canvas会遮挡住数值小的Canvas。
此设置使Canvas渲染到指定的显示中。支持的辅助显示器(例如监视器)的最大数量为8。
最新几个版本中拥有的特性,提供给Shader使用的参数。此处不太了解。
启用pixelPerfect可以使元素看起来更清晰并防止模糊。勾选不启用抗锯齿(还在实验中,暂无截图)。
指定Canvas渲染在哪一个摄像机上
当Camera的Projection为Orthograhic时,此值得改变仅仅会改变Canvas的Pos Z;
当Camera的Projection为Perspective时,此值得不仅会改变Canvas的Pos Z,还会影响Scale。
当Plane Distance等于Camera的Clipping Planes的Near时 ,相当于Render Mode 是 Screen Space-Overlay 的效果,当Plane Distance等于Camera的Clipping Planes的Far时,Canvas在所有物体的后面。
Sorting Layer,可为UGUI设置画布深度,在下拉菜单中点击“Add Sorting Layer”按钮进入标签和层的设置界面,或者点击导航菜单->edit->Project Settings->Tags and Layers进入该页面。可以点击“+”添加Layer,或者点击“-”删除Layer。画布所使用的Sorting Layer越排在下面,显示的优先级也就越高。
在相同的Layer中区别显示层级关系的设定,相同的Layer中Order in Layer 越高,显示的优先级也就越高。
World Space即世界控件模式。在此模式下,Canvas被视为与场景中其他普通游戏对象性质相同的类似于一张面片(Plane)的游戏物体。在此模式下我们可以手动设置RectTransform数值,来改变Canvas在世界中的位置选择大小等。当所用UI为场景中的一部分时,我们可以使用这种模式。
此处在我使用时World Space模式下,Event Camera为空也可以执行按钮点击事件,摸索中~~~~~
不断学习中。整理出来忘记时看看,有错误的地方感谢指出。
现有的自适应方法,通常都是基于屏幕的分辨率。分辨率越高的设备上,UI显示的越小。这就造成了一些5寸左右的手机分辨率比ipad等平板设备还要高。UI在平板上显示太大。但是在高分辨率手机上显示太小。
以上脚本为基于屏幕物理尺寸自适应UI的一种方法。通过计算屏幕的DPI获取到屏幕的实际尺寸。然后根据一个标准的尺寸对UI的分辨率进行相对应的缩放。
可以改进的地方就是对于大屏幕或者小屏幕进行缩放的限制。避免类似ipad pro这类的设备上,UI有小的离谱。
配合这个脚本使用的同时。UI也需要用到锚点,进行初步的自适应,不然会造成UI的错乱。
效果图,素材是网上随便拉的
这是运行后的Hierarchy的界面,其中最下面的Item是放在摄像机不能拍到的位置,当做预设体,每个Item都有Toggle组件,在Grid上有Toggle Group 组件,并且将Itme上的Toggle组件中Group设置为Grid,这实现了点了一个之后,其他不会高亮。Grid上有组件 Grid Layout Group,该组件实现了当创建Item,并且将父物体设置为Grid后能够自动排版
这里我们需要写三个类,一个是自己捏造的数据类,放在Item上获取各种UI的类,还有能够创建Item并且能够对Item进行管理的类
public class ItemData//这个类存放的是数据
{
public int _starNum;//星星的数量(本来是想找星星的,现在就随便将就一下)
public string _icon;//这是名字
public string _itemName;//关卡的名字
public string _itemNum;//第几关
}
item上的类,用来获取item上的UI控件
public class Item : MonoBehaviour
{
public Image _star1;
public Image _star2;
public Image _star3;
public Image _icon;
public Text _levelNum;
public Text _levelName;
void initializeItem()
{
_star1 = transformFind("StarGroup/star1")GetComponent<Image>();
_star2 = transformFind("StarGroup/star2")GetComponent<Image>();
_star3 = transformFind("StarGroup/star3")GetComponent<Image>();
_icon = transformFind("Icon")GetComponent<Image>();
_levelName = transformFind("Levelname/name")GetComponent<Text>();
_levelNum = transformFind("Levelname/Lv")GetComponent<Text>();
}
void Awake()
{
initializeItem();
}
}
这是个管理Item创建的类
public class MainMgr : MonoBehaviour
{
GameObject item;
Transform Parent; //这里需要得到Gird的Transform
List<ItemData> dataGroup = new List<ItemData>();
void Awake()
{
CreateData();
item = transformFind("Item")gameObject; //获得一开始放在摄像机外的游戏对象,当做预设体
Parent = transformFind("Grid"); //保存Gird的Transform
}
void CreateData() //创建自己捏造的数据
{
dataGroupClear();//确保这个List没有其他数据
ItemData itemdata = new ItemData();
itemdata_icon = "1 (5)";
itemdata_itemName = "小树林";
itemdata_itemNum = "第一关";
itemdata_starNum = 3;
dataGroupAdd(itemdata);
ItemData itemdata1 = new ItemData();
itemdata1_icon = "1 (7)";
itemdata1_itemName = "沼泽";
itemdata1_itemNum = "第二关";
itemdata1_starNum = 1;
dataGroupAdd(itemdata1);
ItemData itemdata2 = new ItemData();
itemdata2_icon = "1 (15)";
itemdata2_itemName = "山海关";
itemdata2_itemNum = "第三关";
itemdata2_starNum = 1;
dataGroupAdd(itemdata2);
ItemData itemdata3 = new ItemData();
itemdata3_icon = "1 (12)";
itemdata3_itemName = "墓地";
itemdata3_itemNum = "第四关";
itemdata3_starNum = 2;
dataGroupAdd(itemdata3);
ItemData itemdata4 = new ItemData();
itemdata4_icon = "1 (32)";
itemdata4_itemName = "神殿";
itemdata4_itemNum = "第五关";
itemdata4_starNum = 3;
dataGroupAdd(itemdata4);
ItemData itemdata5 = new ItemData();
itemdata5_icon = "1 (25)";
itemdata5_itemName = "天庭";
itemdata5_itemNum = "第六关";
itemdata5_starNum = 2;
dataGroupAdd(itemdata5);
ItemData itemdata6 = new ItemData();
itemdata6_icon = "1 (30)";
itemdata6_itemName = "心魔";
itemdata6_itemNum = "第七关";
itemdata6_starNum = 3;
dataGroupAdd(itemdata6);
}
GameObject tempItem; //创建临时的游戏对象
void CreateTempItem() //创建Item
{
if (dataGroup != null) //当这个List不为空时
{
for (int i = 0; i < dataGroupCount; i++) //循环创建Item
{
tempItem = Instantiate(item) as GameObject; //创建Item并且获取到这个游戏对象
tempItemtransformlocalPosition = Vector3zero; //将其位置,缩放大小,旋转角度初始化
tempItemtransformlocalRotation = new Quaternion();
tempItemtransformlocalScale = Vector3one;
tempItemtransformSetParent(Parent); //设置其父物体为Grid
Item itemSprite = tempItemAddComponent(); //为每一个创建的Item添加脚本
itemSprite_levelNametext = dataGroup[i]_itemName;//获取每一个关卡的名字获取,一下类似
itemSprite_levelNumtext = dataGroup[i]_itemNum;
string path = stringFormat("Icon/{0}", dataGroup[i]_icon);//字符串拼接
itemSprite_iconsprite = ResourcesLoad(path, typeof(Sprite)) as Sprite;
ShowStar(dataGroup[i]_starNum, itemSprite);//调用这个方法获得星星的显示
}
}
}
void ShowStar(int num,Item tempitem)//这个方法是用来显示星星
{
if (num == 1)
{
tempitem_star1gameObjectSetActive(true);
tempitem_star2gameObjectSetActive(false);
tempitem_star3gameObjectSetActive(false);
}
if (num == 2)
{
tempitem_star1gameObjectSetActive(true);
tempitem_star2gameObjectSetActive(true);
tempitem_star3gameObjectSetActive(false);
}
if (num == 3)
{
tempitem_star1gameObjectSetActive(true);
tempitem_star2gameObjectSetActive(true);
tempitem_star3gameObjectSetActive(true);
}
}
void Start () {
CreateTempItem();
}
}
以上就是简单的游戏关卡的选择界面的实现,如果有错误,或者更好的方法,望指正,万分感谢!
因项目的需求,在制作中需要让UGUI中的组件,追随鼠标的运动轨迹。由于个人在以前使用中对于UGUI的坐标系了解不深,在使用中产生了一些问题,在此对UGUI的坐标系做一个简单的记录,以备后面查询。
Unity3D 采用InputmousePosition来获取当前鼠标的位置,获取的位置是相对于屏幕坐标系的,而UGUI使用的坐标系和屏幕坐标系不是同一个坐标系,
在UGUI中组件使用的坐标都是2D在Rect中的一个相对坐标,所以在实际使用中需要进行转换。
<pre>
public class test : MonoBehaviour
{
public RectTransform myRectTransform; // 目标组件
public Canvas myCanvas; // 当前画布
// Update is called once per frame
void Update ()
{
Vector2 vT = Vector2zero;
// 通过此函数,将鼠标坐标,从屏幕坐标,转换到UGUI坐标
RectTransformUtilityScreenPointToLocalPointInRectangle(myCanvastransform as RectTransform, InputmousePosition, myCanvasworldCamera, out vT);
myRectTransformlocalPosition = vT;
}
}
</pre>
#######附带一说,在Unity3D中可以使用函数ScreenshowCursor(老版本)、UnityEngineCursorvisible来显示和隐藏鼠标
以上就是关于Unity UGUI系列四 Pivot Anchor全部的内容,包括:Unity UGUI系列四 Pivot Anchor、Unity UGUI Canvas简谈、Unity3d UGUI基于屏幕尺寸的自适应等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)