本文目录
tmw制作血条
这篇文章为大家介绍两种血条的制作的方法
第一种就是使用Image搭配遮罩来制作一个血条。
1.新建一个unity工程,然后新建一个场景。
2.Hierarchy面板里新建一个Panel,在右边的inspector里将Color的其调为不透明,颜色调成灰色。
3.在Panel下面新建一个Image,将Rect Transform的Width调为400,Height调为50,为其选上一张适当的的背景图片作为血条的背景,将填充色调为黑灰色。
4.再在Panel下面新建一个Image,命名为fill,同样的将Rect Transform下的Width调为400,Height调为50,为其填充为蓝色,然后将fill设置为的Image的子级,并给Image添加Mask组件。这是左右拖动fill,就是产生如下效果。
5.接下我们为fill添加一个脚本来控制血量。
完成后改变currentHP的值就会发现血条的血量也会跟着变化.
第二种就是使用UGUI自身的的Slider来制作血条,这一种相对第一种来说简单许多。
1.新建一个场景,Hierarchy面板里新建一个Panel,在右边的inspector里将Color的其调为不透明,颜色调成灰色。
2.右击Panel,在UI下选择Slider,然后删除Handle Slide Area,并将Fill Area的Rect Transform的left和Right设置为0,将Fill的width设置为0.将slider的Width调为400,Height调为50。接着将Fill的颜色设置为绿色。设置好如下图所示。
3.下来来到Slider的inspector面板里将Max Value的值设置为100。然后运行工程拖动右侧Value的滑动条就可以控制血量。
ug的ui样式编辑器
在NGUI 2.7的示例程序中有Example 7 - Scroll View (Panel),这个滚动视图的例子很好的演示了如何搭建一个可以上下滚动的效果。这个例子中如果选中Center On Items的复选框,那么每次滚动结束都会有一个Grid是正好滚到正中间的。但是这里没有实现让点中的Grid滚到正中间的代码。实现起来很简单,只需要重写UICenterOnChild这个类,在Recenter函数中在计算closest transform,我们只需要把Click 选中的Grid的Transform传到这里,然后在每次Click选中Grid的事件处理中调用这个函数就可以实现这个效果了。
unity togglegroup 当前选中的
参考
Unity 3D UGUI Toggle用法教程
Is On :用来表示Toggle当前开关状态,勾选为开;
Graphic :控制Toggle组件开关图片的显示隐藏,默认选取Checkmark,就是那个勾勾图片;
挂上这个脚本,会发现事件中有一个带参数的,还有一个不带参数的:
虽然ListenInFunction是带参数的,但是却要选上面那个绿色不带参数的,刚开始我是懵逼的…………
参照 UGUI中Button和Toggle 添加动态事件 得到了解释:
选下方红色的静态方法,其实UI中会多出一个checkbox,可以指定传入的参数:
当然也可以传入其它类型,比如
参考
Unity UGUI入门组件整理(三)【Toggle组件与Toggle Group组件】
假如初始状态是Toggle3被勾选,当我点击Toggle1勾选时,打印如下:
这样就可以根据名字和选中状态来做逻辑处理了。
是否允许不打开任何开关?如果启用此设置,则按下当前打开的开关会将其关闭,因此没有任何开关处于打开状态。如果禁用此设置,则按下当前打开的开关将不改变该开关的状态。
这个说的有点绕,并且有些博客上还有种错误的说法,就是这个开关能允许Group多选。其实测试一下就知道了,在勾选Allow Switch off时,点击当前选中的Toggle,可以将当前Toggle改成未选择状态,此时整个Group中所有的Toggle都会处于未选择状态。而如果没勾选Allow Switch off,就达不到这个效果,会强迫你必须选一个。
在官方文档中,描述ToggleGroup叫开关组:
UGUI学习笔记(五) ToggleGroup制作选择题单选框
ugui layout 性能
一、 UGUI布局系统由 布局元素 (Layout Elements)和 布局控制器 (Layout Controller)组成。
1、布局控制器的基础接口为ILayoutController。
(1)ILayoutController有两个方法,布局系统调用这两个方法的顺序是固定的,首先调用SetLayoutHorizontal,再调用SetLayoutVertical:
A、void SetLayoutHorizontal() :处理水平方向的布局;
B、void SetLayoutVertical() :处理垂直方向的布局。
(2)继承ILayoutController的两个接口:
A、ILayoutSelfController :只控制自己RectTransform的改变;继承ILayoutSelfController的两个类如下:
[1] (内容尺寸适配器) Content Size Fitter <—— ILayoutSelfController:根据孩子中布局元素的尺寸及自身包含内容的多少控制自身的尺寸;
[2] (纵横比适配器) AspectRatioFitter <—— ILayoutSelfController:根据自身设置的模式(AspectMode)和比率(Aspect Ratio)以及宽或高调整另一边的大小,不受子元素的影响。
B、ILayoutGroup :控制所有孩子节点的布局变化。这个接口就是我们比较熟悉的接口,平时项目中使用的很多布局组件都继承该接口:
[1] ScrollRect <—— ILayoutGroup;
[2] GridLayoutGroup <—— LayoutGroup <—— ILayoutGroup;
[3] HorizontalLayoutGroup\VerticalLayoutGroup->HorizontalOrVerticalLayoutGroup <—— LayoutGroup <—— ILayoutGroup
2、所有包含RectTransform组件的GameObject都视为布局元素。
(1)布局元素拥有一些定义自身尺寸的属性:
A、Minimum width:最小宽度;
B、Minimum height:最小高度;
C、Preferred width:如果有充足的空间可以分配的最合适宽度;
D、Preferred height:如果有充足的空间可以分配的最合适高度;
E、Flexible width:灵活宽度,一般是相对于父元素的比例;
F、Flexible height:灵活高度,一般是相对于父元素的比例。
默认情况下,Minimum width、Minimum height、Preferred width、Preferred height均为0,Flexible width、Flexible height都是disabled的。如果想调整这些属性就需要添加继承ILayoutElement接口的组件重写这些值。像我们常用的Text、Image组件都继承了ILayoutElement;同时一些布局控制器自身也继承了ILayoutElement,如:LayoutGroup(包括所有继承LayoutGroup的子类)、ScrollRect;UISystem也创建了一个单独组件LayoutElement继承ILayoutElement,任何一个想重写上述属性的GameObject都可以通过添加LayoutElement组件实现。LayoutElement同时继承了ILayoutIgnorer接口,可以通过设置ignoreLayout决定该GameObject是否被Layout System忽略。
(2)ILayoutElement定义了布局元素用到的属性minWidth、preferredWidth、flexibleWidth、minHeight、preferredHeight、flexibleHeight,
同时定义了两个方法:
void CalculateLayoutInputHorizontal():计算布局元素的minWidth,preferredWidth和flexibleWidth值
void CalculateLayoutInputVertical():计算布局元素的minHeight,preferredHeight和flexibleHeight值
二、布局重建过程
1、首先引起布局重建的元素调用LayoutRebuilder.MarkLayoutForRebuild() ,然后逐层向上递归查找直到找到最上层的布局根节点,这个根节点必须包含继承ILayoutGroup接口、Behaviour类并且isActiveAndEnabled属性为true的组件。然后以这个根节点初始化一个布局重建器LayoutRebuilder,然后将该LayoutRebuilder添加到CanvasUpdateRegistry中m_LayoutRebuildQueue队列中等待处理。调用过程如下:
static void LayoutRebuilder.MarkLayoutForRebuild(RectTransform rect)
->static void LayoutRebuilder.MarkLayoutRootForRebuild(RectTransform controller)
->static bool CanvasUpdateRegistry.TryRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
-> CanvasUpdateRegistry.InternalRegisterCanvasElementForLayoutRebuild(ICanvasElement element)
-> 加入m_LayoutRebuildQueue队列中。
其中有一个比较特殊的就是ScrollRect,在ScrollRect的OnEnable()方法和SetDirtyCaching()方法中会先调用CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this),再调用LayoutRebuilder.MarkLayoutForRebuild(rectTransform)。与LayoutRebuilder比较,ScrollRect本身也继承了ICanvasElement接口。在Rebuild()函数中,ScrollRect针对CanvasUpdate.Prelayout(布局执行前)和CanvasUpdate.PostLayout(布局执行后)两个阶段实现了自己的执行逻辑。而LayoutRebuilder的Rebuild()函数只针对CanvasUpdate.Layout阶段实现对应的执行逻辑
2、CanvasUpdateRegistry构造函数中会将PeformUpdate方法加入Canvas.willRenderCanvases事件中,然后在渲染所有的Canvas之前,抛出willRenderCanvases事件从而调用PeformUpdate(),在PeformUpdate函数中执行步骤如下:
(1)首先会删除m_LayoutRebuildQueue中所有无效的元素;
(2)然后根据节点的深度(父节点个数越大越靠前)对m_LayoutRebuildQueue排序;
(3)然后分别以CanvasUpdate.PreLayout(布局前),CanvasUpdate.Layout(布局),CanvasUpdate.PostLayout(布局后)的参数顺序调用每一个ICanvasElement元素的Rebuild方法;
(4)然后调用所有ICanvasElement元素的LayoutComplete()方法。针对该方法只有LayoutRebuilder类中实现:将该LayoutRebuilder从LayoutRebuilder的静态对象池s_Rebuilders中删除;
(5)然后清空m_LayoutRebuildQueue队列;
(6)布局结束后调用ClipperRegistry.instance.Cull()遍历所有裁剪组件(继承IClipper接口的组件,如RectMask2D)的裁剪方法PerformClipping()。
3、下面看一下ICanvasElement布局重建过程的实现,重建的实现就在LayoutRebuilder的Rebuild方法中,源码如下:
如上所示,整个布局分四个步骤:
(1)对该节点下所有有效(继承Behaviour且isActiveAndEnabled为true)的布局元素(即包含继承ILayoutElement组件的节点)执行CalculateLayoutInputHorizontal()计算水平方向布局尺寸。对孩子的遍历顺序由下往上,因为父节点尺寸计算依赖于子节点的尺寸;虽然针对所有布局元素,但是真正实现CalculateLayoutInputHorizontal()方法的只有LayoutGroup相关的组件。
LayoutGroup实现了一个虚方法CalculateLayoutInputHorizontal(),主要就是收集其子节点下所有没有被标记 ignoreLayout 的物体存到m_RectChildren列表中。LayoutGroup的子类重写该函数时都会先调用这个虚函数,然后再执行自己特有的逻辑。
A、 水平布局组件 HorizontalLayoutGroup <—— HorizontalOrVerticalLayoutGroup <—— LayoutGroup
重写CalculateLayoutInputHorizontal()。如上,首先调用LayoutGroup中CalculateLayoutInputHorizontal()方法,然后调用HorizontalOrVerticalLayoutGroup中的CalcAlongAxis(int axis, bool isVertical)方法,CalcAlongAxis()是一个公用方法,可以根据传入的参数确定计算哪个方向的尺寸,其中axis表示方向(0:horizontal 1:vertical),isVertical判断是否一个Vertical Group。CalcAlongAxis()执行过程如下:
① 首先遍历所有孩子节点调用GetChildSizes()方法获取对应方向上的尺寸(min、preferred、flexible);
② 然后根据所有子节点的尺寸计算当前节点对应方向上的尺寸totalMin、totalPreferred、totalFlexible;
③ 调用SetLayoutInputForAxis()方法将第二步计算的值设置对应的向量m_TotalMinSize、m_TotalPreferredSize、m_TotalFlexibleSize;
B、垂直布局组件VerticalLayoutGroup 重写方法如下,实现参考HorizontalOrVerticalLayoutGroup
(2)对该节点下所有布局控制器(即包含继承ILayoutController组件的节点)执行SetLayoutHorizontal()设置水平布局。对孩子的遍历顺序自上而下,因为孩子节点实际的布局依赖于父节点的布局;
A、HorizontalLayoutGroup和VerticalLayoutGroup中的SetLayoutHorizontal()会直接调用HorizontalOrVerticalLayoutGroup.SetChildrenAlongAxis()方法根据布局方向和布局组件类型设置其下子布局元素的位置和尺寸。
B、GridLayoutGroup也重写了SetLayoutHorizontal()方法,直接调用SetCellsAlongAxis(0),针对水平布局实现如图2-4所示,只设置每个子元素的尺寸,而不会改变子元素的位置。
(3)对该节点下所有布局元素(即包含继承ILayoutElement组件的节点)执行CalculateLayoutInputHorizontal()计算垂直方向布局尺寸;对孩子的遍历顺序由下往上;
(4)对该节点下所有布局控制器(即包含继承ILayoutController组件的节点)执行SetLayoutVertical()设置垂直布局。对孩子的遍历顺序自上而下;
从上面的执行顺序还可以看出,Layout System先搞定水平方向的布局然后才去设置垂直方向的布局。
三、布局重建触发因素
1、 以下函数,都会直接或间接的调用LayoutBuilder.MarkLayoutForRebuild()触发布局重建:
(1)OnEnable() :所有继承ILayoutController或ILayoutElement组件(AspectRatioFitter除外)的OnEnable()方法都会都会间接调用LayoutBuilder.MarkLayoutForRebuild();
A、Graphic :OnEnable() -> SetAllDirty() -> ( m_SkipLayoutUpdate变量为false时才会调用 )LayoutBuilder.MarkLayoutForRebuild();
B、LayoutGroup\ContentSizeFitter\LayoutElement\ScrollRect :OnEnable() -> SetDirty() -> LayoutBuilder.MarkLayoutForRebuild()。
(2)OnDisable() :所有继承ILayoutController或ILayoutElement组件的OnDisable()方法都会调用LayoutBuilder.MarkLayoutForRebuild()
(3)OnRectTransformDimensionsChange(): RectTransform尺寸变化时调用。继承自UIBehaviour的ContentSizeFitter、LayoutGroup、ScrollRect、Graphic都重写了该方法,具体调用如下:
A、ContentSizeFitter :OnRectTransformDimensionsChange() ->SetDirty() -> (IsActive()为true才会调用)LayoutRebuilder.MarkLayoutForRebuild();
B、LayoutGroup :OnRectTransformDimensionsChange() ->(isRootLayoutGroup为true时才会调用)SetDirty() ->(IsActive()为true时才会调用)LayoutRebuilder.MarkLayoutForRebuild();
C、ScrollRect :OnRectTransformDimensionsChange() -> SetDirty() ->( IsActive()为true时才会调用 )LayoutRebuilder.MarkLayoutForRebuild();
D、Graphic :OnRectTransformDimensionsChange() ->( gameObject.activeInHierarchy为true时才会调用 )SetLayoutDirty() ->(IsActive()为true时才会调用)LayoutRebuilder.MarkLayoutForRebuild();
(4)OnDidApplyAnimationProperties(): 动画导致属性( 重写OnDidApplyAnimationProperties()方法的类自身所特有的属性 )改变时调用。继承UIBehaviour的Graphic、LayoutGroup、LayoutElement都重写了该方法,具体调用如下:
A、Graphic :OnDidApplyAnimationProperties() -> SetAllDirty() -> ( m_SkipLayoutUpdate变量为false时才会调用 )LayoutBuilder.MarkLayoutForRebuild()。Graphic本身是个抽象类,不能当作组件直接添加,而继承自Graphic的Image\Text( ——> MaskableGraphic ——> Graphic)组件的一些特有属性,如图3-1红框内标记,当动画改变Text的这些属性时会调用OnDidApplyAnimationProperties()函数。如图3-2红框内标记,当动画改变Image的这些属性时会调用OnDidApplyAnimationProperties()函数。
B、LayoutGroup :OnDidApplyAnimationProperties() -> SetDirty() -> ( IsActive()为true时才会调用 )LayoutBuilder.MarkLayoutForRebuild()
如图3-3、3-4、3-5分别是VerticalLayoutGroup、HorizontalLayoutGroup,当动画改变VerticalLayoutGroup的这些属性时会调用OnDidApplyAnimationProperties()函数。
C、LayoutElement :OnDidApplyAnimationProperties() -> SetDirty() -> ( IsActive()为true时才会调用 )LayoutBuilder.MarkLayoutForRebuild()
如图3-6所示,当动画改变LayoutElement的这些属性时会调用OnDidApplyAnimationProperties()函数。
(5)OnBeforeTransformParentChanged() :父节点transform属性变化前调用。继承自UIBehaviour的Graphic和LayoutElement类都重写了该方法:
A、Graphic :OnBeforeTransformParentChanged() -> SetAllDirty() -> LayoutBuilder.MarkLayoutForRebuild()
B、LayoutElement :OnBeforeTransformParentChanged() -> SetDirty() -> LayoutBuilder.MarkLayoutForRebuild()
2、 某些组件特有属性变化或函数调用:
(1)RectTransform 中导致布局变化的属性:Width、Height、Scale、以及锚点变化;
(2)Text 中导致布局变化的属性:text、alignment、fontSize、horizontalOverflow、verticalOverflow、lineSpacing、fontStyle、resizeTextForBestFit、resizeTextMinSize、supportRichText、resizeTextMaxSize、font;方法:FontTextureChanged()。
(3)Image 中导致布局变化的属性:sprite、overrideSprite;方法:SetNativeSize()、OnCanvasHierarchyChanged()。其中OnCanvasHierarchyChanged()只有在canvas.referencePixelsPerUnit变化且Image类型为Sliced或Tiled时才会调用SetLayoutDirty()
(4)LayoutGroup 中导致布局变化的属性:padding、childAlignment;方法:OnTransformChildrenChanged()
(5)GridLayoutGroup 中导致布局变化的属性:startCorner、startAxis、cellSize、spacing、constraint、constraintCount
(6)HorizontalOrVerticalLayoutGroup 中导致布局变化的属性:spacing、childForceExpandWidth、childForceExpandHeight、childControlWidth、childControlHeight、childScaleWidth、childScaleHeight
(7)ContentSizeFitter 中导致布局变化的属性:horizontalFit、verticalFit
(8)LayoutElement 中导致布局变化的属性:ignoreLayout、minWidth、minHeight、preferredWidth、preferredHeight、flexibleWidth、flexibleHeight、layoutPriority
(9)ScrollRect 中导致布局变化的属性:verticalScrollbar、horizontalScrollbar、horizontalScrollbarVisibility、verticalScrollbarVisibility、viewport
四、布局重建分析工具
1、第三节我们总结了一些可能导致布局重建的原因,游戏中尽量避免执行这些操作以减少布局重建,同时尽可能少的使用Layout相关组件以减少CPU时间的占用。通过第二节对重建过程的分析,我们知道每个引起布局重建的元素的元素都会先加入CanvasUpdateRegistry中m_LayoutRebuildQueue队列中,所以我们可以通过反射的方式来获取游戏中引起布局重建的元素(引用
),脚本如下:
public class CheckRebuildElement:MonoBehaviour
{
IList m_LayoutRebuildQueue;
privatevoid Awake()
{
System.Type type = typeof(CanvasUpdateRegistry);
FieldInfo field = type.GetField("m_LayoutRebuildQueue",BindingFlags.NonPublic | BindingFlags.Instance);
m_LayoutRebuildQueue = (IList)field.GetValue(CanvasUpdateRegistry.instance);
}
privatevoid Update()
{
for(int j = 0; j
以上就是关于ugui怎么制作背包系统,tmw制作血条的全部内容,以及ugui怎么制作背包系统的相关内容,希望能够帮到您。
版权声明:本文来自用户投稿,不代表【蒲公英】立场,本平台所发表的文章、图片属于原权利人所有,因客观原因,或会存在不当使用的情况,非恶意侵犯原权利人相关权益,敬请相关权利人谅解并与我们联系(邮箱:350149276@qq.com)我们将及时处理,共同维护良好的网络创作环境。