有些UI元素(主要是非可交互控件)没有事件处理能力,可以为其添加,有三种方法:
1. 实现相应得事件接口:参考UnityEventSystems命名空间
2. 添加EventTrigger组件,并指定事件处理器
3. 程序动态添加
示例1:拖拽界面元素
首先新建一个Unity工程,创建一个简单的UI窗体界面,如下图:
为Header添加一个脚本DragPlane,用来控制拖动Window,代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragPanel : MonoBehaviour, IDragHandler, IPointerDownHandler
{
/// <summary>
/// 记录window在Background中的位置
/// </summary>
private Vector2 windowInBackgroundPos;
/// <summary>
/// 记录鼠标按下时的坐标位置
/// </summary>
private Vector2 downPos;
/// <summary>
/// 记录鼠标拖动后的坐标位置(相对于Background的原点位置)
/// </summary>
private Vector2 curPos;
/// <summary>
/// 保存拖拽区的父节点
/// </summary>
private RectTransform window;
// Unity会在用户点击到标题条时给我们发送此消息(也即:Unity会“回调”此函数)
// 并且将鼠标按下的位置通过eventData发送给我们
public void OnPointerDown(PointerEventData eventData)
{
// 获取到当前节点的父节点
window = this.transform.parent as RectTransform;
// 记录下当前标题条在父节点Window中的本地坐标(鼠标点击的位置)
windowInBackgroundPos = window.localPosition;
// 调用ScreenPointToLocalPointInRectangle()静态函数,获取鼠标点下时在Background坐标系中的位置
// 参数为1.目标坐标系 2.鼠标位置 3.鼠标按下时对应的摄像机 4.传出鼠标按下时的位置
RectTransformUtility.ScreenPointToLocalPointInRectangle(
window.parent as RectTransform
, eventData.position
, eventData.pressEventCamera
, out downPos);
}
// 将鼠标拖动后的位置通过eventData发送给我们
public void OnDrag(PointerEventData eventData)
{
// 传出一个拖动后的鼠标位置
RectTransformUtility.ScreenPointToLocalPointInRectangle(
window.parent as RectTransform
, eventData.position
, eventData.pressEventCamera
, out curPos
);
Debug.Log(curPos);
// 拖动后的偏移值
Vector2 offset = curPos - downPos;
// 拖动后的窗口位置等于旧位置加上偏移值
window.localPosition = windowInBackgroundPos + offset;
}
}
这样就实现了点住标题可拖动窗口的效果。
示例2:拉伸界面元素
为Resize Zone添加一个ResizePanel脚本,代码如下:using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ResizePanel : MonoBehaviour, IDragHandler, IPointerDownHandler
{
/// <summary>
/// 窗口原始大小
/// </summary>
private Vector2 origSize;
/// <summary>
/// 记录鼠标按下时的坐标位置
/// </summary>
private Vector2 downPos;
/// <summary>
/// 记录鼠标拖动后的坐标位置(相对于Background的原点位置)
/// </summary>
private Vector2 curPos;
/// <summary>
/// 保存拖拽区的父节点
/// </summary>
private RectTransform window;
public void OnPointerDown(PointerEventData eventData)
{
window = this.transform.parent as RectTransform;
// 保存窗口原始大小
origSize = window.sizeDelta;
// 传出鼠标点下时的位置
RectTransformUtility.ScreenPointToLocalPointInRectangle(
window.parent as RectTransform
, eventData.position
, eventData.pressEventCamera
, out downPos
);
}
public void OnDrag(PointerEventData eventData)
{
RectTransformUtility.ScreenPointToLocalPointInRectangle(
window.parent as RectTransform
, eventData.position
, eventData.pressEventCamera
, out curPos
);
Vector2 offset = curPos - downPos;
// 因为UGUI坐标系原点坐标系在屏幕左下角
// 而我们是以左上角为原点,所以要进行一下Y轴的翻转
offset.y *= -1;
window.sizeDelta = origSize + offset;
}
}