Graphical User Interface,图形用户界面
1、OnGUI:OnGUI是Unityl中通过代码驱动的GUI系统。
2、NGUI:第三方插件包,是Unity一直以来最流行的UI插件。
3、UGUI:从Unity4.6开始后,Unity:找到NGUI的作者,用了一年开发了UGUI,
变成内置于Unity中的包,集成到了编辑器中。
OnGUI
- 主要用来创建调试工具、创建自定义属性面板、创建新的Editor窗口和工具达到扩展编辑器效果。
- OnGUI不建议使用在项目UI中。
private void OnGUI()
{
GUI.Box(new Rect(10f, 10f, 50f, 50f), "box");
if (GUI.Button(new Rect(10f, 70f, 50f, 25f), "Button"))
{
Debug.Log("点击了Button");
}
}
UGUI
Text
- Font:字体
- Font Style:字体类型(Normal:正常 Bold:加粗;Italic:斜体;Bold And Italic)
- Font Size:字体大小
- Line Spacing:行间距
- Rich Text: 可以结合多种字体类型和大小
<i>Text</i>
<size=15>Text</size>
<color=black>Text</color>
<color=#0500CD>Text</color>
- Alignment:对齐方式
- Align By Geometr:几何方向对齐
- Horizontal Oveflow:水平方向溢出方式(Wrap:自动换行;Overflow:溢出显示)
- Vertical Overflow:垂直方向溢出方式(TrunCate:截断不显示;Overflow:溢出显示)
- Best Fit:字体最佳适应大小
- Color:颜色与透明度
- 脚本上有Color、Color32的区别,Color类是Float类型的参数,大小为0-1,Color32是Int类型参数,大小为0~255
- Material:材质
- Raycast Target:射线投射目标,是否能够响应图形射线
- Raycast Padding 射线投射填充
- Maskable 可遮盖的
脚本修改组件
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TextTest : MonoBehaviour
{
public Font testFont;
public Text thistext;
// Start is called before the first frame update
void Start()
{
TextInstance();
}
void TextInstance()
{
//获取当前游戏对象的Text组件
thistext = this.GetComponent<Text>();
//1、 赋值
thistext.text = "你好,世界";
//2、字体
thistext.font = testFont;
// 1.Bold加粗 2. Italic斜体 3. BoldAndItalic 4. Normal
thistext.fontStyle = FontStyle.Normal;
//字体大小
thistext.fontSize = 20;
//行间距
thistext.lineSpacing = 1;
//3、富文本
thistext.supportRichText = true;
//4、对齐方式
TextAnchor anchor = TextAnchor.MiddleCenter;
thistext.alignment = anchor;
//5、溢出方式
thistext.horizontalOverflow = HorizontalWrapMode.Wrap;
thistext.verticalOverflow = VerticalWrapMode.Truncate;
thistext.resizeTextForBestFit = true;
}
}
Image
- Source Image:源图像,Sprite图像资源
- Color:颜色与透明度
- Material:材质
- Raycast Target:射线投射目标;
- Raycast Padding 射线投射填充
- Maskable:可遮盖的
- Image Type:
- Simple默认,在拉伸区域内完全显示一张图片
- Set Native Size:设置原始尺寸
- Sliced切片,九宫格应用,需要图片做过九宫格分割,四角在图片拉伸时不会拉伸变形(设置图片边框,当拉伸宽度时候,只有边框宽度会被拉伸,高度不会被拉伸,同理,高度被拉伸,宽度不会被拉伸,宽度的边框就不会变形)
- Tiled平铺,像铺地板一样填满整个控件
- Filled填充,技能冷却主要依靠这个属性
- Fill Method:切割方式,水平、垂直,90、180、360度圆形
- Fill Origin:切割起始位置
- Fill Amount:切割的量,0~1
- Clockwise:顺时针方向
- Preserve Aspect:保持长宽比
- Simple默认,在拉伸区域内完全显示一张图片
用Filled实现技能冷却效果
实现点击技能进入冷却,冷却结束又可以可以使用技能
- 高亮的技能图片是Skill对象,阴影图片作为子对象Shadow,把控制技能冷却的脚本挂载到Shadow对象上
- 在Skill对象上添加Button组件,实现当点击技能时候,触发事件进入技能冷却
- 代码实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ImageTest : MonoBehaviour
{
private Image thisImage;
public float coolDownTime = 5f;
public float restTime = 5f;
private bool isColding = false;
// Start is called before the first frame update
void Start()
{
//获取当前对象的Image组件
thisImage = GetComponent<Image>();
//开始无冷却,技能高亮状态,也就是阴影图片占比为0
thisImage.fillAmount = 0;
}
// Update is called once per frame
void Update()
{
if (isColding)
{
//Time.deltaTime是每一帧之间的时间间隔,Updata方法是每一帧调用一次
restTime -= Time.deltaTime;
//阴影图片的占比
thisImage.fillAmount = restTime / coolDownTime;
}
//技能冷却为0,恢复初始状态
if(restTime < 0)
{
//图片高亮
thisImage.fillAmount = 0;
//技能冷却参数复原
restTime = coolDownTime;
//点击标志复原
isColding = false;
}
}
public void OnSkillClick()
{
//点击事件触发
isColding = true;
}
}
Rawlmage
- Texture:纹理;区别于Sprite
- UV Rect:UV矩阵,改变UV坐标,可实现一张图片切分,如果这一组图相互切换变成一个动画,例如动物跑动,就能实现动图的效果。
- RawImage核心代码比Image少很多,Raw Image不支持交互,可用于显示任何图片而不仅仅是Sprite,一般用在背景、图标上,支持UV Rect(用来设置只显示图片的某一部分),而Image不支持UV Rect。
- 扩展:Outline/描边组件Shadow阴影组件
- 使用RawImage加Texture实现分镜显示
- X和Y代表图片和RawImage的中心点的偏移量
- W是在水平方向上,RawImage的宽度和图片的宽度的比值,比如W等于1就是图片填满RawImage,如果W是2,图片宽度就会被缩小一半,如果是0.5,图片宽度会被拉大一倍
- 同理,H就是高度上的比值
可以修改每帧的间隔时间
实现渐入动画效果
- W设置为0.1,只显示1/10,也就是显示一个数字,通过改变X的偏移值,实现数字改变的效果
- 代码实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RawImageTest : MonoBehaviour
{
public RawImage thisRawImage;
public float speed = 1f;
public float intervalTime = 1f;
public float timer = 0f;
// Start is called before the first frame update
void Start()
{
thisRawImage = this.gameObject.GetComponent<RawImage>();
//1、渐入动画效果
//thisRawImage.uvRect = new Rect(new Vector2(-1,0),new Vector2(1,1));
//2、动画切换效果
//初始化,W值设置为0.1,比值为1:10,就是图片被拉长10倍,刚好只能显示一个数字
thisRawImage.uvRect = new Rect(new Vector2(0, 0), new Vector2(0.1f, 1));
}
// Update is called once per frame
void Update()
{
//1、渐入动画效果
//if(thisRawImage.uvRect.x <0)
//{
// //每帧X值增加Time.deltaTime,每帧左偏移
// thisRawImage.uvRect = new Rect(new Vector2(thisRawImage.uvRect.x + speed * Time.deltaTime, 0), new Vector2(1, 1));
//}
//else
//{
// //复原
// thisRawImage.uvRect = new Rect(new Vector2(0,0), new Vector2(1,1));
//}
//2、动画切换效果
timer += Time.deltaTime;
if (timer>=intervalTime)
{
//到了数字9复原
if(thisRawImage.uvRect.x > 0.9f)
{
thisRawImage.uvRect = new Rect(new Vector2(-0.1f, 0), new Vector2(thisRawImage.uvRect.width, 1));
}
thisRawImage.uvRect = new Rect(new Vector2(thisRawImage.uvRect.x + 0.1f, 0), new Vector2(thisRawImage.uvRect.width,1));
timer = 0f;
}
}
}
RawImage实现小屏幕效果
-
新建一个相机,作为分镜,创建Sprite子对象,在子对象上创建动画
-
子对象创建动画,添加关键帧,改变y的值实现上下移动动画效果
-
创建一个渲染器纹理Render Texture,关联分镜的相机,可以渲染相机捕捉到的动画
-
把渲染纹理器赋值给RawImage
实现分镜图片上下移动动画效果
Outline描边组件
Shadow阴影效果
Button
-
Interactable:是否可交互
-
Transition: 确定控件以可视方式响应用户操作的方式的属性
-
Navigation: 在EventSystem中,存在一个当前被选中按钮,我们可以通过按下上下左右,使被选中按钮进行更改。
-
Visualize:显示控件之间的导航
-
图片交互方式
-
动画交互方式
点击Button对象,打开Animation
添加关键帧,改变按钮大小动画效果
光标到Button时,就会播放放大缩小的动画 -
Navigation导航,点击按钮之后,可以通过键盘方法键导航到另外一个按钮
水平方向Horizontal导航
点击左边的按钮,然后通过键盘方向键就可以导航到右边按钮
Explicit通过赋值去指定键盘方向键导航到哪个对象
点击事件OnClick,可视化绑定脚本方法
通过脚本代码绑定方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ButtonTest : MonoBehaviour,ISelectHandler
{
void Start()
{
//通过脚本绑定方法
this.gameObject.GetComponent<Button>().onClick.AddListener(ClickButton);
//绑定带有参数的方法
string str = "button have parameter";
//内置是Action委托需要返回值为void
this.gameObject.GetComponent<Button>().onClick.AddListener (() =>ClickButton(str));
}
public void ClickButton()
{
Debug.Log("button test");
}
public void ClickButton(string str)
{
Debug.Log(str);
}
public void OnSelect(BaseEventData eventData)
{
Debug.Log("Button被选中");
}
}
Toggle
- Is On:默认是否选中
- Toggle Transition:切换是是否有过渡效果,Fade表示有,None表示没有
- Graphic:设置开关要起作用的图形对象,不一定非要是默认的对号
- Group:设置分组。把多个Toggle放在同一个物体下,在这个物体上添加Toggle Group,并给Toggle赋值,就可以实现单选。
- On Value Change:当Toggle值改变时所调用的函数。
实现单选
挂载脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ToggleTest : MonoBehaviour {
// Use this for initialization
void Start () {
this.gameObject.GetComponent<Toggle>().onValueChanged.AddListener((bool changeValue)=> OnToggleValueChanged02(changeValue));
}
// Update is called once per frame
void Update () {
}
public void OnToogleValueChanged()
{
Debug.Log("Toggle Value Change");
}
public void OnToggleValueChanged02(bool isOn)
{
Debug.Log(isOn);
}
}
Slider
- Fill Rect:填充矩形,滑块与最小值方向所构成的填充区域所要使用的填充矩形,如果滑动条的作用只是用于改变指定值,那么此选项建议置空,这个相比于Scrollbar所多出来的属性主要用于标识从最小值变化到当前值所经过的变化区域。
- Handle Rect:操作条矩形,当前值处于最小值与最大值之间比例的显示范围,也就是整个滑条的最大可控制范围。
- Direction:方向,滑动条的方向,从左至右,从上至下还是其他的。Left To Right;Right To Left;Bottom To Top;Top To Bottom
- Min Value:滑动条的可变化最小值。
- Max Value:滑动条的可变化最大值。
- Whole Numbers: 变化值为整型,勾选此项,拖动滑动条将按整型数(最小为1)进行改变指定值。
- Value:当前滑动条对应的值。
音量控制
- 用脚本把滑动条滑动的值和Audio Source控制音量的Volume关联起来,实现同步
- 脚本代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SliderTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void SliderValueChanged()
{
float value = this.gameObject.GetComponent<Slider>().value;
Debug.Log(value);
//实现同步
this.gameObject.GetComponent<AudioSource>().volume = value;
}
}
血条控制
- 设置背景图片,根据图片的分辨率设置父对象Slider的大小
- 设置锚框
- 设置Fill
- 把Fill Area和Fill的锚都设置为框
最后,缩放血条到合适大小
Dropdown
- Options下拉选项,选择之后,Label的Text组件文本内容被赋值
- 给选项添加图片Image,先在Item上添加图片Image
- 绑定显示Item Image图片,表示下拉框每一个选项显示的图片去那里找
- 给每一个选项赋值,下拉框的每一个选项都对应有一个图片
- 选择后,显示在第一个框框里,就需要设置绑定的图片
Dropdown脚本使用
- 创建并挂载脚本,拖拽到触发事件中
- 脚本代码
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class TestDrop : MonoBehaviour
{
public Sprite[] optionImages;
void Start()
{
//事件绑定
this.gameObject.GetComponent<Dropdown>().onValueChanged.AddListener((int index) => DropdownItemChanged(index));
CreateDropdownOptions();
}
// Update is called once per frame
void Update()
{
}
//用代码初始化
public void CreateDropdownOptions()
{
var thisDropdown = this.gameObject.GetComponent<Dropdown>();
//清除
thisDropdown.options.Clear();
Dropdown.OptionData op1 = new Dropdown.OptionData();
op1.text = "水瓶座";
op1.image = optionImages[0];
thisDropdown.options.Add(op1);
Dropdown.OptionData op2 = new Dropdown.OptionData();
op2.text = "双鱼座";
op2.image = optionImages[1];
thisDropdown.options.Add(op2);
Dropdown.OptionData op3 = new Dropdown.OptionData();
op3.text = "白羊座";
op3.image = optionImages[2];
thisDropdown.options.Add(op3);
Dropdown.OptionData op4 = new Dropdown.OptionData();
op4.text = "金牛座";
op4.image = optionImages[3];
thisDropdown.options.Add(op4);
}
public void dropdownItemChanaged()
{
int index = this.gameObject.GetComponent<Dropdown>().value;
Debug.Log(index);
}
public void DropdownItemChanged(int index)
{
var text = this.gameObject.GetComponent<Dropdown>().options[index].text;
Debug.Log(text);
}
}
- 赋值
OnSelect事件
- 判断选择的是什么对象
- 代码实现接口ISelectHandler的OnSelect方法,需要导入UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ButtonTest : MonoBehaviour,ISelectHandler
{
public void OnSelect(BaseEventData eventData)
{
Debug.Log("Button被选中");
}
}
InputField
- 当输入框值改变时候,触发值改变事件,然后再点击输入框以外的东西,触发事件On End Edit
- 代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class InputFieldTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void ValueChangedTest()
{
var value = this.gameObject.GetComponent<InputField>().text;
Debug.Log("我是ValueChangedTest方法:"+value);
//获取输入的是哪一个键
foreach(KeyCode item in System.Enum.GetValues(typeof(KeyCode)))
{
if (Input.GetKeyDown(item))
{
//打印出点击的键值
Debug.Log(item.ToString());
}
}
}
public void EndEditTest()
{
var value = this.gameObject.GetComponent<InputField>().text;
Debug.Log("我是EndEditTest方法:"+value);
}
}
- 循环判断输入的键值
RectTransform
-
UGUI对象所特有的组件,区别于Transform
-
Pivot:轴点,UI对象旋转的中心点
-
Anchors:锚,UI对象所特有的,由四个位于UI对象父物体矩形边框范围内的四个点组成(UGUI对象都是矩形边框),用来锚定UI对象。
(Min_x,Min_y) (Min_x,Max y) (Max_x,Min_y);(Max_x,Max_y);- 有三种形态:锚点,锚线,锚框
- 无论父物体的位置尺寸大小改变,UI子物体的Rect Transform四个参数的的值不变。不同情况,Rect Transform四个参数有不同的含义。
-
锚点:四个点重合的情况。无论如何改变父物体的尺寸,UI子物体RectTransform四个参数的的值不变,其含义分别为:
- PosX:锚点到UI子物体左边框的垂直距离
- PosY:锚点到UI子物体下边框的垂直距离
- Width:UI子物体的宽度
- Height:UI子物体的高度
也就表示UI子物体的尺寸大小不变,并且锚点与UI子物体左下角的点的方向距
离不变:进而推断出轴点与锚点的方向距离也保持不变:
- 锚线:两个点重合的情况。改变父物体的尺寸,UI子物体Rect Transform四个参数的
值不变,其含义分别为:- PosX:锚线与UI子物体左边框的垂直距离
- Top::锚线上方端点与UI子物体上边框的垂直距离
- Width:UI子物体的宽度
- Bottom:锚线下方端点与UI子物体下边框的垂直距离
- 垂直方向的锚线
也就表示锚线到UI子物体轴点的垂直距离保持不变,但是UI子物体的高度会随着父物
体的高度变化而变化
-
水平方向的锚线
UI子物体的宽度会随着父物体的宽度变化而变化 -
锚框:四个点分开的情况。改变父物体的尺寸,UI子物体Rect Transform四个参
数的值不变,其含义分别为:- Left:左方锚线与UI子物体左边框的垂直距离
- Top:上方锚线与UI子物体上边框的垂直距离
- Right:右方锚线与UI子物体右边框的垂直距离
- Bottom:下方锚线与UI子物体下边框的垂直距离
父对象长宽改变时候,并不会改变这四个参数的值,所以图片就会被等比例缩放
也就表示UI子物体的尺寸大小包括高度宽度都会随着父物体的尺寸改变而改变
注意:UI父物体与UI子物体的尺寸大小变化会受两者Scale大小比例影响
Raycast Target
实现鼠标点击返回当前位置所有UI
代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class RaycastTest : MonoBehaviour
{
public EventSystem eventSystemTest;
public GraphicRaycaster rayTest;
public List<GameObject> raycastTargetGameobjects;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if(Input.GetMouseButtonDown(0))
{
raycastTargetGameobjects = getGameObjectByRaycast(Input.mousePosition);
}
}
public List<GameObject> getGameObjectByRaycast(Vector2 inputPosition)
{
List<GameObject> resultList = new List<GameObject>();
PointerEventData ped = new PointerEventData(eventSystemTest);
ped.position = inputPosition;
List<RaycastResult> RaycastResultList = new List<RaycastResult>();
rayTest.Raycast(ped, RaycastResultList);
if(RaycastResultList.Count > 0 )
{
foreach(var item in RaycastResultList)
{
resultList.Add(item.gameObject);
}
}
return resultList;
}
}
Canvas–画布
-
画布,创建UI物体时,会自动创建,并且,所有UI物体都是Canvas的子物体。和Canvas一同创建的还有一个EventSystem,其是一个基于Input的事件系统,可以对键盘、触摸、鼠标、自定义输入进行监听处理。
-
绘制元素顺序
画布中的UI元素是以它们在层次结构中出现的顺序绘制的。首先绘制第一个孩子,然后
绘制第二个孩子,依此类推。如果两个UI元素重叠,则后一个元素将出现在前一个元素
的顶部。 -
要更改哪个元素显示在其他元素的顶部,只需拖动层次结构中的元素即可。
Screen Space Overlay
- 屏幕空间-叠加,表示Canvas下的所有的UI控件永远位于屏幕的前面,不管有没有相机,UI元素永远在屏幕最前面,主要是2D效果。在这种模式下,在不同的屏幕分辨率下画布会自动适配屏幕的分辨率大小。
- Pixel Perfect:完美像素,UI元素精确到像素对齐,边缘更清晰
- Sort Order:排列顺序,多个Canvas存在的时候,数值越大,越优先显示
Screen Space -Camera
- 屏幕空间-相机模式,Canvas和摄像机之间有一定的距离,可以在摄像机和Canvas之间播放一些粒子特效,主要是3D效果。
- Pixel Perfect:完美像素,UI元素精确到像素对齐,边缘更清晰
- Render Camera:指定一个相机,用于渲染Canvas
- Plane Distance:Canvas平面与摄像机的距离
- Sorting Layer:Canvas显示层级,存在多个Canvas时,层级越大,显示优先级越高
- Order in Layer:层级顺序,同Sorting Layeri下,Order越大显示优先级越高
World Space
- 世界空间,Canva5就和普通的3D物体一样了,可以控制它的大小,旋转,缩放等,一般用来做血条。
- Event Camera:用于响应事件的相机
- Sorting Layer:Canvas显示层级,存在多个Canvas时,层级越大,显示优先级越高
- Order in Layer:层级顺序,同Sorting Layer下,Orderi越大,显示优先级越高
- Constant Pixel Size:无论屏幕大小如何,都便Ul元素保特相同的像素大小
- Scale Factor:以此比例缩放Canvas中的所有UI元素。
- Scale With Screen Size:根据不同屏幕尺寸自动改变UI大小
- Constant Physical Size:恒定物理尺寸
- World Space:世界空间设置
- 只有UI的元素才继承了Graphic基类,才能响应图形射线。
- Ignore Reversed Graphic:图片翻转后点击无效
- Blocking Objects:可以阻止射线的Object类型
- Blocking Mask:可以阻止射线的Mask类型