
Unity 基礎 之 IDragHanlder 多種方法簡單實作 UGUI 元素随着滑鼠移動,拖動的效果
目錄
Unity 基礎 之 IDragHanlder 多種方法簡單實作 UGUI 元素随着滑鼠移動,拖動的效果
一、簡單介紹
二、實作原理
三、注意實作
四、效果預覽
五、實作步驟
六、多種方法實作拖拽 UI
方法一:RectTransformUtility.ScreenPointToWorldPointInRectangle
方法二 :RectTransformUtility.ScreenPointToWorldPointInRectangle 并帶位移 offset
方法三:RectTransformUtility.ScreenPointToLocalPointInRectangle 并帶位移 Offset
方法四:Camera.WorldToScreenPoint 和 Camera.WorldToScreenPoint 并帶位移 Offset
一、簡單介紹
Unity中的一些基礎知識點。
本節介紹,使用 IDraHandler ,簡單的就實作 UGUI 元素,随着滑鼠的移動而移動的效果。
二、實作原理
1、IBeginDragHandler, IDragHandler, IEndDragHandler 三個接口,進行實作拖拽的功能
2、RectTransformUtility.ScreenPointToWorldPointInRectangle 或者 RectTransformUtility.ScreenPointToLocalPointInRectangle
進行坐标轉化,實作拖拽
3、必要的再結合 Camera.WorldToScreenPoint 和 Camera.ScreenToWorldPoint 一起實作拖拽移動效果
三、注意實作
1、根據 Canvas 的 Render Mode 不同的拖拽方法,移動的效果可能會略有不同,擇需使用即可
四、效果預覽
五、實作步驟
1、打開 Unity,建立一個空工程
2、在場景中搭建UI,布局如下
3、建立腳本,編輯方法移動 UI,把腳本對應指派
六、多種方法實作拖拽 UI
方法一:RectTransformUtility.ScreenPointToWorldPointInRectangle
1、代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragHandlerUGUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform rectTransform;
// Start is called before the first frame update
void Start()
{
rectTransform = GetComponent<RectTransform>();
}
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("開始拖拽");
}
public void OnDrag(PointerEventData eventData)
{
Vector3 pos;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, eventData.position, eventData.enterEventCamera, out pos);
rectTransform.position = pos;
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("結束拖拽");
}
}
2、效果如下
方法二 :RectTransformUtility.ScreenPointToWorldPointInRectangle 并帶位移 offset
1、代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragHandlerUGUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform rectTransform;
private Vector3 pos; //控件初始位置
private Vector3 mousePos; //滑鼠初始位置
private void Start()
{
rectTransform = GetComponent<RectTransform>();
}
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("開始拖拽");
pos = this.GetComponent<RectTransform>().position;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out mousePos);
}
public void OnDrag(PointerEventData eventData)
{
Vector3 newVec;
RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out newVec);
Vector3 offset = new Vector3(newVec.x - mousePos.x, newVec.y - mousePos.y, 0);
rectTransform.position = pos + offset;
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("結束拖拽");
}
}
2、效果如下
方法三:RectTransformUtility.ScreenPointToLocalPointInRectangle 并帶位移 Offset
1、代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragHandlerUGUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private Vector3 pos; //控件初始位置
private Vector2 mousePos; //滑鼠初始位置
private RectTransform canvasRec; //控件所在畫布
private void Start()
{
canvasRec = this.GetComponentInParent<Canvas>().transform as RectTransform;
}
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("開始拖拽");
//控件所在畫布空間的初始位置
pos = this.GetComponent<RectTransform>().anchoredPosition;
//将螢幕空間滑鼠位置eventData.position轉換為滑鼠在畫布空間的滑鼠位置
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRec, eventData.position, eventData.pressEventCamera, out mousePos);
}
public void OnDrag(PointerEventData eventData)
{
Vector2 newVec;
RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRec, eventData.position, eventData.pressEventCamera, out newVec);
//滑鼠移動在畫布空間的位置增量
Vector3 offset = new Vector3(newVec.x - mousePos.x, newVec.y - mousePos.y, 0);
//原始位置增加位置增量即為現在位置
(this.transform as RectTransform).anchoredPosition = pos + offset;
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("結束拖拽");
}
}
2、效果如下
方法四:Camera.WorldToScreenPoint 和 Camera.WorldToScreenPoint 并帶位移 Offset
1、代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragHandlerUGUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Vector3 uiScreenPosition;
Vector3 mouseScreenPosition;
Vector3 mScreenPosition;
private Vector3 offset;
Camera mCamera;
// Start is called before the first frame update
void Start()
{
mCamera = Camera.main;
}
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("開始拖拽");
//轉換對象到目前螢幕位置
uiScreenPosition = mCamera.WorldToScreenPoint(transform.position);
mouseScreenPosition = mCamera.WorldToScreenPoint(eventData.position);
//滑鼠螢幕坐标
mScreenPosition = new Vector3(mouseScreenPosition.x, mouseScreenPosition.y, uiScreenPosition.z);
//獲得滑鼠和對象之間的偏移量,拖拽時相機應該保持不動
offset = transform.position - mCamera.ScreenToWorldPoint(mScreenPosition);
}
public void OnDrag(PointerEventData eventData)
{
mouseScreenPosition = mCamera.WorldToScreenPoint(eventData.position);
//滑鼠螢幕上新位置
mScreenPosition = new Vector3(mouseScreenPosition.x, mouseScreenPosition.y, uiScreenPosition.z);
// 對象新坐标
transform.position = offset + mCamera.ScreenToWorldPoint(mScreenPosition);
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("結束拖拽");
}
}
2、效果如下