/**
*Copyright(C) 2019 by #COMPANY#
*All rights reserved.
*FileName: #SCRIPTFULLNAME#
*Author: #AUTHOR#
*Version: #VERSION#
*UnityVersion:#UNITYVERSION#
*Date: #DATE#
*Description:
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Drag : MonoBehaviour
{
private void Start()
{
transform.GetComponent<Button>().onClick.AddListener(() =>
{
Debug.Log("点击了");
});
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector2 mousePos2D = Input.mousePosition;
RaycastHit2D hit = Physics2D.Raycast(mousePos2D, Vector2.zero);
if (hit.transform != null)
{
var listener = EventTriggerListener.Get(hit.transform);
Vector3 offset = Vector3.zero;
Button btn = hit.transform.GetComponent<Button>();
listener.onBeginDrag += (go) =>
{
if (btn!=null)
{
btn.enabled = false;
}
offset = hit.transform.position - Input.mousePosition;
};
listener.onDrag += (go) =>
{
hit.transform.position = Input.mousePosition + offset;
DragRangeLimit(hit.transform);
};
listener.onEndDrag += (go) =>
{
if (btn != null)
{
btn.enabled = true;
}
};
}
}
}
/// <summary>
/// 限制移动距离在屏幕内
/// </summary>
/// <param name="tra"></param>
public void DragRangeLimit(Transform tra)
{
var pos = tra.GetComponent<RectTransform>();
float x = Mathf.Clamp(pos.position.x, pos.rect.width * 0.5f, Screen.width - (pos.rect.width * 0.5f));
float y = Mathf.Clamp(pos.position.y, pos.rect.height * 0.5f, Screen.height - (pos.rect.height * 0.5f));
pos.position = new Vector2(x, y);
}
}
需要一个类似于NGUI的事件监听类
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
using System;
public class EventTriggerListener : EventTrigger
{
public delegate void VoidDelegate(GameObject go);
public VoidDelegate onClick;
public VoidDelegate onDown;
public VoidDelegate onEnter;
public VoidDelegate onExit;
public VoidDelegate onUp;
public VoidDelegate onSelect;
public VoidDelegate onUpdateSelect;
public VoidDelegate onDrag;
public VoidDelegate onBeginDrag;
public VoidDelegate onEndDrag;
public static EventTriggerListener Get(GameObject go)
{
EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
if (listener == null)
listener = go.AddComponent<EventTriggerListener>();
return listener;
}
public static EventTriggerListener Get(Transform go)
{
EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
if (listener == null)
listener = go.gameObject.AddComponent<EventTriggerListener>();
return listener;
}
public override void OnPointerClick(PointerEventData eventData)
{
if (onClick != null) onClick(gameObject);
}
public override void OnPointerDown(PointerEventData eventData)
{
if (onDown != null) onDown(gameObject);
}
public override void OnPointerEnter(PointerEventData eventData)
{
if (onEnter != null) onEnter(gameObject);
}
public override void OnPointerExit(PointerEventData eventData)
{
if (onExit != null) onExit(gameObject);
}
public override void OnPointerUp(PointerEventData eventData)
{
if (onUp != null) onUp(gameObject);
}
public override void OnSelect(BaseEventData eventData)
{
if (onSelect != null) onSelect(gameObject);
}
public override void OnUpdateSelected(BaseEventData eventData)
{
if (onUpdateSelect != null) onUpdateSelect(gameObject);
}
public override void OnDrag(PointerEventData eventData)
{
if (onDrag != null) onDrag(gameObject);
}
public override void OnBeginDrag(PointerEventData eventData)
{
if (onBeginDrag != null) onBeginDrag(gameObject);
}
public override void OnEndDrag(PointerEventData eventData)
{
if (onEndDrag != null) onEndDrag(gameObject);
}
}
按下btn失活 抬起激活 这样就实现了移动图标不会激活Btn事件
需要注意的是要拖拽的物体要添加2D碰撞 这个脚本只用挂一个.不用每个物体都挂 根据2D射线碰撞拖动
这样的话有个问题 就是你按下才注册按下事件 所以第一次按下事件不会触发 第二次才会 每次点击到都要重新注册
所以更改一下 在btn界面传入transform注册
/**
*Copyright(C) 2019 by #COMPANY#
*All rights reserved.
*FileName: #SCRIPTFULLNAME#
*Author: #AUTHOR#
*Version: #VERSION#
*UnityVersion:#UNITYVERSION#
*Date: #DATE#
*Description:
*History:
*/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Drag : MonoBehaviour
{
bool canTouch=true;
private void Start()
{
RegisterDrag(transform);
transform.GetComponent<Button>().onClick.AddListener(() =>
{
Debug.Log("点击了");
});
}
// Update is called once per frame
void Update()
{
}
/// <summary>
/// 限制移动距离在屏幕内
/// </summary>
/// <param name="tra"></param>
public void DragRangeLimit(Transform tra)
{
var pos = tra.GetComponent<RectTransform>();
float x = Mathf.Clamp(pos.position.x, pos.rect.width * 0.5f, Screen.width - (pos.rect.width * 0.5f));
float y = Mathf.Clamp(pos.position.y, pos.rect.height * 0.5f, Screen.height - (pos.rect.height * 0.5f));
pos.position = new Vector2(x, y);
}
public void RegisterDrag(Transform tra)
{
if (tra.transform != null)
{
var listener = EventTriggerListener.Get(tra.transform);
Vector3 offset = Vector3.zero;
Button btn = tra.transform.GetComponent<Button>();
listener.onBeginDrag += (go) =>
{
if (!canTouch)
return;
offset = tra.transform.position - Input.mousePosition;
if (btn != null)
{
btn.enabled = false;
}
};
listener.onDrag += (go) =>
{
if (!canTouch)
return;
tra.transform.position = Input.mousePosition + offset;
DragRangeLimit(tra.transform);
};
listener.onEndDrag += (go) =>
{
if (!canTouch)
return;
if (btn != null)
{
btn.enabled = true;
}
};
}
}
}
这样就可以丝滑般流畅 可以根据canTouch控制是否可以拖动
源码地址
https://github.com/1004019267/ScorwViewMoveAndDragUI