/**
*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("點(diǎn)擊了");
});
}
// 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>
/// 限制移動(dòng)距離在屏幕內(nèi)
/// </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);
}
}
需要一個(gè)類似于NGUI的事件監(jiān)聽類
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失活 抬起激活 這樣就實(shí)現(xiàn)了移動(dòng)圖標(biāo)不會(huì)激活Btn事件
需要注意的是要拖拽的物體要添加2D碰撞 這個(gè)腳本只用掛一個(gè).不用每個(gè)物體都掛 根據(jù)2D射線碰撞拖動(dòng)
這樣的話有個(gè)問題 就是你按下才注冊(cè)按下事件 所以第一次按下事件不會(huì)觸發(fā) 第二次才會(huì) 每次點(diǎn)擊到都要重新注冊(cè)
所以更改一下 在btn界面?zhèn)魅雝ransform注冊(cè)
/**
*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("點(diǎn)擊了");
});
}
// Update is called once per frame
void Update()
{
}
/// <summary>
/// 限制移動(dòng)距離在屏幕內(nèi)
/// </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;
}
};
}
}
}
這樣就可以絲滑般流暢 可以根據(jù)canTouch控制是否可以拖動(dòng)

GIF.gif
源碼地址
https://github.com/1004019267/ScorwViewMoveAndDragUI