siki学院中有关UI的
//Andy老师的
01 UGUI整体解决方案-基础篇(Unity 2019.1.0f2)(免费)
02 UGUI整体解决方案-优化篇(Unity 2019.1.0f2)(付费)
03 UGUI整体解决方案-案例篇(Unity 2019.1.0f2)(付费)
下载:Unity Samples: UI
//
//Siki老师的
UI框架 - 基于Unity5.3UGUI
背包系统 装备系统和锻造系统 - 基于Unity5.3UGUI
//望在适配上有所了解
101 RectTransform基础概念
//单位是像素
//失效Image的方框叫Panel(后面的中心与轴心的那个框)
//进行一侧锚点设置后,四个小三角就出现了
//pivot,轴心,是小蓝圈,位置的来源。位置,是轴心相对父物体锚点的位置
//anchors是锚点,小三角。物体的“原点”
详情面板的两种显示模式
中心与轴心
//轴心状态下,轴心可以移动
102 Anchor的简单应用
点击(锚点位置)
//锚点 == 计算位置时的原点(位置=轴心-锚点)
Shift+点击(锚点位置+轴心位置)
//轴心模式下,上面的的“中心与轴心”有说到
Ctrl+Alt+点击(锚点位置+缩放与移动)
影响位置,影响大小
//左右是合的,所以左右只影响位置。因为是对齐左边,所以拉右边没变化
//上下是分的,所以上下会影响大小和位置
//小图是做对齐(Canvas不能缩放?所以加了Bg)。
//调整的是Bg
// 锚点都分开的情况
103 Anchor的适应性设置
//锚点可以手动拖。(这时的概念有点像学网页时的margning和padding)
104 RectTransform两种位置属性的关系
//localPosition 物体的几何中心 为原点,与轴心的相对位置。蓝线交点与小蓝圈
//position物体的 锚点的几何中心 为原点,与轴心的相对位置。红线交点与小蓝圈
105 轴心点参数的应用
//将Bg的轴心设置在左边,Bg下的物体排列就方便计算。(在中心还要减掉宽度的一半)
106 获取UI宽高最安全的方式
[Tooltip("这个public不出来")] RectTransform rectTransform;
public float height;
public float width;
//
[Tooltip("不安全,有时是负数")] public Vector2 sizeData;
// Start is called before the first frame update
void Start()
{
rectTransform = transform.GetComponent<RectTransform>();
height = rectTransform.rect.height;
width = rectTransform.rect.width;
//
sizeData = rectTransform.sizeDelta;
}
//sizeData不安全,受锚点影响
107 蓝图模式和原始编辑模式
蓝图模式
//作用于旋转,缩放
原始编辑模式
//作用于轴心,锚点
108 canvas的三种渲染模式
**
**
顶层
//不能移动旋转
相机
//不能移动旋转
作为一个普通物体
//可以移动旋转
//抗锯齿,100像素抗锯齿为了填补锯齿处有可能变为101像素
109 ui单位和像素的对应关系
//由1、2得到,该图一个像素有12b/100=1.28长。
//以上和3得到,该Canvas中该图的像素是1.28*100=128
//验证以上的说法
110 ConstantPixelSize模式下的UI适配
//注意方法是在Start()开始的。所以运行前,分辨率先调成其他的
(问题) 此时出现了Unity无法重命名的情况
分辨率不同时出现的覆盖问题
//
111 最常用的UI适配方式
先设置Canvas的参考分辨率与(游戏)想要的分辨率一致
//
Match Width Or Height,没有一定的= =情况
Expand,canvas高宽 = = 标准高宽,另一个大于标准
Shrink,canvas高宽 = = 标准高宽,另一个小于标准
112 针对屏幕DPI做适配
DPI ,点数/平方英尺
113 重要!管理UI点击响应的组件
忽略反转图形(保留翻译错的)
代码与效果
挂个改变颜色的脚本
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class NewBehaviourScript113 : MonoBehaviour
,IPointerUpHandler
{
public void ChangeColor()
{
float r = (float)Random.Range(0f, 1f);
float g = (float)Random.Range(0f, 1f);
float b = (float)Random.Range(0f, 1f);
print(r + " " + g + " " + b);
GetComponent<Image>().color = new Color(r,g,b);
}
public void OnPointerUp(PointerEventData eventData)
{
ChangeColor();
}
}
//取消Canvas的GraphicRaycaster
//是正反面的反转
114 GraphicRaycaster参数的应用
115 简单好用!CanvasGroup的使用
透明度
可交互(在子物体挂Selectable时不起开关作用)
射线检测
继承父Canvas
116 渲染层级的基本概念
其实看得好乱,游戏生效的只有摄像机深度,其他都是场景生效
摄像机 z坐标(只影响场景)
z坐标(只影响场景) 深度(影响游戏)
//仅深度也一样
深度(影响游戏)
Canvas 平面距离(不影响) 排序图层(只影响场景) 图层顺序 (只影响场景)
平面距离(只影响场景)
排序图层(只影响场景)
图层顺序 (只影响场景)
117 决定UI渲染层级的四种因素
118 Image基础参数讲解
Color 0f-1f
Color32 0-255
涉及射线检测
119 九宫格切割操作
错误:No SpriteEditor
切图
我看视频是直接拖出来的(像鼠标选择一样),但是不知道怎么弄出来的。
所以红色是从原有的Ctrl+D复制来的。切了原图一半的子图
120 ImageType参数的简单应用
都是平铺,左边是九宫格,右边没有九宫格,两者缩放的区别
121 简单实现技能CD效果
122 UV坐标的概念
贴图映射到模型的坐标体系
123 使用RawImage实现帧动画
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class NewBehaviourScript123 : MonoBehaviour
{
[Tooltip("7*5")] public RawImage rawImage;
[Tooltip("列数")] public float offsetX;
[Tooltip("行数")] public float offsetY;
// Start is called before the first frame update
void Start()
{
rawImage = GetComponent<RawImage>();
offsetX = 1f / 7f;
offsetY = 1f / 5f;
StartCoroutine(FrameAnimation());
}
IEnumerator FrameAnimation()
{
float x = 0f;
float y = 0f;
while (true)
{
y += offsetY;
while (true)
{
x += offsetX;
rawImage.uvRect=new Rect(x, y, rawImage.uvRect.width, rawImage.uvRect.height);
yield return new WaitForSeconds(0.3f);
}
}
}
}
//网上找的图,切得不准
124 UVRect的宽高概念
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class NewBehaviourScript124 : MonoBehaviour
{
[Tooltip("8*4")] public RawImage rawImage;
[Tooltip("列数")] public float countX;
[Tooltip("行数")] public float countY;
float offsetX;
float offsetY;
// Start is called before the first frame update
void Start()
{
rawImage = GetComponent<RawImage>();
offsetX = 1f / countX;
offsetY = 1f / countY;
StartCoroutine(FrameAnimation());
}
IEnumerator FrameAnimation()
{
float x = 0f;
float y = 0f;
while (true)
{
while (y < 1f)
{
y += offsetY;
while (x < 1f)
{
x += offsetX;
rawImage.uvRect = new Rect(x, y, rawImage.uvRect.width, rawImage.uvRect.height);
yield return new WaitForSeconds(0.1f);
}
x = 0f;
}
y = 0f;
}
}
}
//进行循环
进行切割
125 在UI上展示3D模型
之前写过
Unity RPG 黑暗之光 问题记录 74-80 头像
1、将TextureRender赋值给RawImage的Texture
2、将TextureRender赋值给摄像机
3、将摄像机对准好模型
126 Text组件详解
127 Unity中富文本的使用
public Text text;
// Start is called before the first frame update
void Start()
{
text = GetComponent<Text>();
text.supportRichText = true;
text.text = "<b>加粗</b>";
text.text += "<i>斜体</i>";
text.text += "<size=30>字体大小</size>";
text.text += "<color=#eeff11>颜色</color>";
}
128 Unity遮罩及我们为什么要避免使用Mask
Unity中SetPassCall, Batches的区别,它们与Draw call 的关系
看到的与draw call 有关的参数大部分情况下只有SetPassCall 和 Batches两个
//
问题:Mask会增加drawCall
方法:RectMask2D或自己写
129 交互组件基类Selectable
比如Selectable是Button、Toggle等的基类,并且比如:Button/、Toggle等不能同时在一个物体上
130 Button的介绍及使用
事件动态添加
public Button button;
void Start()
{
button.onClick.AddListener( ()=>ChangeColor(Color.red));
}
void ChangeColor(Color color)
{
button.GetComponent<Image>().color = color;
}
131 Toggle的介绍及使用
事件动态添加
GetComponent<Toggle>().onValueChanged.AddListener((value)=> {
print(value); });
132 ToggleGroup的介绍及使用
是否出现都不勾选状态
133 Slider的介绍及使用
GetComponent<Slider>().onValueChanged.AddListener((value) => print(value));
134 加载进度条的实现
public bool isSmooth = false;
// Start is called before the first frame update
void Start()
{
switch ( isSmooth )
{
case true :
{
StartCoroutine(OnValueChange());
} break;
case false :
{
StartCoroutine(OnValueChangeSmooth());
}
break;
default: break;
}
}
/// <summary>生硬点</summary>
IEnumerator OnValueChange()
{
float process = 0f;
while (process<1f)
{
process += 0.1f;
GetComponent<Slider>().value = process;
yield return new WaitForSeconds(0.5f);//每0.5s会执行一遍循环体
}
}
/// <summary>平滑点</summary>
IEnumerator OnValueChangeSmooth()
{
float process = 0f;
while (process < 1f)
{
Slider slider = GetComponent<Slider>();
process += 0.1f;
//类似帧循环,快点
yield return new WaitUntil(() =>
{
float from = slider.value;
float to = process;
float smooth = 0.5f;
slider.value = Mathf.SmoothStep(slider.value, process, smooth);
return process - slider.value < 0.01f;
});
yield return new WaitForSeconds(0.5f);//每0.5s会执行一遍循环体
}
}
135 Scrollbar的介绍及使用
GetComponent<Scrollbar>().onValueChanged.AddListener((value) => {
print(value); });
136 ScrollView的运动模式讲解
137 ScrollView的新特性讲解
138 Dropdown的应用
新建item的Image,一个Title Image,。分别赋值给项图像,目标图像。
给Options添加想要的图像
139 InputField内容类型的讲解
140 InputField自定义输入内容格式
141 InputField其余属性讲解
void Start()
{
InputField inputField = GetComponent<InputField>();
inputField.onValueChanged.AddListener((value) => print("onValueChanged:" + value) ) ;
inputField.onEndEdit.AddListener((value) => print("onEndEdit:" + value) ) ;
}
142 水平布局组件讲解
143 水平及垂直布局组件常见问题
144 网格自动布局组件
初始位置
145 LayoutElement组件的使用
灵活高度
146 LayoutElement常见问题
147 AspectRatioFitter组件的使用
148 ContentSizeFitters的常见用途
//父节点挂
//三个子节点挂
//改变子节点的布局元素的Min宽度。父节点的大小相应改变
//不加内容适配
201 简述事件系统及图形射线和其他射线的区别
202 UGUI实现事件的三种方式
203 EventTrigger实现事件调用的两种方式演示
204 拖拽事件接口部分讲解
视频的,没起作用
int i = 0;
// Start is called before the first frame update
void Start()
{
InitEventTrigger();
}
void InitEventTrigger()
{
EventTrigger eventTrigger = gameObject.AddComponent<EventTrigger>();
eventTrigger.triggers = new List<EventTrigger.Entry>();
//
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerClick;
entry.callback = new EventTrigger.TriggerEvent();
entry.callback.AddListener((data) => OnButtonClick());
}
public void OnButtonClick()
{
i ++;
GetComponent<Image>().color = i%2==0? Color.red:Color.blue;
}
//类似
UGUI的点击事件的学习
总结,EventTrigger的事件列表都为空
205 拖拽事件接口的注意事项及简单应用
public class NewBehaviourScript204 : MonoBehaviour,IInitializePotentialDragHandler, IBeginDragHandler,IDragHandler, IEndDragHandler
{
/// <summary>初始一次</summary>
public void OnInitializePotentialDrag(PointerEventData eventData)
{
print("Init");
}
/// <summary>依赖于Drag</summary>
public void OnBeginDrag(PointerEventData eventData)
{
print("Begin");
}
public void OnDrag(PointerEventData eventData)
{
print("Drag");
RectTransform rect = GetComponent<RectTransform>();
Vector3 pos = new Vector3();
RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, eventData.position, eventData.enterEventCamera,out pos);
rect.position = pos;
}
/// <summary>依赖于Drag</summary>
public void OnEndDrag(PointerEventData eventData)
{
print("End");
}
}
206 IDrop接口的注意事项
/层级
拖拽的要在最上面
//层级带来的Drop覆盖
动态添加Canvas的覆盖和Ray
//添加前
//修改后
代码 多了Drop在这里插入代码片
public class NewBehaviourScript204 : MonoBehaviour,
IInitializePotentialDragHandler,
IBeginDragHandler,IDragHandler,
IDropHandler,
IEndDragHandler
{
/// <summary>初始一次</summary>
public void OnInitializePotentialDrag(PointerEventData eventData)
{
print("Init"+gameObject.name);
}
/// <summary>依赖于Drag</summary>
public void OnBeginDrag(PointerEventData eventData)
{
print("Begin" + gameObject.name);
}
public void OnDrag(PointerEventData eventData)
{
print("Drag" + gameObject.name);
RectTransform rect = GetComponent<RectTransform>();
Vector3 pos = new Vector3();
RectTransformUtility.ScreenPointToWorldPointInRectangle(rect, eventData.position, eventData.enterEventCamera,out pos);
rect.position = pos;
}
/// <summary>依赖于Drag</summary>
public void OnDrop(PointerEventData eventData)
{
print("Drop" + gameObject.name);
}
/// <summary>依赖于Drag</summary>
public void OnEndDrag(PointerEventData eventData)
{
print("End" + gameObject.name);
}
207 点击事件接口的讲解 Pointer
public class NewBehaviourScript207 : MonoBehaviour,
IPointerEnterHandler,
IPointerExitHandler,
IPointerDownHandler,
IPointerUpHandler,
IPointerClickHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
print("Enter");
}
public void OnPointerExit(PointerEventData eventData)
{
print("Exit");
}
public void OnPointerDown(PointerEventData eventData)
{
print("Down");
}
public void OnPointerUp(PointerEventData eventData)
{
print("Up");
}
public void OnPointerClick(PointerEventData eventData)
{
print("Click");
}
208 点击事件的UGUI祖传Bug
父
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript208 : MonoBehaviour,
IPointerDownHandler,
IPointerUpHandler,
IPointerClickHandler
{
public void OnPointerDown(PointerEventData eventData)
{
print("Down" + transform.name);
}
public void OnPointerUp(PointerEventData eventData)
{
print("Up" + transform.name);
}
public void OnPointerClick(PointerEventData eventData)
{
print("Click" + transform.name);
}
}
子
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript208_1 : MonoBehaviour,
IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
print("Click" + transform.name);
}
}
效果
点击父物体正常,点击子物体,执行父物体的Down,Click(虽然子物体没有实现Down,Click。实现了就不会)
209 选择事件部分接口
需要Selectable组件
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript209 : MonoBehaviour,
ISelectHandler,
IUpdateSelectedHandler,
IDeselectHandler
{
public void OnSelect(BaseEventData eventData)
{
print("Select"+transform.name);
}
public void OnUpdateSelected(BaseEventData eventData)
{
print("UpdateSelect" + transform.name);
}
public void OnDeselect(BaseEventData eventData)
{
print("Deselect" + transform.name);
}
}
210 系统按键接口
Selectable组件
对应Unity的键盘输入模块的键
代码与效果
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript210 : MonoBehaviour,
ISelectHandler,
IUpdateSelectedHandler,
IDeselectHandler,
IScrollHandler,
IMoveHandler,
ISubmitHandler,
ICancelHandler
{
public void OnSelect(BaseEventData eventData)
{
print("Select" + transform.name);
}
public void OnUpdateSelected(BaseEventData eventData)
{
print("UpdateSelect" + transform.name);
}
public void OnDeselect(BaseEventData eventData)
{
print("Deselect" + transform.name);
}
public void OnScroll(PointerEventData eventData)
{
print("Scroll(滑轮)" + transform.name);
}
public void OnMove(AxisEventData eventData)
{
print("Move(WSAD)" + transform.name);
}
public void OnSubmit(BaseEventData eventData)
{
print("Submit(Enter Space)" + transform.name);
}
public void OnCancel(BaseEventData eventData)
{
print("Cancel(Esc)"+transform.name);
}
}
211 参数中的clickTime的坑
clickTime记录的是游戏开始就进行的时间点(点击)
ClickTime上:Down<Up=Click
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript211 : MonoBehaviour,
IPointerDownHandler,
IPointerUpHandler,
IPointerClickHandler
{
public void OnPointerDown(PointerEventData eventData)
{
print("Down" + transform.name + eventData.clickTime);
}
public void OnPointerUp(PointerEventData eventData)
{
print("Up" + transform.name + eventData.clickTime);
}
public void OnPointerClick(PointerEventData eventData)
{
print("Click" + transform.name + eventData.clickTime);
}
}
212 拖动的另外一种实现方式
实现拖拽,说在设备上可能有不同步的时候
using UnityEngine;
using UnityEngine.EventSystems;
public class NewBehaviourScript212 : MonoBehaviour,
IDragHandler
{
public void OnDrag(PointerEventData eventData)
{
transform.GetComponent<RectTransform>().anchoredPosition += eventData.delta;
}
}