有些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;
}
}