C#實現(xiàn)對UI元素拖拽的實現(xiàn)示例
本篇文章來分享一下對UI元素的拖拽實現(xiàn)。
實現(xiàn)思路
1)按下記錄偏移
鼠標(biāo)按下時,記錄“UI元素錨點” 與“鼠標(biāo)點擊點”的位置差(offset)
2)拖動更新位置
鼠標(biāo)移動時,用“鼠標(biāo)實時位置+偏移量” 更新UI位置,保證UI元素始終跟隨鼠標(biāo)的“抓取點”移動。
為什么要使用offset?
使用offset是為了讓拖拽操作更自然(避免鼠標(biāo)點擊物體時,物體瞬間跳到鼠標(biāo)位置)。
若不使用offset,直接把物體位置設(shè)為鼠標(biāo)位置(rectTransform.position = mousePos):當(dāng)點擊物體非中心點(比如左上角)時,物體會瞬間 “瞬移” 到鼠標(biāo)指針正下方,拖拽手感非常生硬。因為鼠標(biāo)點擊的位置(mousePos)和物體錨點位置(rectTransform.position)通常不在同一位置,直接賦值會導(dǎo)致物體跳位。
計算邏輯
rectTransform.position:物體的錨點位置(默認是物體中心點);
mousePos:鼠標(biāo)點擊時,在世界空間中的指針位置;
offset:兩者的差值 = 物體錨點位置 - 鼠標(biāo)點擊位置。
假設(shè)物體錨點在屏幕上的位置是 (100, 200)(rectTransform.position);點擊的是物體左上角,此時鼠標(biāo)位置是 (80, 220)(mousePos);則offset = (100,200) - (80,220) = (20, -20)。此時offset代表:“鼠標(biāo)點擊點”相對于“物體錨點”的偏移量(即錨點在鼠標(biāo)點擊點的右側(cè)20、下方20位置)。
注意offset只需在OnPointerDown(鼠標(biāo)按下時)計算一次,之后拖拽過程中保持不變。因為它只需要記錄按下瞬間的偏移關(guān)系,拖動時復(fù)用即可。如果在OnDrag中重復(fù)計算,反而會導(dǎo)致物體抖動。
簡而言之,offset就是記住抓住物體的位置,讓拖拽時物體跟著抓點走,而不是跳來跳去。
代碼實現(xiàn)
using UnityEngine;
using UnityEngine.EventSystems;
public class Drag : MonoBehaviour, IDragHandler, IPointerDownHandler
{
private RectTransform rectTransform;
private Vector3 offset;
private void Awake()
{
rectTransform = gameObject.GetComponent<RectTransform>();
}
public void OnDrag(PointerEventData eventData)
{
if (eventData.pointerPressRaycast.gameObject == gameObject)
{
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out Vector3 mousePos))
{
rectTransform.position = mousePos + offset;
}
}
}
public void OnPointerDown(PointerEventData eventData)
{
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out Vector3 mousePos);
offset = rectTransform.position - mousePos;
}
}效果

Unity常用UI交互接口
接口名稱 | 核心方法 | 觸發(fā)時機 | 使用場景 |
IPointerDownHandler | OnPointerDown(PointerEventData eventData) | 鼠標(biāo)/觸摸按下到UI元素時(觸發(fā)一次) | 拖拽起始記錄、長按檢測起點、按鈕按下反饋 |
IPointerUpHandler | OnPointerUp(PointerEventData eventData) | 鼠標(biāo)/觸摸在UI元素上抬起時(移出元素后抬起不觸發(fā)) | 拖拽結(jié)束判定、按鈕抬起反饋 |
IPointerClickHandler | OnPointerClick(PointerEventData eventData) | 按下 + 抬起都在同一UI元素上(完整點擊,觸發(fā)一次) | 普通按鈕點擊、UI元素選中 |
IPointerEnterHandler | OnPointerEnter(PointerEventData eventData) | 鼠標(biāo)/觸摸移入UI元素時(觸發(fā)一次) | 懸停提示顯示、按鈕高亮 |
IPointerExitHandler | OnPointerExit(PointerEventData eventData) | 鼠標(biāo)/觸摸移出UI元素時(觸發(fā)一次) | 懸停提示關(guān)閉、按鈕高亮取消 |
IDragHandler | OnDrag(PointerEventData eventData) | 拖拽過程中每幀觸發(fā)(需先按下UI元素) | UI拖拽移動、滑動條拖動、背包物品拖拽 |
IBeginDragHandler | OnBeginDrag(PointerEventData eventData) | 拖拽開始時(按下后首次移動,觸發(fā)一次) | 記錄拖拽初始位置、生成拖拽虛影 |
IEndDragHandler | OnEndDrag(PointerEventData eventData) | 拖拽結(jié)束時(抬起鼠標(biāo)/觸摸,觸發(fā)一次) | 判定拖拽落點、恢復(fù)原UI狀態(tài) |
IScrollHandler | OnScroll(PointerEventData eventData) | 鼠標(biāo)滾輪滾動或觸摸滑動時(每幀觸發(fā)) | 自定義滾動視圖UI縮放、滾動文本框 |
ISelectHandler | OnSelect(BaseEventData eventData) | UI元素被選中時(如鍵Tab切換) | 輸入框選中高亮、菜單選項選中反饋 |
IDeselectHandler | OnDeselect(BaseEventData eventData) | UI元素失去選中時(如切換到其他元素) | 輸入框失去焦點保存內(nèi)容、取消菜單選中狀態(tài) |
ISubmitHandler | OnSubmit(BaseEventData eventData) | 選中UI元素后提交(如按 Enter 鍵) | 菜單確認、表單提交、按鈕激活 |
ICancelHandler | OnCancel(BaseEventData eventData) | 觸發(fā)取消操作時(如按Esc鍵) | 關(guān)閉彈窗、取消輸入、退出當(dāng)前界面 |
到此這篇關(guān)于C#實現(xiàn)對UI元素拖拽的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)C# UI元素拖拽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實現(xiàn)根據(jù)指定容器和控件名字獲得控件的方法
這篇文章主要介紹了C#實現(xiàn)根據(jù)指定容器和控件名字獲得控件的方法,其中包括了遍歷與遞歸的應(yīng)用,需要的朋友可以參考下2014-08-08
C# 文件上傳下載(Excel導(dǎo)入,多線程下載)功能的實現(xiàn)代碼
這篇文章主要介紹了C# 文件上傳下載(Excel導(dǎo)入,多線程下載)功能的實現(xiàn)代碼,需要的朋友可以參考下2017-08-08
.NET操作NPOI實現(xiàn)Excel的導(dǎo)入導(dǎo)出
NPOI是指構(gòu)建在POI 3.x版本之上的一個程序,NPOI可以在沒有安裝Office的情況下對Word或Excel文檔進行讀寫操作,下面小編為大家介紹了如何操作NPOI實現(xiàn)Excel的導(dǎo)入導(dǎo)出,需要的可以參考一下2023-09-09
DevExpress之ChartControl創(chuàng)建Drill-Down樣式的Title實例
這篇文章主要介紹了DevExpress之ChartControl創(chuàng)建Drill-Down樣式的Title實現(xiàn)方法,以實例形式講述了創(chuàng)建Drill-Down樣式的Title原理與實現(xiàn)過程,需要的朋友可以參考下2014-10-10
C#實現(xiàn)tostring轉(zhuǎn)換成16進制的方法
本文介紹了在C#中將整數(shù)、字節(jié)數(shù)組、字符串轉(zhuǎn)換為十六進制字符串,以及將十六進制字符串轉(zhuǎn)換回整數(shù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-02-02
c#基礎(chǔ)知識---委托,匿名函數(shù),lambda
這篇文章主要介紹了c# 委托,匿名函數(shù),lambda的相關(guān)知識,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06

