动画事件:写在text中,读写 动画名字+路径+动画时长+动画触发事件
动画:勾选此选项后,动画会跳抖动,动画一致播放,播放不完整。自己一直传递自己,一般此选项不勾选。
动画平滑过渡的原理:
插值两个帧之间有变化的骨骼的旋转和位移。
Mirr: 动画镜像 左右走
2DBlendTree :
多个动画之间的融合。相同身体部位,不同身体的融合。
AnimationLayer: 2课
不同身体部位的融合。边走边挥手。每个层负责不同部位的运动。Override 覆盖上一层的运动,Additive附加动画融合。
file:///D:/unity2018insatll/Editor/Data/Documentation/en/Manual/AnimationOverview.html
每个动画clip可以看作是一个线性的记录。
动画来自: MAYA MAX
动画融合: 混合多个剪辑,以提供一个流畅的运动,因为球员在现场移动。
unity把工作流合并到Mecanim中,以淘汰老版动画。
从Unity动画导出—插件
unity中当查看导入的动画关键帧时,动画窗口提供动画数据的只读视图。要编辑此数据,请在Unity中创建一个新的空动画剪辑然后选择、复制并粘贴导入的动画剪辑中的动画数据到新的可写动画剪辑中。
unity中由于大量的人形动画,因为unity提供的Avatar系统:识别一个特定的动画模型在布局上是人形的,模型的哪些部分对应于腿部、手臂、头部和身体。
提供动画时,对材料和组件的变量进行动画化,即事件
TimeLine: 可以在相同的序列中动画许多不同的游戏对象
The Animation window: 可以创建离散的单个动画编辑。
时间线视图有两种模式:
即多普勒表和曲线【每个动画属性的值随时间变化的视图】。
曲线缺点:不易观察,比如:一个用于旋转弹跳立方体的简单动画剪辑。弹跳的Y位置值可能在0到2之间变化(这意味着立方体在动画期间弹出2个单位高);然而,旋转值从0到360(表示它的旋转度)。当同时查看这两条曲线时,位置值的动画曲线将很难识别,因为视图将被放大以适应窗口内旋转值的0-360范围:F键可以缩放到当前选定的关键帧。A键 查看整个时间线
状态机可以被看作是一种流程图,或者是一个用统一的可视化编程语言编写的简单程序。
按住鼠标滚轮: 可以拖动状态流程图。
使您可以在一个动画控制器中有多个动画层同时工作,每个层都由一个单独的状态机控制。
常见用途是让一个单独的层在一个基本层上播放上半身动画,控制角色的一般运动动画。
对于一个复杂的动作可能由多个阶段组成。与其用单个状态处理整个操作,不如确定不同的阶段并为每个阶段使用单独的状态。例如,一个角色可能会有一个动作叫做“神枪手”【它蹲下来瞄准,射门,然后再站起来】,跑,跳。
注意: 子状态机只是在编辑器中可视地折叠一组状态的一种方式。
子状态内部会有一个额外状态以up开头。是链接外部状态的桥梁,如下。
子状态机:
unity使用动画层来管理不同身体部分的复杂状态机。这方面的一个例子是,如果你有一个下半身层用于步行跳跃,而一个上半身层用于投掷物体/射击。
在每个层上,您可以指定掩码(动画模型中应用动画的Avatar)和混合类型。覆盖意味着来自其他层的信息将被忽略,而加法意味着动画将被添加到以前的层之上。
掩码属性用于指定在此层上使用的掩码。例如,如果您想在模型的上半身上播放一个投掷动画,同时您的角色也可以同时行走、跑步或站立。您可以在定义上半身部分的层上使用一个面罩来播放投掷动画,Mask把上半部分遮住 如下所示:
有时,能够在不同的层中重用相同的状态机是很有用的。例如,如果您想要模拟“受伤”的行为,而不是“健康”的动作,而是为步行/跑/跳提供“受伤”的动画。您可以单击其中一个层上的“同步”复选框,然后选择要与之同步的层。然后,状态机结构将是相同的,但是状态所使用的实际动画剪辑将是不同的,复制了状态图 但是不复制动画。
同步层根本没有自己的状态机定义-相反,它是同步层源的一个实例。在同步层视图中对状态机的布局或结构所做的任何更改(例如,添加/删除状态或转换)都是对同步层的源进行的。唯一对同步层唯一的更改是在每个状态中使用的选定动画。
[对同步层的任何更改,也会对同源层更改,只有各自选定的动画不会同步]
应用: 如果某一时刻 角色必须以一只手或一只脚在某一时间的某一地点着陆。
Animator.MatchTarget function
登录后复制
animator.MatchTarget(jumpTarget.position, jumpTarget.rotation, AvatarTarget.LeftFoot,
new MatchTargetWeightMask(Vector3.one, 1f), 0.141f, 0.78f);
角色开始脱离地面的位置:始脱离地面的位置,规范化时间内,此时动画播放的进度为14.1%
落地的位置,是78.0%
注意:只有在游戏中调用正确的抬起点和落地点时才有意义。
子关节的位置根据其父关节的旋转而变化,因此可以根据其包含的各个关节的角度和相对位置来确定关节链的终点。这种提出骨架的方法被称为正向运动学。【由手带动前臂,带动大臂,带动肩膀】
应用: 让角色的脚在一个不平整的表面上站稳时
由于我们不打算让角色的手到达物体的中心(圆柱体的枢轴点),我们将一个空的子对象(在这种情况下,称为“柱面抓取柄”)放置在圆柱体上。
案例 file:///D:/Unity5.6.6/Editor/Data/Documentation/en/Manual/InverseKinematics.html
将多个动作混合在一起。
例如: 根据人物的速度来混合行走和跑步的动画。或者在运行时向左或向右倾斜。
区分过渡树和混合树是很重要的。虽然两者都用于创建流畅的动画,但它们被用于不同的情况。
过渡树:
用于在给定的时间内平稳地从一个动画状态过渡到另一个动画状态。
混合树:
用于允许多个动画通过不同程度地合并它们的部分来平滑地混合。每个运动对最终效果的贡献程度由一个混合参数控制,它只是与Animator控制器关联的数值动画参数之一。为了使混合运动有意义,混合的运动必须具有相似的性质和时间。混合树是动画状态机中的一种特殊状态类型。为了使混合效果更好,剪辑中的动作必须在标准时间的同一点发生。例如,步行和跑步动画对齐
<1. 创建混合树
<2. 给混合树根节点添加子动画
<3. 如图:
<4. 可以切换到2D Freeform Cartesian[2D卡迪尔坐标方向]或者2D自由的方向中看动画融合的权重。
分别选中蓝色的四角形点
动画之间的混合使用线性插值处理(即每个动画的数量是按混合参数加权的独立动画的平均值)。但是,您应该注意到根运动不是以相同的方式插值的。
(1). 1D Blending: 检查器中paly,拖动红色参数箭头查看影响。
上图: 1是自动设置阀值参数,阀值之间的跨度是一致的 2.根据某个轴的速度或者角速度来设置阀值。
The 2D Blending Diagram /二维混合图
(2) Direct Blending
使用直接混合树允许您将动画参数直接映射到BlendTree子节点的重量。如果您想要精确地控制正在混合的各种动画,而不是使用一个或两个参数间接地混合它们(在1D和2D混合树中)..简单地绕过了交叉衰落,或各种2D混合算法. 混合动画的面部表情,或当混合附加动画。
(3) 2D Simple Directional:具有方向性的动画片段,同一方向上最好不要有多个动画片段
(4) 2D Freeform Directional :主要用于控制具有方向性的动画片段,同一方向上允许有多个动画片段,(0,0)位置上必须有一个动画片段
(5) 2D Freeform Cartesian : 不一定具有方向性的动画片段.(一般用这个)
Additional Blend Tree Options
Adjust Time Scale > Homogeneous Speed: 按钮重新调整剪辑的速度,使其与所选参数的最小值和最大值相对应,但保持与最初拥有的相对速度相同。只有当所有的动作 都是动画剪辑而子混合树时,调整时间尺度才是可用的。
Animator系统的性能优化:
<1. 当你没有动画播放使用的骨骼,处理成本应该可以忽略不计。如果它们的附件不存在或隐藏,则成本更低。
<2.网格合并: 只要有可能(如果角色只有一种材料),就把有皮的网格组合起来。将一个角色分割成两个蒙皮的网格渲染器会降低性能。
<3. 在没有混合的情况下播放单个动画剪辑比使用老版动画系统慢. 老版动画非常直接,采样曲线并直接写入变换。Unity当前的动画系统有临时的缓存,它用来混合,并有额外的复制采样曲线和其他数据。
<4. 动画缩放曲线比动画平移和旋转曲线更昂贵。避免使用比例动画。(注意:这不适用于常量曲线(对于动画剪辑的长度具有相同值的曲线)。常数曲线经过优化,比普通曲线成本更低。与默认场景值(常量)相同的常数曲线值不写入每个帧的场景。)
<5. 同步层的开销 :取决于是否同步,是否同步取决于该层所播放的动画和混合树。当层的权重为零时,unity将跳过层更新。
<6. 对于人型动画,如果使用了Avatar Mask,如果不需要IK目标或手指动画,则删除
对于普通动画:根运动比不使用根运动要昂贵得多。如果不使用根运动,请确保没有指定根骨。
场景中优化:
使用散列代替字符串查询动画。shotFloat = Animator.StringToHash("Shot");
实现一个小AI层来控制动画,有限状态机。为OnStateChange、OnTranstionBegin和其他事件提供简单的回调。使用状态标记可以轻松地将您的AI状态机与unity动画状态机相匹配。
运行时优化,始终通过将Animator组件的裁剪模式设置为基于渲染器的动画来优化动画【渲染器不可见时禁止动画变换写入,IK】,禁用蒙皮网格组件在屏幕外的更新。
file:///D:/unity2018insatll/Editor/Data/Documentation/en/Manual/HOWTO-exportFBX.html //建模软件的导出优化
Navigation :智能地在游戏世界中移动。
NavMesh:导航网格
Off-Mesh Link: 非网格链接组件,跳过沟渠或篱笆,或者在穿过它之前打开一扇门,都可以被描述为脱离网格的链接。
NavMesh Obstacle: 应该避免的移动障碍.
Following the Path: 我们首先需要将起点和目的地位置映射到它们最近的多边形(可见角落)。然后,我们开始搜索从开始的位置,访问所有的邻居,直到我们到达目标多边形。跟踪访问的多边形允许我们找到从开始到目的地的多边形序列。
Path: 描述从起点到目标多边形的路径的多边形序列称为道路。 代理人将始终转向走廊的下一个可见角落,到达目的地。
多个代理(agents )同时移动: 当处理多个代理同时移动时,它们在相互回避时需要偏离原来的路径,使用一条线段组成的路径就变的困难了。由于每个帧中的代理移动都很小,所以我们可以利用多边形的连通性来修复走廊,以防我们需要绕道。然后我们迅速找到下一个可以看到的拐角处。
转向逻辑采用下一个拐角的位置并基于该数字计算出到达目的地所需的期望方向和速度(或速度)。 存在于其他代理发生碰撞的可能。
障碍物避免选择新的速度,该速度在期望方向上移动和防止将来与导航网格的其他代理和边缘碰撞之间平衡。 Unity正在使用倒数速度障碍(RVO[Reciprocal Velocity Obstacles])来预测和防止碰撞。
【向量的相交性问题是在一定时间内不发生相交;若是人工智能精粹中躲避障碍物的解法(但是一个是静止的; 两个球以一定速度运动的相交性问题),两个球以一定速度运动会不会相交的问题,人与人之间推搡使用RVO】
RVO:
全局导航和本地导航之间的区别:
描述路径的多边形线性列表是一种灵活的转向数据结构,可以随Agent位置的移动而进行局部调整。
本地导航试图找出如何在不与其他代理或移动对象发生碰撞的情况下有效地移动到下一个角。
https://gameinstitute.qq.com/community/detail/127106 //Unity UI优化(二) - 填充率,画布和输入
//Unity渲染优化
file:///D:/unity2018insatll/Editor/Data/Documentation/en/Manual/OptimizingGraphicsPerformance.html
减少包体的建议: 纹理、声音和动画
一: 压缩纹理
Textures: 使用平台特定覆盖的纹理压缩格式,把纹理压缩为专门的格式,为快速纹理采样优化。
unity 为每个平台设置了其默认格式,包体只包含转换后的纹理。源资产文件以原始格式保留在项目的“Asset”文件夹中。
自己设置纹理压缩格式:
【但在某些情况下,希望重写默认格式,为某些纹理选择不同的压缩格式(例如,如果您使用纹理作为掩码,只有一个通道,则可以选择使用BC4格式来节省空间,同时保持质量)】。
若要为每个平台应用自定义设置,请使用纹理导入程序批量设置默认选项,然后使用平台特定覆盖面板覆盖特定平台的默认设置。
下图,每个平台默认的表示:
当您使用目标平台不支持的纹理压缩格式时,纹理将解压缩为RGBA 32并与压缩的纹理一起存储在内存中 。浪费了时间和内存。所以要使用支持的纹理压缩格式。
纹理在CPU上解压缩为DXT或ETC,然后在运行时上传到GPU。压缩时间长,但在运行时解压缩非常快。有损压缩注意平衡质量和内存大小。
压缩对照表 : 文档中搜 Texture compression formats for platform-specific overrides
对于Android:
1 . 除非您是针对特定的硬件(如Tegra),否则ETC 2压缩是Android最有效的选择,它提供了质量和文件大小的最佳平衡(以及相关的内存大小要求)。如果您需要一个alpha通道,您可以将其存储在外部,并且仍然可以从较小的纹理文件大小中获益。
2. 您可以将ETC1用于具有Alpha通道的纹理,但仅当构建用于Android且纹理放置在图集上时(通过指定打包标记)。 要启用此功能,请使用纹理的ETC1复选框选中“压缩”。 Unity将生成的图集分成两个纹理,每个纹理没有Alpha通道,然后将它们组合在渲染管道的最后部分。
3.若要在纹理中存储alpha通道,请使用RGB 16位压缩,所有硬件供应商都支持
二:减小图像的物理大小:
减少纹理的MaxSize , 通过降低分辨率来降低内存。同时也提高GPU对纹理的采样模式 FitterMode
三:网格与动画
压缩网格和导入动画剪辑,节省内存。但压缩可能会带来一些不准确的地方。试验什么水平的压缩是可以接受的。
四: DLLs
应该避免依赖System.dll或System.Xml.dll. 存储大小增加了大约1兆字节。
.NET 2.0和.NET 2.0的子集。在“播放机设置”中为您的生成选择适当的级别。
五: 优化图形性能
GPU:
file:///D:/unity2018insatll/Editor/Data/Documentation/en/Manual/SL-ShaderPerformance.html //shader优化
受到填充率或内存带宽的限制.降低显示分辨率并运行游戏。如果较低的显示分辨率使游戏运行得更快,您可能会受到填充率的限制。
填充率是指GPU在屏幕上每秒可以渲染的像素数。如果我们的游戏收到填充率的限制,意味着我们的游戏每帧尝试绘制的像素数量超过了GPU的处理能力。
Shader:
<1. 尽量减少数学函数(如pow、exp、log、cos、sin、tan)资源密集,在像素着色器中的使用,因此尽可能避免使用它们。
<2. 记住,Alpha测试(丢弃)操作经常会使片段着色器变慢。
<3. 浮点数精度问题Fload fixed 。尽可能使用半精度的变量[half
]。
<4. PC, 顶点数 200 K和3M以下
<5. 如果您使用的是内置着色器,请选择Mobile或Unlit类别中的着色器。 它们也适用于非移动平台,但它们是更复杂着色器的简化版和近似版。
<6. 只有一个(最好是方向性的)像素光会影响几何体,而不是倍数。
<7. 使用像素着色器或纹理组合器混合多个纹理,而不是多通道方法。
CPU : DrawCall
对象中使用更少的材料,把不同的纹理放到一个更大的纹理图谱中。
在非移动对象上设置静态属性,以允许内部优化,如静态批处理。
尽量避免使用雾。
使用天空盒来“伪造”远处的几何体。
静态批处理会导致内存和存储开销,而动态批处理会导致一些CPU开销。
动态批处理与图形工作不兼容
批处理动态GameObjects每个顶点具有一定的开销,因此批处理仅应用于总共包含少于900个顶点属性的网格。带有光照贴图的GameObjects不能动态,
建模优化: 保持正逆运动学分离 搜 Modeling characters for optimal performance
六: Lighting
照明性能最快的选择总是创建照明,根本不需要计算。要做到这一点,使用Lightmap来“烘焙”静态照明一次,而不是计算每个帧。生成光映射环境的过程只需稍长一点,而不只是在“Unitity”中的场景中放置一盏灯。
不要设置射向相机的光源来实现模型边缘照明效果,在shader中计算。
每个灯都有一个渲染模式设置,可以设置为重要或不重要;标记为不重要的灯具有较低的渲染开销。用于修改最终作为像素灯的灯数和作为顶点灯的灯数。
七、 Textures
如果有一张PNG图片, 95%的地方是全透明的,而在全透明的地方,RGB值是有意义的;
如果设置了alphaIsTransparency属性,则全透明的地方,Unity会将RGB值全部丢失!!!,
所以:
如果要使用此纹理的4个通道做数据存储时(比如地型的4通道混合),千万不能勾选alphaIsTransparency属性.
PNG图片仅仅用于UI显示;则可以勾选此属性。
一般是2^n格式,如果不是则在此处可以自己设置,但是如果是sprites格式,则必须由导入前就设置好
8. Android:
音效加载:
针对安卓平台,如果一开始就将音效给加载进去的话,那么上图中的内存占用率就会很大,导致最为明显的变化就是,场景加载的时候卡顿严重,影响游戏的体验优化方案。
对于背景音乐(高频音乐)设置加载模式为streaming模式,使用缓存加载,播放完毕后会自动从缓存中卸载,从而提高内存占用率,如果你发现的的音效很占内存那么试试这个操作肯定不错。
1.取消x86架构的兼容选项
一般情况下android平台不需要编译x86的版本,因为设备太少了,需要考虑对应平台的时候可以单独打一个x86版本的包。在OtherSetting中。 cpu x86 手机基本没有了
,安卓包减小10M,爽歪歪。
9. Sprite Atlas
无论精灵的纹理设置是什么,在图集中打包,最终图集纹理只会按照atlas中的设置。
9.2. NGUI和UGUI 图集的不同
(1)NGUI 必须先打出图集,然后开始做界面,我们始终都要考虑我们的UI图集,如图集的大小会不会超过 1024K,图集如何规划 ;
(2)UGUI,开发者不需要去管理自己的图集,做界面的时候只用小图,而在最终打包的时候,引擎会把我们的小图打包成一张大的图集
[Mode 各个选项的说明:设置使用新版或者老版的打包方式]
1)disabled不启用、
2)enabled for builds(legacy sprite packer):打包时启用(针对sprite packer这种打包方式)
3)always enabled(legacy sprite packer):总是启用(针对sprite packer这种打包方式)
4)enabled for builds:打包时启用(针对sprite Atlas这种打包方式)
5)always enabled(针对sprite Atlas这种打包方式)
可是开发的时候就想看图集会占几个Draw Call,而不是让unity build是自己打包。
第二步:设置 tag 和 Mesh Type
Mesh Type有两个可选项:
(1)Full Rect:会把所有的小图按照矩形的方式来排列,如果宽高不一样的图片,它们会自动补起。
(2)Tight: 是紧密打包方式,也就是尽可能的把图片都打包在图集上,更省空间。
第三步:点击Pack,完成打包
Window----->2D------->Sprite Packer 点击左上角的 pack 就可以啦,完成! 【注意是否设置成了老版的图集打包】
补充说明:
(1) 放在Resources文件夹中的图片,Unity不会打包到图集中!
(2) 打包好的图集会放在缓存文件夹Project\Library\AtlasCache里面!
新版本的图集打包方式:sprite atlas
sprite Atlas是2017版本之后的图集打包方式, Sprite Atlas 针对旧版本的图集打包系统Sprite Packer在性能和易用性上的不足,进行了全面改善。
第一步:设置 Mode: Always Enabled
Edit---->ProjectSetting------->Editor--------->Mode
第二步: 在Project 面板中右键 create -> sprite atlas
第三步: 分配资源给 sprite atlas , 完成!
可以将文件夹,纹理或精灵分配给Sprite Atlas。可以将整个文件夹分配给Sprite Atlas资产,该文件夹中的所有纹理(包括子文件夹)都将被打包。
新功能Variants: 变体
就是指原有图集的一个变种。它会复制原图集的贴图,并根据一个比例系数来调整复制贴图的大小。通常用于为高分辨率和低分辨率的屏幕准备不同的图集。因为如果只准备一套高分辨率的图集,在低分辨率的设备上占用内存过多。反之,如果只准备一套低分辨率图集,在高分辨率的设备上就会模糊。
==》
新功能:图集访问
Sprite Atlas作为一种资源开放给用户,可以在脚本中访问,还可以通过名字获取图集中的精灵。这样用户可以更加直接地随时编辑图集,而且不用去单独加载图集中的每个精灵。UnityEditor下的。
Resources下的图片不能打包图集,且用不用的都会打到包里,应该使用图集形式,减少内存和DrawCall
登录后复制
void Start()
{
transform.GetChild(0).GetComponent<Image>().sprite= LoadSprite("New Sprite Atlas", "time_green_6");
}
SpriteAtlas numAtlas;
public Sprite LoadSprite(string atlasName,string spriteName)
{
Sprite sprite = null;
if (numAtlas != null)
{
sprite = numAtlas.GetSprite(spriteName);
}
else
{
numAtlas = Resources.Load<SpriteAtlas>(atlasName);
sprite = numAtlas.GetSprite(spriteName);
}
return sprite;
}
Draw order of elements(绘制UI的顺序)
绘制顺序和在层级面板中的顺序是一样的,如果有重叠,则后一个显示在层级中前一个的上边。SetSiblingIndex控制层级顺序
Screen Space - Overlay
最前边,如果调整屏幕大小或更改分辨率,Canvas将自动更改大小以匹配此大小。
相机如果是透视,如果调整屏幕大小,更改了分辨率,或者相机的尺寸,画布也会自动更改大小以匹配。
World Space
画布的大小可以使用它的rect变换手动设置。
Pivot
当设置为Pivot,则可以调整UI的支点。可以在Rect Transform中调整UI的支点。
Image
Simple - 平等的展开图片。
Sliced - 切片模式,对应图要进行九宫格。大小不会扭曲角,只有中心部分是拉伸。
Tiled - 对整个精灵都是平铺的。
Filled -填充,填充起点 填充度数 参数控制 顺时针 使用完美像素-即图片自身的像素数和大小
Interaction Components(交互组件)
交互组件至少有一个UnityEvent,当用户以特定方式与组件交互时调用该UnityEvent。 UI系统捕获并记录从附加到UnityEvent的代码传播的任何异常。
Toggle
Is On : 选择或者不选择,只有在unity运行状态下,才能更新到场景显示上。
Toggle Group
ToggleGroup可以用来对一组相互排斥的切换进行分组。属于同一组的切换被限制,因此一次只能选择其中一个-选择其中一个会自动取消所有其他的选择。
AllowSwitchOff: 如果没有勾选,则点击已经勾选的Toggle不会改变自身的状态,如果勾选,则点击已经勾选的Toggle会改变自身的状态。
单选:
创建Panel,添加组管理组件-->创建多个Toggle作为子集,且Group属性关联到Panel上。
单击Toggle时调用的UnityEvent。事件可以将当前状态作为bool类型的动态参数发送。此处可以关联参数改变后,需要做的行为
多选:
就是获取所有的Toggle,统计是开启状态,且选择项<最多选则数,否则就屏蔽掉,不让选择。
Dropdown(下拉列表)
Input Field
若要获取输入字段的文本,请在InputField组件本身上使用Text属性,而不是使用显示文本的文本组件的Text属性
Aspect Ratio Fitter
Rich Text
它指示关键字在文本中查找标记。
登录后复制
We are <i>斜体</i> not amused.
We are <b>粗体</b> amused.
We are <size=25>设置字号</size> unaffected.
we are <color=green>设置为绿色</color>
设置图文混排:
<1. 使用富文本占位
<2.使用正则表达式提取用于占位的富文本
<3.重绘text网格,在占位处生成绘制一个网格并且把图片根据UV贴到网格上添加上(或者直接创建一个图片的预制体,让后加载、更新图片、生成)。
根据uv坐标贴纹理:
http://edu.manew.com/course/343/tasks //UGUI源码
uv: 指的是模型贴图的坐标,根据模型贴图的坐标把图片贴到模型上去。
根据UV裁剪图片,然后贴上
<4.给图片添加点击事件。射线,碰撞器
百度云工程:图文混排
1.Anchor:
子物体的位置是根据父物体的变化而变化的,而子物体和父物体联系的桥梁就是Anchor。
用小数表示,该点所在位置的x、y占父物体大小(xy)的比例.黑色画线部分占灰色物体总长度和总宽度的比例
为了方便后续描述,我把Anchor分为两种情况
锚点
锚框
(即示意图中的情况)2.绝对与相对布局概念
2.1 绝对布局:
就是出现锚点
的情况,此时的recttransform面板中的属性变成了。在绝对布局的情况下无论分辨率是多少,父物体多大,该UI元素的大小是恒定的。可能就会出现在高分辨率情况下元素太小或者低分辨率情况下元素比屏幕大的情况。
此时支点PosX
和PosY
的值就是Pivot到锚点的值,Pivot这个属性应该是RectTransform那么多属性中最好理解的一项了吧!
2.2相对布局:
出现锚框的情况。在这种情况下UI元素的四个角,距离四个对应的锚点的距离是不变的,在这种情况下RectTransform的属性又变为了Left(到左边的距离)
,Top(到父物体顶部的距离)
,Right(到右边的距离)
,Bottom
,PosZ
,其中的PosZ
表征的是该元素到父物体在Z轴上的偏移,利用这个值可以调整UI元素的显示顺序,不过我用的不多,这里不作太多讨论。剩下的四个值应该很好理解了,就是UI元素的每一条边距离父物体的每一条边的距离。
在示意图的情况下,我设定了红色图片(子物体)距离灰色图片(父物体)的每一条边的距离都是200个单位。
接下来我们将灰色的图片(父物体)缩小,看看红色图片的变化:整体缩小了,但是到父物体每条边的距离保持不变。
如果出现这种情况:因为Top
和Bottom
的值加起来比父物体的高还要高
3.Pivot
Pivot中心点,就是该UI元素旋转缩放的中心点,左下角为(0,0)右上角为(1,1)
4.Offset
OffsetMax的值是怎么计算得出来的呢?OffsetMax又有什么用呢?
其实没有那么神秘,这个值就是UI元素的右上角的坐标,减去AnchorMax的值,得到一个从AnchorMax指向元素右上角的向量(vector2类型),如下图。
那么这个值有什么用呢:因为这个值是一个可读可写的属性,
1. 所以在锚框
的情况下我们可以在代码里面动态的去调整UI元素相对边界的距离,其次更重要的是,
登录后复制
GetComponent<RectTransform>().offsetMax = Vector2.zero;
2. 利用这这两个值就可以计算出sizeDelta的值了!
5.sizeDelta
以前对这个属性是真的一脸懵逼,网上很多教程说这个值可以设置UI元素的大小,但是真的有时候好用,有时候有不好用,真的一头雾水,官方文档说的也是很笼统,但是现在搞清楚了其中的联系以后,就觉得清晰了不少了。
其实sizeDelta的值就是OffsetMax-OffsetMin的值
5.1锚点情况下的sizeDelta
锚点情况下,offsetMax和Min的起点相同,根据向量相减的三角形法则,可以得到一个新的向量,这个新的向量的X和Y的大小正好UI元素的宽和高相等,所以在这个时候去设置sizeDelta的值,可以直接调整UI元素的大小
5.2锚框情况下的sizeDelta:向量a-向量b= 向量b->a
在锚框的情况下,offstMax减去Min,得到的将不再是UI元素的大小,而是一个新的奇怪的向量,这个向量代表的物理意义是,sizeDelta.x值就是锚框的宽度与UI元素的宽度的差值,sizeDelta.y的值就是锚框的的高度与UI元素的高度的差值
所以这个属性之所以叫做sizeDelta,是因为在锚点情况下其表征的是size(大小),在锚框的情况下其表征的是Delta(差值)
那么我们在锚框的情况下要怎么样才能获得元素的大小呢?这个时候就可以用到rect属性了。
6.rect
7.anchoredPosition
通过直接设置anchoredPosition的值可以改变UI元素的位置,但也是要分锚点
和锚框
的情况
在使用锚点的情况下,anchoredPosition表征的是元素Pivot到Anchor的距离
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删