网站设计和制作费用,百度免费网站怎样建设,做问卷调查的是哪个网站好,旅游网站的设计代码个人总结#xff0c;太简单的直接跳过。
一、缩放模式 1.固定像素大小 就是设置一个100x100的方框#xff0c;在1920x1080像素下在屏幕中长度占比1/19#xff0c;在3840x2160#xff0c;方框在屏幕中长度占比1/38。也就是像素长款不变#xff0c;在屏幕中占比发生变化 2.…个人总结太简单的直接跳过。
一、缩放模式 1.固定像素大小 就是设置一个100x100的方框在1920x1080像素下在屏幕中长度占比1/19在3840x2160方框在屏幕中长度占比1/38。也就是像素长款不变在屏幕中占比发生变化 2.根据比例缩放 在1920x1080p下是100x100在3840x2160中方框的长宽会变成200x200也就是在屏幕中占比不变。 3.固定物理大小 就是无论在什么分辨率中在现实世界中拿尺子去量它的长度都是一样的不过这取决于是否能正确获取设备的DPI信息在编辑器模式本身就是不准的实机才有这个效果。 二、Canvas模式 1.Screen Space-Overlay 显示在一切之上使用SortOrder对同为ScreenSpace模式的Canvas进行排序。 2.Screen Space-Camera 用相机渲染画布也就是画布渲染在世界空间中可以被世界空间中的物体遮挡。 一般单独创建一个UiCamera用于渲染相机模式的画布UICamera把Culling mask设置为UI层级就可以只渲染UI。 其中PlanetDistance表示画布距离相机的距离在和3d物体混合显示时使用这个来排序sorting layer表示排序层order in layer表示同一层中的order。 同一sorting layer如果order in layer 相同就依靠hireraarchy的顺序排序如果orderinLayer不同则依靠order in layer排序数字越大就显示在前。不同sorting layer根据sorting layer的顺序进行排序。 注意Sprite是2D/3D物体在overlay模式中Ui永远显示在Sprite之前。由于Sprite的Sortinglayer和order layer是2d/3d空间中使用的其实2d模式也是3d空间,当canvas使用相机模式或者世界空间模式的时候UI 元素与 Sprite可以在同一渲染队列中比较从而实现跨系统的排序。此使Sorting layer和Order in layer的设置优先于3D空间中的深度判定比如A画布在Sprite之后但是如果A画布的Sprite layer较高或者order in layer较高则A画布会显示在Sprite之前Sprite和Sprite对比也是同理。 3.World Space 画布直接被放置在世界空间中,默认使用深度排序可以被遮挡与其他相机模式的画布世界空间的画布,Sprite进行排序时也可以使用sortingLayer和order in layer进行排序。 三、锚点AnchroedPosition,Pivot 图中绿色为父物体Image,白色为当前选中Image。 中间的空心圆是pivot表示枢轴点轴心点旋转和缩放基于这个。取值范围为0-1表示在自身UI的长宽的百分比。 anchordPostion当四个锚点在同一个点时表示pivot相对于这个点的偏移量。比如 此时 anchordPositionx,y) 但是当锚点设置为区域时情况就大不相同了。 如图锚点设置为0.25,0.25)和(0.75,0.75).在说明这种情况下需要先了解下锚点的作用 锚点设置的左下角min和右上角(max)他是基于父物体的相当于设置了当前Ui在父物体中的的基准区域设置基准区域后再在inspector中设置相对位置。当左下角和右上角锚点在同一个位置时相当于区域设置为0它相对于父物体的大小就是0所以父物体长宽变换时子物体的长宽不动但是位置会跟着变化因为锚点中的数值其实就代表在父物体中的百分比位置。而如果设置在不同的点就会构成一个区域这个区域占有一定的面积并且四个角也设置好了位置当父物体变换时这个基准区域会保持和之前相同比例进行长宽变换此时inspector面板就变成了left,top,right,bottom的设置了这个表示Ui和基准区域的四条边的距离。 重点来了区域模式的anchoredPostition的计算这个我翻遍百度谷歌和各种ai没找到具体的计算公式最后自己测试出来的。anchoredPosition图形和基准区域左下角的相对距离图形和基准区域的大小的插值*pivot. 具体什么意思呢如图 和基准区域相同位置和大小 和基准区域相同位置和大小时无论如何移动pivotanchoredPosition都为(0,0)此时白色长宽为100100 x移动50y移动50 整体移动后anchoredPosition为(50,50) 移动后x增长50 整体移动后再拉伸anchoredPosition5050500*0.50.5(75,50)就是相对距离长宽变换*pivot。 拉伸后pivot变为10.5 此时移动Pivot为(1,0.5)结果变为5050500*10.5(100,50) 同理如果把pivot改为(0,0.5)结果就是(50,50) 四、anchordPosition和localPosition,position的区别 anchoredPosition上面已经说了而llocalPosition和position都是基于Transform的只有当Pivot改变时数值才会改变localPosition和position使用的数值和分辨率是相对应的。要注意的是pivot位置并不是只会主动改变当修改长宽的时候pivot也会跟着被动改变注意这里说的是pivot的位置改变不是pivot的值改变要注意区分。 五、使用代码设置位置 1.rectTransform.anchoredPosition targetAnchoredPos; 和获得anchoredPosition不同设置的时候无论锚点是固定点还是自定义区域都是直接设置轴心点到锚点的相对位置。 2.sizeDelta和SetSizeWithCurrentAnchors 在 Unity UI 中sizeDelta 和 SetSizeWithCurrentAnchors 都用于设置 RectTransform 的尺寸但它们的工作方式有所不同。
rectTransform.sizeDeltasizeDelta; sizeDelta直接设置RectTransform的宽度和高度当锚点固定时他直接设置尺寸。但是当锚点为自定义区域时它代表的是额外的尺寸如第三部分中的100x100的白色方框sizeDelta设置为100的时候白色方框的尺寸变为110x100。 SetSizeWithCurrentAnchors 也是设置 RectTransform 的尺寸但它会把anchor 的影响考虑在内计算最终的 sizeDelta以确保视觉上符合指定的尺寸。 当SetSizeWithCurrentAnchors的时候无论锚点如何都是把尺寸长度设置为目标值。
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal,sizeDelta.x);
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical,sizeDelta.y); 3.offsetMin / offsetMax rectTransform中的OffsetMin/OffsetMax属性用于设置相对于Anchors的偏移量就是自定义区域模式中的inspector面板上的left,bottom,right,up这些属性。这个对固定锚点也有效因为固定锚点其实也是有anchormin和anchorMax构成的只是他们的位置相同而已。 如果先设置SizeDelta(无论哪种方式)再设置offset的话offset会覆盖尺寸的设置。 4.rectTransform.Rect rectTransform.rect 返回的是一个 本地空间local space 下的 矩形区域它主要用于获取 UI 元素的实际大小和边界信息。 4.1.rect.size和rect.width,rect.height他们就是表示实际的区域的长宽。 4.2.rect.xMin,rect.xMax,rectyMin,recct.yMax。 表示的是相距pivot的距离值如100x100的方框中pivot为0.50.5时xMin-50yMin-50,xMin50,xMax50。如果pivot为0,0那么xMin0yMin0xMax100yMax100。如果要获取世界中边界位置需要使用GetWorldCorners()方法获得世界空间下的边界。还有,x等效于xMiny等效于yMin 5.rectTransform.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left,50,200); 此方法表示的是贴边操作选择Edge后它会自动设置锚点到父物体对应边并设置和边的间距和ui的长宽常用于制作侧边栏之类的效果。注意他不是设置和锚点的间距而是父物体的边的间距因为它本身就会修改锚点到指定的边。等效于以下代码
rectTransform.anchorMin new Vector2(0, rectTransform.anchorMin.y);
rectTransform.anchorMax new Vector2(0, rectTransform.anchorMax.y);
rectTransform.anchoredPosition new Vector2(50 200 * rectTransform.pivot.x, rectTransform.anchoredPosition.y);
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 200);六、UI特效 1.制作Ui特效的几种方式 粒子特效的大部分图片来自B站Up主别看着我笑了我自己懒得作图直接截取的它的视频里的图应该不算侵权吧毕竟我这个基本只算是个笔记写出来防止以后自己忘掉到处翻。别看着我笑了https://space.bilibili.com/457739566 1.1.修改UI网格 比如UGUI中常用的文字的outline效果和Shadow效果Mask效果图片的FillType效果等就是修改Ui网格实现的。 图片来自B站视频BV1bR4UeyEa8 1.2.使用自定义Shader 图片来自B站视频BV1bR4UeyEa8 unity的Image组件会自动把Sprite传递给shader的_MainTex参数然后编辑shader就可以制作Ui的shader效果了包括边框流动反光置灰等效果。 比如置灰的效果
half4 frag (v2f i) : SV_Target{half4 color tex2D(_MainTex, i.uv);float gray dot(color.rgb, half3(0.299, 0.587, 0.114));return half4(gray, gray, gray, color.a);}再比如边框流光的效果 shader代码太长核心部分
half4 frag (v2f i) : SV_Target
{half4 color tex2D(_MainTex, i.uv)*_Color;half4 flowingColortex2D(_FlowingTex,i.uv1);if(color.a0.1){return colorflowingColor;}return color;} 僵尸Image置灰加边框流光 图片来自B站视频BV1bR4UeyEa8 图片来自B站视频BV1bR4UeyEa8 1.3.粒子特效 Ui和粒子特效有时候需要结合使用。粒子特效是3d空间的在overlay的Canvas下建一个粒子特效是根本看不见的。所以需要Cmaera模式的Canvas来配合使用。这种情况下就需要一个单独的Ui相机这个ui相机需要叠加到主相机上所以需要设置模式为Depth Only,然后主相机就可以去除掉Ui的渲染UI相机则用来渲染需要和3d空间排序的UI。 图片来自B站视频BV1bR4UeyEa8 关于图中右上角的正常Ui这是要表达无需和3d空间排序的Ui放在overlay模式的canvas中就可以了。图中右下角所说的放所需背景“的含义是这种模式下UI主要是作为特效的背景进行使用。 camera模式常用的特效效果如下 主界面点击屏幕出现波纹 Ui玩家互相遮挡 上面这张图片就是用两种canvas制作的首先是camera模式的Ui上下两个横幅Ui充当商人的背景。 然后是正常Ui在最前面遮挡所有的 1.4.更复杂的粒子特效 图片来自B站视频BV1bR4UeyEa8 上图看着有点复杂其实简而言之就是复杂的内容需要自己处理就比如给粒子系统加上遮罩那就获取到particle system然后在OnPopulateMesh方法中获得单个粒子的quad判断位置决定显隐就行了。不过一般用插件就行了我倒是没用过好像UIParticle不错 1.5.动画/序列帧动画 上面的内容很多情况下都可以考虑使用动画系统包括流光闪光这些其实都可以用动画系统控制相关的位置来达到相关效果包括加载动画的粒子特效遮罩等。 七、UI技巧 1.自适应 这个算是非常常见的需求了比如文本自适应大小提示框自适应大小。 首先是文本自适应大小这个很简单直接在Text上加ContentsizeFilter然后设置要扩展的方向为prefeeredSize就行了 。简单来说ContentSizeFilter就是根据Text等能够提供期望宽高的提供的期望宽高来动态调整自身宽高的组件所以可以自适应宽高。 随着数字增加自动变高 然后是对话框自适应大小 。 要制作对话框首先创建一个Image把文本框包裹起来文本框使用和上面文本自适应一样的设置。然后在Image上添加一个布局组件gridLayoutGroup,verticalLayoutGroup,HorizontalGroupLayout都行取决于你的文本框想要横向自适应大小还是竖向。添加布局组建后再添加一个ContentSizeFilter就可以并设置自适应方向为PreferredSize就行了。此时自适应对话框就制作完成了。简单来说就是文本会自适应宽高然后背景图片的layoutGroup组件可以获取子物体的宽高然后得到自己的期望宽高背景图片上的ContentSizeFilter得到这个期望宽高再调整自己的宽高就完成了自适应。 要制作多个子级的话原理也是一样背景添加一个布局组和ContetntSIzeFilter就行然后各个子物体添加contentsizeFilter就行。 如图黑色背景添加VerticalLayoutGroup,contentSizeFilterContetntSizeFilter设置为纵向扩展然后添加自定义文字区域添加ContentSizeFilter然后添加两张图片图片不需要ContentSizeFilter因为他的长度不是自适应变化的然后再加一个文字区域(添加ContentSizeFilter)。 其实上面的方法不是特别标准也会有上图中的警告虽然能达到效果。这就需要引出layoutGroup的知识这一块很复杂懒得学的话也可以直接就用上面的方法制作自适应。 1.1.LayoutGroup控制 以下LayoutGroup相关内容来自B站UP主Async_Officia的视频我对其做了文字版总结。 Unity的Horizontal Layout Group 和Vertical Layout Group的作用 首先建立如图的UI结构黑色背景长宽为900x900挂载HorizontalLayoutGroup,关闭ChildForceExpand,然后添加红绿蓝三个Image它们都是正方形长度分别为100200200。 1.1.1.Child Force Expand ChildForceExpand是将剩余空间分配各个子物体简单来说有几个子物体就把剩余空间等分后分给子物体。当勾选childForceExpande的width,变为如下效果 然后上图中可以看到剩余空间均分后构成了三个区域child Alignment就决定子物体在区域的哪一部分childLayoutment中前面的Uppe,middle,lower等表示在父物体的上中下方后面Left,center,right的表示子物体在分成的区域中的左中右 就比如这个例子中把upperLeft改为upperCenter就会发现子物体在区域的中间 1.1.2.ControlChildSize 先关闭Child Force Expand单独打开ControlChildSize的Width会发现子物体都看不见了 此时子物体的width都变成了0因为没有宽高信息如果Image的Sprite不为空的话其实就有宽高信息就不会变成0,但是Sprite为空的时候就没有宽高信息这个时候子物体的width就由布局组件来控制了不再允许手动设置的大小。此时我们就需要LayoutElement来告诉它我们想要的宽度和高度。当然了在Image有sprite可以正常显示的情况下LayoutElement也可以覆盖Sprite的宽高信息 如图把期望宽度preffered设置为100就会显示了还有一个MinWidth我没有设置它是最小宽度如果设置了当布局组件发生长宽变化的时候如果父物体空间不够的话子物体的长度宽度就会缩小,缩小到MinWidth的时候就不会再继续缩小了之后就会强行使用MinWidth来显示宽度。Height也是同理只不过我们没有勾选Height勾选ControlChildSize的Height后就可以用同样的方式来控制子物体的长宽。 1.1.2.1.flexible width 当父物体的空间大于所有子物体的期望空间之和的时候这里是没有勾选Child Force Expand的情况如果勾选Flexible width子物体就会根据flexible width的比例来侵占剩余空间。比如都没有勾选那就都是0所以不会侵占空间如果有一个勾选并设置大于0的值那么那个就会侵占所有剩余空间。有两个勾选了并且设置的数值相等那么就两个子物体每个占50%,如果他们设置的值不等比如绿色设置1蓝色设置3那么绿色就获得剩余空间的25蓝色获得剩余空间的75%。注意这里的侵占是和Child Forece Expand不同这里是直接更改子物体的长宽因为勾选的就是Control child Size。 1.1.3.Control Child Size和Child Force Expand结合使用 首先要知道的是ChilForceExpand会把多余区域分给子物体构成子物体区域子物体可以在其中设置左中右位置。 然后Control Child Size使用Layout Element控制最小长宽(Min Width)期望长宽(Preferred Width)和可变长宽(Flexible Width),MinWdith决定最小宽度Preferred Width决定期望宽度当子物体剩余空间不足时会向最小宽度缩小而当子物体剩余空间足够而又没有启用可变长宽那么自子物体会保持期望长宽。当子物体剩余空间足够又启用了可变长宽那么子物体会根据可变长宽比例瓜分剩余空间。 如果结合起来使用勾选child Force Expand后会对子物体进行分区此时勾选Control child size那么就会强制所有Flexible为1以侵占剩余空间此时修改每个子物体的FlexibleWidth也是有效的但是只能设置大于等于1的值。这种情况和只勾选control child size然后把所有子物体的flexible设置为1的效果是一样的。因为child Force Expand分区的时候已经把剩余区域根据比例分给子物体了所以这里认为子物体是侵占了分区的空间和按比例侵占了剩余的空间是等价的。 关于横向布局中的childForceExpand中的Height和Control childSize中的height。把childForceExpand理解成把剩余高度都分到一个区域内就行了此时如果再勾选Control child Size的height,那就是填满整个区域。就算不勾选childForceExpand只勾选Control childSize也会把高度自动铺满整个空间。 1.1.4.UseScale 这个就很简单了勾选后再布局的时候把缩放也考虑在内而已比如绿色是200长度。勾选后缩放改为2计算的时候就把绿色当作400长度计算布局。 1.2.标准的的自适应Ui设置方法 在学习了上面的知识后就可以知道标准的自适应内容方法了。 之前说过LayoutGroup组件是基于子物体的PreferedHeight或者PreferredWidth来计算布局的没有Sprite的Image的Preferred宽高为0所以要用LayoutElement来提供。但其实Text组件,InputField组件都会实时提供这些属性所以layoutGroup可以直接根据这些属性来控制他们的宽高以实现自适应宽高带有Sprite的Image组件没有明说会提供但是应该也是提供的。对了前提是开启了ControleChildSize 所以LayoutGroup本身就可以让子物体自适应宽高而无需让子物体添加ContentSizeFilter图片等要控制宽高的话就添加LayoutElment就可以设置期望宽高。 如图分别为自适应高度文字区域1两个图像和自适应高度文字区域2他们都没有添加ContentSIzeFilter和LayoutElement,如果觉得图片小了添加LayoutElement设置就可以了。 文本自适应大小 但是还有个问题就是背景没有随着所有子物体所占区域进行自适应。之前也说了GroupLayout本身会提供所有子物体所占的PreferredSize所以再给LayoutGroup组件添加一个ContentSizeFilter并设置verticalFit为prefferedSize就行了。 1.2.1.更新不及时导致的bug Unity 的 Layout Group 组件默认不会在每一帧都刷新布局它通常会等到 End of Frame 或 LateUpdate 之后才会刷新。因此你可以在文本变动后手动强制刷新 Layout。 解决方法 在修改 Text 内容后手动调用
LayoutRebuilder.ForceRebuildLayoutImmediate(targetPanel); 具体例子 void Update(){if (Input.GetKeyDown(KeyCode.Space)) // 模拟文本变化{textComponent.text 新增文本; ForceRefresh();}}void ForceRefresh(){//targetPanel 需要是 GridLayoutGroup 所在的 RectTransform或者更高一级的 Layout GroupLayoutRebuilder.ForceRebuildLayoutImmediate(targetPanel);} 1.3.安全区 安全区是指现在手机有许多异性屏某些地方不应该显示Ui不然就被手机的刘海或者前置摄像头挡住了因此要修改画布的锚点来避开显示。 Unity提供了Scrren.safeArea来获取当前设备的安全区域用它来动态调整UI布局。
using UnityEngine;public class SafeAreaHandler : MonoBehaviour
{private RectTransform rectTransform;private Rect lastSafeArea new Rect(0, 0, 0, 0);void Start(){rectTransform GetComponentRectTransform();ApplySafeArea();}void ApplySafeArea(){Rect safeArea Screen.safeArea;if (safeArea ! lastSafeArea) // 只有在区域变更时更新{lastSafeArea safeArea;// 转换 SafeArea 到 UI 坐标系Vector2 anchorMin new Vector2(safeArea.x / Screen.width, safeArea.y / Screen.height);Vector2 anchorMax new Vector2((safeArea.x safeArea.width) / Screen.width, (safeArea.y safeArea.height) / Screen.height);rectTransform.anchorMin anchorMin;rectTransform.anchorMax anchorMax;}}void Update(){// 处理屏幕旋转避免适配失效if (Screen.safeArea ! lastSafeArea){ApplySafeArea();}}
}七、UI优化 待续说实话个人感觉Ui没必要优化能耗多少性能