NGUI 提供了非常豐富、強大的組件庫,其中就包括 UIDragObject 組件,這個組件用來實現面板的拖動效果,但是這個組件有一個不好的地方就是被拖動的對象可以被拖到屏幕之外,不過我們可以很容易的借助 NGUI 的代碼類庫進行來修復這個問題。
我們先看一下 NGUI 自帶的 UIDragObject 組件如何實現面板的拖動。
第一步先布局好界面,如圖:
然后我們給可拖動的對象(Background)添加 UIDragObject 組件,如圖:
接着設置 UIDragObject 的 Target 屬性為 Background,如圖:
到這兒我們先運行一下,看看效果,這時候我們是無法拖動面板的,究其原因很簡單,我們沒有給 Background 添加 Collider,如圖:
下面,我們給 Background 添加 Box Collider,如圖:
設置好 Box Collider 的 Size 信息,如圖:
這時候我們再次運行,就可以看到,我們可以拖動面板了,但是我們也可以發現,我們可以把面板拖到屏幕之外,如圖:
下面我們就去修復這個問題,我們先去掉 UIDragObject 組件,如圖:
接着我們新建立一個 C# 類,取名 UDragManager.cs,如圖:
然后我們編寫 UDragManager.cs 類,具體代碼如下:
using UnityEngine; using System.Collections; public class UDragManager : MonoBehaviour { public Transform target; private Vector3 offset; private Bounds bounds; void OnPress(bool pressed) { if (target == null) return; if (pressed) { bounds = NGUIMath.CalculateRelativeWidgetBounds(target.transform); Vector3 position = UICamera.currentCamera.WorldToScreenPoint(target.position); offset = new Vector3(Input.mousePosition.x - (position.x - bounds.size.x / 2), Input.mousePosition.y - (position.y - bounds.size.y / 2),0f); } } void OnDrag(Vector2 delta) { Vector3 currentPoint = new Vector3 (Input.mousePosition.x - offset.x, Input.mousePosition.y - offset.y, 0f); //如果坐標小於0 if (currentPoint.x < 0) { currentPoint.x = 0; } //如果坐標大於屏幕寬 if (currentPoint.x + bounds.size.x > Screen.width) { currentPoint.x = Screen.width - bounds.size.x; } //如果坐標小於0 if (currentPoint.y < 0) { currentPoint.y = 0; } //如果坐標大於屏幕高 if (currentPoint.y + bounds.size.y > Screen.height) { currentPoint.y = Screen.height - bounds.size.y; } currentPoint.x += bounds.size.x / 2; currentPoint.y += bounds.size.y / 2; target.position = UICamera.currentCamera.ScreenToWorldPoint (currentPoint); } }
接下來,我們再給 Background 添加 UDragManager 類,如圖:
並且設置好 UDragManager 的 Target 屬性為 Background,如圖:
這時候我們再次運行,看看最終的效果,這時候我們已經把面板限制在屏幕中間了,其實我們還可以把面板限制在屏幕中的一塊區域中,只需要修改區域判定的代碼就可以了,最終效果圖如下: