【狗刨学习网】 随着 Unity 4.6 发布,新 UI 系统终于与大家见面了。 RectTransform Unity UI 系统使用 RectTransform 实现基本的布局和层次控制。RectTransform 继承于 Transform,所以 Transform 的所有特征 RectTransform 同样拥有。在 轴心:表示UI元素的中心,使用相对于自身矩形范围的百分比表示的点位置,这会影响定位、缩放和旋转。 锚点:相对于父级矩形的子矩形区域,这个矩形各个边界值使用百分比表示。 尺寸变化量:相对锚点定义的子矩形的大小变化量,与锚点定义的子矩形合并后的区域才是最终的UI矩形。 在 Inspector 界面上,为了更方便的调节 RectTransform 的属性,锚点的两个点重合时会显示位置和宽高(直接调节位置和sizeDelta),否则显示相对锚点矩形边界的偏移量(通过计算后再赋值给位置和sizeDelta)。在程序中,RectTransform RectTransform 组件同样负责组织 GameObject 的层级关系。在 UI 系统中,子级 UI 对象总是覆盖显示在父级 UI 对象上;层级相同的 UI 对象,下方的 UI 对象总是覆盖显示在上方的 EventSystem 如果你使用 UI 系统,那么 EventSystem 对象会自动创建。这个对象负责监听用户输入。默认情况下,在电脑上可以使用键盘和鼠标输入,在移动设备上可以使用触摸输入。但是如果你要为surface这样的设备开发,你也可以同时启用两种输入。当需要屏蔽用户输入时,将此对象关闭即可。UnityEngine.EventSystems.EventSystem.current Canvas Canvas 是其他所有 UI 对象的根。在一个场景里 Canvas 数量和层级都没有限制。子 Canvas 使用与父 Canvas 相同的渲染模式。一个 Canvas 有三种渲染模式: Screen Space - Overlay:UI元素相对于屏幕空间,以2D方式显示在任何相机画面的上面。这是非常标准的 Screen Space - Camera:UI元素相对于屏幕空间,由指定的相机负责显示,相机的参数影响显示的结果。你可以把 World Space:UI元素相对于世界空间,和其他场景里的物体一样有世界位置、遮挡关系。通常用来做非常创新的 CanvasScaler 这个组件负责屏幕适配。UI 系统使用 RectTransform 来计算 UI 的位置和大小,但这还不够。如何让设计的 UI 可以适配不同的分辨率、宽高比和 DPI?这个组件给出了以下3种适配方法,注意任何一种适配方法都不会改变UI的宽高比和相对定位。 Constant Pixel Size:通过调节 Canvas 像素大小来维持缩放不变。它的意思是在任何屏幕上不改变 Scale With Screen Size:根据屏幕分辨率缩放。这可能是大部分游戏最方便的适配方法。在这种模式下,你需要指定一种设计分辨率,然后指定缩放的算法。无论哪种缩放算法,如果实际宽高比与设计宽高比相同,UI
Constant Physical Size:通过调节 Canvas 物理大小来维持缩放不变。它的意思是在任何屏幕上不改变 Selectable 可交互UI组件的基类。它负责响应用户的输入,产生视觉变化、切换导航目标 以及 处理通用的UI事件。 Transition:可交互组件有4种视觉状态:正常(normal), 高亮(highlighted), Navigation:可以使用键盘和游戏控制器切换导航目标,如果你要开发一个仅使用游戏控制器就可以玩的游戏(主机游戏),那么这个功能非常重要,因为玩家没有鼠标也无法使用触摸屏,只能通过按钮来切换导航目标。这个功能被设计的非常完善,以至于你几乎什么都不用做就可以处理的很好。一共有5种导航选项:不使用(None)、水平(Horizontal)、垂直(Vertical)、自动(Automatic)、显式指定(Explicit)。在非显式指定的情况下,导航系统根据每个UI元素的矩形位置和大小,自动查找4个方向上是否存在最合适的切换目标。如果选择显式指定,需要为4个方向指定切换目标(Selectable)。在Inspector 通用事件:OnSelect, OnDeselect, OnPointEnter, OnPointExit, Auto Layout 自动布局用于简化UI的布局工作。自动布局基于 RectTransform 的布局系统,包含 布局元素(Layout Elements) 和 布局控制器(Layout Controllers)两个概念。 布局元素含有 最小尺寸、首选尺寸 和 可选尺寸 这些参数,布局控制器根据这些参数来调整布局元素的大小和位置。布局控制器调整的基本原则是:首先分配最小尺寸,然后如果还有足够空间就分配首选尺寸,最后如果还有空间则分配可选尺寸。一个含有 Rich Text 默认情况下一个 Text 组件以单一样式显示所有文本,使用富文本可以让显示样式更丰富,比如高亮部分文本。实际上,富文本功能不仅可以用在 UI 系统,还可以用在 Legacy GUI 系统 和 Debug 中。 富文本使用方法类似 html 标签,比如 "Hello" 将显示为加粗的 "Hello"。这些标签还可以嵌套使用。可用的标签有
如果使用 TextMesh,还可以使用 material 和 quad 标签。material 需要指定 material 数组中的 material 下标,如 "Cool";quad 标签没有结束标签,通常用来在文本中显示一个图片,如 UnityEvent 一个可序列化的、可显示在 Inspector 上的事件类型。典型的用途就是 Button 的 OnClick 事件。拖拽一个对象或组件到方框中,就可以选择事件触发时调用的方法。可选方法必须是公开的、无返回值的、含有0个或1个可序列化的参数。也可以调用 UnityEvent 可以通过代码添加、移除或调用方法,是对 C# 的 delegate 的包装。另外还有泛型版本的 UnityEvent,最多支持 4 个参数,不过由于是泛型抽象类,需要先继承再使用。 public class MyEvent : UnityEvent { } public MyEvent UnityEvent 是从程序里通过 Invoke 方法调用的,Invoke 需要的参数类型和数量与泛型参数一致。但是,Inspector上依然只能填写0个或1个参数,在 Inspector 上添加的方法是无法直接获得 自定义控件 通过此自定义控件的例子,来说明如何灵活运用 UI 系统各种功能实现各种奇葩需求。 需求:实现一种角色点数分配的控件,角色有一定数量的点数,可以分配给多种属性,每种属性都可以分配一定范围的点数,各属性点数之和不能超过角色拥有的点数。一般的实现方法是,为每个角色显示剩余点数和多条属性滑块,拖动每个滑块会改变剩余点数。这里我们要求把所有滑块放到一个大滑动条中,可以直接拖动每个滑块。这样的好处是可以直观的看到每个角色总能力对比以及剩余可分配点数。如下为设计图。 我们先分析这个需求:整个滑动条代表点数总量;所有滑块是左对齐拼接的;每个滑块具有自身最大值、最小值限制;所有滑块总长度不超过整个滑动条;每个滑块是可交互的。可以得到初步的设想是,每个滑块拥有一个继承 Selectable // 属性 class Attribute{ public string name; public Sprite image; public Color color; public int min; public int max; public int value; public ValueSlider valueSlider; } min、max、value 分别为 最小点数、最大点数 和 初始点数。最后一个 ValueSlider 就是我们自定义的 Selectable 组件,在属性里保存对应的组件引用方便对其进行修改。ValueSlider // 滑块 class ValueSlider : Selectable{ MultiAttributesSlider _multiAttributesSlider; Attribute _attribute; public void Init(MultiAttributesSlider multiAttributesSlider, Attribute attribute) { _multiAttributesSlider = multiAttributesSlider; _attribute = attribute; } public override void OnPointerDown(PointerEventData base.OnPointerDown(eventData); _multiAttributesSlider.BeginSlide(_attribute, eventData); } public override void OnPointerUp(PointerEventData base.OnPointerUp(eventData); _multiAttributesSlider.EndSlide(); } } 初始化的时候保存根部组件(起个名字叫“多属性滑动条”)和对应的属性引用,然后按下和弹起时分别调用根部组件的开始滑动、结束滑动方法。没有什么实际的内容,主要的操作都在根部组件上。根部组件定义如下: class MultiAttributesSlider : MonoBehaviour{ // 总点数 int _totalValue; // 属性数组 [SerializeField] Attribute[] _attributes; //剩余点数 int _restValue; // 一个点数对应的像素大小 float pixelsPerPoint; // 保存滑块按下时的信息 Attribute _currentAttribute = null; PointerEventData _eventData; int _beginValue; int _beginRestValue; // 当鼠标按下任何一个滑块时调用 public void BeginSlide(Attribute currentAttribute, PointerEventData eventData) { _currentAttribute = currentAttribute; _eventData = eventData; _beginValue = currentAttribute.value; _beginRestValue = _restValue; } // 当鼠标从任何一个滑块释放时调用 public void EndSlide() { _currentAttribute = null; } // 初始化 void Awake() { // 需要通过自定义编辑器来保证 Inspector 填写的参数完全合理。这个例子忽略这一步。 // 统计已使用的点数 int valueCount = 0; for(int i=0; i<_attributes.Length; valueCount += _attributes.value; } // 计算剩余点数 _restValue = _totalValue - valueCount; RectTransform lastParent = transform as RectTransform; // 计算一个点数对应的像素大小 pixelsPerPoint = lastParent.sizeDelta.x / _totalValue; // 创建每个滑块;更好的做法是,在自定义编辑器中使用一个按钮来生成所有滑块 for(int i=0; GameObject slider = new GameObject(_attributes.name); // 初始化 RectTransform RectTransform rect = slider.AddComponent(); rect.SetParent(lastParent, false); rect.localScale = Vector3.one; rect.localRotation = Quaternion.identity; rect.pivot = new Vector2(0, 0.5f); rect.anchoredPosition = Vector2.zero; if (i == 0) { rect.anchorMin = Vector2.zero; rect.anchorMax = new Vector2(0, 1); } else { rect.anchorMin = new Vector2(1, 0); rect.anchorMax = Vector2.one; } rect.sizeDelta = new Vector2(pixelsPerPoint * _attributes.value, 0); // 初始化 Image Image image = slider.AddComponent(); image.sprite = _attributes.image; image.color = _attributes.color; image.type = Image.Type.Sliced; image.fillCenter = true; // 初始化 ValueSlider _attributes.valueSlider _attributes.valueSlider.Init(this, _attributes); // 将当前 RectTransform 作为下一个滑块的父级 lastParent = rect; } } // 更新滑块的值 void Update() { if(_currentAttribute != null) { // 计算滑动距离对应的点数变化 int deltaValue = Mathf.RoundToInt((_eventData.position.x - _eventData.pressPosition.x) / pixelsPerPoint); // 受最小、最大值限制的点数变化 deltaValue = Mathf.Clamp(_beginValue + deltaValue, _currentAttribute.min, _currentAttribute.max) - _beginValue; // 更新剩余点数 _restValue = _beginRestValue - deltaValue; // 如果剩余点数用完,需要减少点数变化 if(_restValue < 0) { deltaValue += _restValue; _restValue = 0; } // 更新当前点数 _currentAttribute.value = _beginValue + deltaValue; // 更新滑块大小 (_currentAttribute.valueSlider.transform as RectTransform).sizeDelta = new Vector2(pixelsPerPoint * _currentAttribute.value, 0); } } } 代码的含义在上面的分析和注释里写的很清楚了,不再赘述。这个组件最好再配合一个自定义的编辑器,但是这里就不想写了,如果你感兴趣可以试试。 下面就是测试。创建一个滑动条背景,添加此脚本,填写参数,最后看起来这样的: 然后运行起来吧。图就不截了,就是上面的设计图......最后再来张合影。 声明:此篇文档时来自于【狗刨学习网】社区,是网友自行发布的Unity3D学习文章,如果有什么内容侵犯了你的相关权益,请与官方沟通,我们会即时处理。 更多精彩内容:www.gopedu.com |
全面理解 Unity UI 系统
时间: 2024-10-06 01:18:46
全面理解 Unity UI 系统的相关文章
理解和使用 Unity UI 系统
随着 Unity 4.6 发布,新 UI 系统终于与大家见面了.这篇文章将不会介绍如何使用按钮.滚动条之类的UI控件,这些内容可以参考Unity Manual:这篇文章的重点是,如何理解 UI 系统的设计,以便更好的在实际中使用.自定义和扩展. EventSystem 如果你使用 UI 系统,那么 EventSystem 对象会自动创建.这个对象负责监听用户输入.默认情况下,在电脑上可以使用键盘和鼠标输入,在移动设备上可以使用触摸输入.但是如果你要为surface这样的设备开发,你也可以同时启用
Unity3D 4.6 新的UI系统
在Unity3D 4.6版本中,终于增加了新的UI系统.虽然从功能,效果等方面来讲,跟NGUI还有一定的差距,但NGUI毕竟是收费插件,对于游戏商用来说有一定的制约. 下面我们来看看,Unity3D 4.6中新的UI系统吧. 如上图所示,我们可以看到在GameObject菜单中,已将3D Object,2D Object和UI分类了. UI中,我们可以看到Panel,Button,Text,Image,RawImage,Slider,Scrollbar,Toggle,InputField,Can
【Unity编程】Unity动画系统(一)
Unity动画系统 Unity动画系统,也称为"Mecanim",提供了以下功能: 简单的工作流程,设置动画的所有元素,包括对象,角色和属性. 支持导入外部创建的动画片段和使用内置动画编辑器制作的动画片段. 人型动画重新定位,动画角色的运动控制可以被所有的角色模型共享,即角色的外观(SkinedMesh)和运动(Animator)是分离的,它们互相组合之后形成最终的动画. 用于编辑动画状态的的简化工作流程,即动画控制器. 方便预览动画片段,以及片段之间的插值过渡. 这使得动画师可以独立
《深入理解Android 卷III》第五章 深入理解Android输入系统
<深入理解Android 卷III>即将公布.作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白.即Android Framework中和UI相关的部分.在一个特别讲究颜值的时代,本书分析了Android 4.2中WindowManagerService.ViewRoot.Input系统.StatusBar.Wallpaper等重要"颜值绘制/处理"模块 第5章 深入理解Android输入系统(节选) 本章主要内容: · 研究输入事件从设
[转]深入理解 Android消息处理系统的原理
原文地址:深入理解 Android消息处理系统的原理作者:hoarn Android应用程序也是消息驱动的,按道理来说也应该提供消息循环机制.实际上谷歌参考了Windows的消息循环机制,也在Android系统中实现了消息循环机制. Android通过Looper.Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列和消息循环). 本文深入介绍一下Android消息处理系统原理. Android系统中Looper负责管理线程的消息队列和消息循环,具
Unity4.6新UI系统初探(uGUI)
一.引言 Unity终于在即将到来的4.6版本内集成了所见即所得的UI解决方案(视频).事实上从近几个版本开始,Unity就在为这套系统做技术扩展,以保证最终能实现较理想的UI系统.本文试图通过初步的介绍和试用,让读者对这套系统有大体的了解,以便更进一步评估这套UI系统好不好用,适合用在什么项目.为了避免坑挖太深,更进一步的试用和评估我将在<用uGUI开发自定义Toggle Slider控件>中进行论述.为论述方便,下文将这套New UI System简称为uGUI,并且以X-UI指代现有第三
UNITY光照系统简介
UNITY_光照系统 光照系统又称照明系统: 从字面意思理解,光照系统的作用就是给我们的场景带来光源,用于照亮场景.一个五彩缤纷的游戏场景肯定要比一个漆黑一片的游戏场景更具吸引力,想让游戏场景变的更漂亮,光照系统是必不可缺的. 在 Unity5.x 中光照系统主要组成部分有两个: 灯光组件(4 个灯光组件,2 个特殊功能组件)以及 Lighting 面板. 两种类型: 实时光照:PC,主机端运行,照明效果好,但是消耗资源较大. 烘焙光照:移动端运行,照明效果也不错,消耗资源较少. 光照系统之实时
Linux系统理解以及Linux系统学习心得
原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 作者:严哲璟 说一下我对Linux系统的理解 1.加载Linux内核准备:在加载基本输入输出模块(BIOS)之后,从磁盘的引导扇区读入操作系统的代码文件块到内存中,之后开始整个系统的初始化. 2.main.c的start_kernel函数是整个操作系统的入口,这也与Linux是基于C语言的特性相符,start_kernel具体做的动作很多
doom3的UI系统
doom3的UI系统是纯数据驱动的,例如 windowDef TextTitle2 { rect 20,341,600,55 visible 1 text "#str_00073" forecolor 0.6,1,1,0 textscale 0.8 font "fonts/micro" textalign 1 notime 1 onTime 0 { transition "forecolor" "1 1 1 0" "