- 通过panel创建一个窗口,实现拖拽,限制拖拽区域,改变窗口大小
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class DragPanel : MonoBehaviour, IPointerDownHandler, IDragHandler
{
private Vector2 pointerOffset;
private RectTransform canvasRectTransform;
private RectTransform panelRectTransform;
void Awake()
{
Canvas canvas = GetComponentInParent<Canvas>();
if (canvas != null)
{
canvasRectTransform = canvas.transform as RectTransform;
panelRectTransform = transform as RectTransform;
}
}
public void OnPointerDown(PointerEventData data)
{
panelRectTransform.SetAsLastSibling();
RectTransformUtility.ScreenPointToLocalPointInRectangle(panelRectTransform, data.position, data.pressEventCamera, out pointerOffset);
}
public void OnDrag(PointerEventData data)
{
if (panelRectTransform == null)
return;
Vector2 localPointerPosition;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvasRectTransform, data.position, data.pressEventCamera, out localPointerPosition
))
{
panelRectTransform.localPosition = localPointerPosition - pointerOffset;
}
}
}
相关:
eventSystem详解 : http://www.manew.com/blog-56596-2917.html
ScreenPointToLocalPointInRectangle : http://gad.qq.com/article/detail/41551
2,通过在panel组件下增加一个透明image用作darg区域,将脚本DragPanel附加到该组件上,并将
panelRectTransform = transform as RectTransform;改为panelRectTransform = transform.parent as RectTransform;
实现只拖拽部分区域。
3,实现函数ClampToWindow来限制传入OnDrag函数中传入ScreenPointToLocalPointInRectangle的screenpoint的区域,以避免panel被拖拽出屏幕
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class DragPanel : MonoBehaviour, IPointerDownHandler, IDragHandler
{
private Vector2 pointerOffset;
private RectTransform canvasRectTransform;
private RectTransform panelRectTransform;
void Awake()
{
Canvas canvas = GetComponentInParent<Canvas>();
if (canvas != null)
{
canvasRectTransform = canvas.transform as RectTransform;
panelRectTransform = transform.parent as RectTransform;
}
}
public void OnPointerDown(PointerEventData data)
{
panelRectTransform.SetAsLastSibling();
RectTransformUtility.ScreenPointToLocalPointInRectangle(panelRectTransform, data.position, data.pressEventCamera, out pointerOffset);
}
public void OnDrag(PointerEventData data)
{
if (panelRectTransform == null)
return;
Vector2 pointerPostion = ClampToWindow(data);
Vector2 localPointerPosition;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
canvasRectTransform, pointerPostion, data.pressEventCamera, out localPointerPosition
))
{
panelRectTransform.localPosition = localPointerPosition - pointerOffset;
}
}
Vector2 ClampToWindow(PointerEventData data)
{
Vector2 rawPointerPosition = data.position;
Vector3[] canvasCorners = new Vector3[4];
canvasRectTransform.GetWorldCorners(canvasCorners);
float clampedX = Mathf.Clamp(rawPointerPosition.x, canvasCorners[0].x, canvasCorners[2].x);
float clampedY = Mathf.Clamp(rawPointerPosition.y, canvasCorners[0].y, canvasCorners[2].y);
Vector2 newPointerPosition = new Vector2(clampedX, clampedY);
return newPointerPosition;
}
}
4,通过Button来控制panel的开关,注册到Button的OnClick事件上
using UnityEngine;
using System.Collections;
public class TogglePanelButton : MonoBehaviour {
public void TogglePanel (GameObject panel) {
panel.SetActive (!panel.activeSelf);
}
}
5,通过更改panel的sizeDelta来更改窗口的大小
在panel上添加一透明image,附加以下脚本即可,由于这里是通过sizeDelta来更改,所以panel的锚点最好设置成聚在一起的一个点,不然放大缩小都会出现一些问题
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ResizePanel : MonoBehaviour, IPointerDownHandler, IDragHandler {
public Vector2 minSize;
public Vector2 maxSize;
private RectTransform rectTransform;
private Vector2 currentPointerPosition;
private Vector2 previousPointerPosition;
void Awake () {
rectTransform = transform.parent.GetComponent();
}
public void OnPointerDown (PointerEventData data) {
rectTransform.SetAsLastSibling();
RectTransformUtility.ScreenPointToLocalPointInRectangle (rectTransform, data.position, data.pressEventCamera, out previousPointerPosition);
}
public void OnDrag (PointerEventData data) {
if (rectTransform == null)
return;
Vector2 sizeDelta = rectTransform.sizeDelta;
RectTransformUtility.ScreenPointToLocalPointInRectangle (rectTransform, data.position, data.pressEventCamera, out currentPointerPosition);
Vector2 resizeValue = currentPointerPosition - previousPointerPosition;
sizeDelta += new Vector2 (resizeValue.x, -resizeValue.y);
sizeDelta = new Vector2 (
Mathf.Clamp (sizeDelta.x, minSize.x, maxSize.x),
Mathf.Clamp (sizeDelta.y, minSize.y, maxSize.y)
);
rectTransform.sizeDelta = sizeDelta;
previousPointerPosition = currentPointerPosition;
}
}
6,在panel上附加以下脚本使得每次点击该窗口都能让它显示在最上面
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class FocusPanel : MonoBehaviour, IPointerDownHandler {
private RectTransform panel;
void Awake () {
panel = GetComponent ();
}
public void OnPointerDown (PointerEventData data) {
panel.SetAsLastSibling ();
}
}