昨天问题
InputField光标被遮挡问题:背景图片输入层级高于光标的层级,把光标弄成子物体,子物体层级高
自制的滑动框,选项怎么对齐,把Template的Pivot.y改为1
分辨率的区别:16:9和1920x1080
16:9,屏幕像素按比例缩放,文本会变模糊
1920x1080,屏幕像素是固定的
Canvas Group:控制一组UI的某些属性(所有子物体的UI组件的属性)
Alpha:改变所有子物体的透明通道,0不显示,1显示
Interactable:改变所有子物体的交互状态,可交互,不可交互
Blocks Raycasts:改变所有子物体的射线检测,接受射线检测,不接受射线检测
Ignore Parent Group:是否忽略父物体的Canvas Group的影响
登录界面的淡入淡出效果
Panel组件(少用)
作用:背景图或父物体
ScrollView组件(拖动框)
Content:可拖动的物体,改变image的父物体Content的坐标
Horizontal、Vertical:是否可以水平、垂直拖动
Movement Type:移动类型
----Elastic:回弹原位,会自动回到对齐的位置
--------Elasticity回弹系数,值越大回弹越慢
----Unrestricted:自由拖动,无限制,拖到哪就是哪
----Clamped:有限制的,拖动物体的拖动框最多能跟视窗对齐,父物体边缘限制在视窗边缘
Inertia:惯性
----Deceleration Rate:惯性的衰减系数,0相当于没有惯性,1
Scroll Sensitivity:鼠标滚轮的滚动系数
Viewport:视窗,如果未指定,则视窗默认为ScrollRect的范围
Horizontal ScrollBar:水平滚动条
----Visibility:显示方式
--------Permanent:永久显示
--------Auto Hide:自动隐藏
--------Auto Hide And Expand Viewport:自动隐藏并且扩展视窗
Vertical ScrollBar:垂直滚动条
Mask遮罩:图片圆形显示
遮罩依赖于Image图片形状,必须与Image一起使用,否则无效
Show Mask Graphic:是否显示遮罩的图片
Viewport里的遮罩
自制拖动框
综合练习-拖动框
Hrizontal Layout Group:水平自动布局组件(对自己的子物体)
Padding:距离四个边缘的间距,距离四个变量的距离
Spacing:各个元素之间的间距
Child Alignment:子物体的对齐方式
Child Control Size:
----Width:是否强行扩大子物体的宽度,来填补额外的可用空间
----Height:是否强行扩大子物体的高度,来填补额外的可用空间
----勾选后,子物体的宽高会变成不可编辑
Child Force Expand:是否强行扩大物体间的横向间隔,来填补额外的可用空间
Movement Type - Clamped:
需要在Content的长度比Viewport大的情况下才可以拖动
可以使用自动扩容组件,给Content动态添加长度
Content Size Fitter(自动扩容组件)
Horizontal Fit:水平自动扩容
----Unconstralned:不需要自动扩容
----Min Size:最小值
----Preferred Size:最合适的值(常用)
一般情况下,需要和自动布局组件或Text组件一起使用
自动扩容后,宽高变为不可修改
名称显示
代码操作
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class SelectUI : MonoBehaviour { public Text nameText; public string playerName; private Toggle toggle; // Use this for initialization void Start () { toggle = GetComponent<Toggle>(); toggle.onValueChanged.AddListener(OnValueChanged); } // Update is called once per frame void Update () { } void OnValueChanged(bool isOn) { Debug.Log("OnValueChanged"); nameText.text = isOn ? playerName : ""; } }
UGUI事件接口
命名空间:using UnityEngine.EventSystems;
继承了UGUI事件接口的类,挂载物体上,只要子物体或自己本身能接受射线检测,接口就是可以执行的。
接口简介:指针点击接口
IPointerClickHandler:当鼠标指针点击,执行接口里的方法(在图片内点击,在图片内抬起)
IPointerDownHandler:当鼠标指针按下
IPointerUpHandler:当鼠标指针抬起,执行接口里的方法(在图片内点击,在图片内外抬起)
IPointerEnterHandler:当鼠标指针进入
IPointerExitHandler:当鼠标指针离开
右键点击按钮
代码操作
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; public class RightButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler { public Graphic graphic;//改变颜色的图像 public Color normalColor = Color.white; public Color enterColor = Color.white;//当鼠标进入时按钮的颜色 public Color pressColor = Color.white;//当鼠标按下时按钮的颜色 //onClick存储所有的在点击的时候执行的方法 public RightButtonEvent onClick = new RightButtonEvent(); private bool isExit = true;//鼠标是否离开图片区域 private void Awake() { if (graphic == null) { graphic = GetComponent<Graphic>(); } } public void OnPointerEnter(PointerEventData eventData) { //当鼠标进入时改变颜色 graphic.color = enterColor; isExit = false; } public void OnPointerExit(PointerEventData eventData) { graphic.color = normalColor; isExit = true; } public void OnPointerDown(PointerEventData eventData) { //只有按下鼠标右键才有效果 if (eventData.button == PointerEventData.InputButton.Right) { graphic.color = pressColor; } } public void OnPointerUp(PointerEventData eventData) { if (eventData.button == PointerEventData.InputButton.Right) { //判断鼠标是否在图片内部 if (isExit) { graphic.color = normalColor; } else { graphic.color = enterColor; } } } public void OnPointerClick(PointerEventData eventData) { if (eventData.button == PointerEventData.InputButton.Right) { onClick.Invoke(); } } [System.Serializable]//这个类是可序列化的 public class RightButtonEvent : UnityEvent { } }
隐式实现
显示实现,两个接口有同名方法时使用
默认不区分鼠标左键右键和中键,可通过枚举类型,判断鼠标按键
给事件添加方法
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class RightButtonTest : MonoBehaviour { private RightButton rightButton; // Use this for initialization void Start () { rightButton = GetComponent<RightButton>(); rightButton.onClick.AddListener(Click); } // Update is called once per frame void Update () { } public void Click() { Debug.Log("点击了右键按钮"); } }
鼠标点击,跟随移动
PointerEventData类
button:鼠标按键的枚举
position:当前鼠标在屏幕中的位置
pressPosition:按下时鼠标在屏幕中的位置
enterEventCamra:当进入时的事件相机(在overlay 模式下为null)
pressEventCamra:当按下时的事件相机(在overlay 模式下为null)
代码操作
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.UI; public class ClickButton : MonoBehaviour, IPointerClickHandler { public GameObject image; public void OnPointerClick(PointerEventData eventData) { //转换坐标的API //转换出来的是局部坐标,localPosition //第一个参数:想要以哪个坐标系为参考(一般情况下都是父物体坐标系) //第二个参数:屏幕坐标(鼠标所在的屏幕坐标) //第三个参数:相机 //第四个参数:转换成功之后的局部坐标 //返回值 Vector2 outPos; bool isSuccess = RectTransformUtility.ScreenPointToLocalPointInRectangle( image.transform.parent as RectTransform, eventData.position, Camera.main,//eventData.pressEventCamera, out outPos ); if (isSuccess) { image.transform.localPosition = outPos; } } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
Overlay模式 ,代码可以填写null
Camera模式,可以填渲染摄像机
使用锚点坐标来移动的问题
将锚点设置在画布的左下角(0,0),通过用锚点坐标改变图片位置
但当锚点不在中心点时,屏幕分辨率变化,画布变化,锚点也会改变
小地图
添加Render Texture
画布设置
相机设置
标签设置
相机遮罩设置
角色展示
摄像机设置纯色,剔除背景
角色旋转代码逻辑
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; public class LeonaRotate : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler { public GameObject obj; bool isInImage = false; public void OnPointerEnter(PointerEventData eventData) { isInImage = true; } public void OnPointerExit(PointerEventData eventData) { isInImage = false; } // Update is called once per frame void Update() { if (isInImage && Input.GetMouseButton(0)) { float offsetX = Input.GetAxis("Mouse X"); obj.transform.rotation *= Quaternion.Euler(0, -offsetX * 60f, 0); } else { obj.transform.rotation = Quaternion.Slerp(obj.transform.rotation, Quaternion.Euler(0, 180, 0), 0.1f); } } }