参考:https://ask.csdn.net/questions/7971448
根据自己的需求修改为如下代码
使用过程中,出现拖动ui位置错误的情况,修改为使用 localPosition
但是吸附到指定位置却需要用的position
public class DragAndDrop : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private RectTransform dragTransform;
private Vector2 initPosition;
private Vector2 startPosition;
[Header("正确区域")]
public RectTransform targetArea;
[Header("初始区域")]
public RectTransform originalArea;
[Header("错误区域")]
public RectTransform[] targetOtherArea;
private bool result; //拖动结果
private bool valid; //拖动有效
public bool Result { get => result; private set => result = value; }
public bool Valid { get => valid; private set => valid = value; }
public void Awake()
{
dragTransform = GetComponent<RectTransform>();
//初始位置
initPosition = dragTransform.localPosition;
}
/// <summary>
/// 重置位置
/// </summary>
public void ResetPos()
{
dragTransform.localPosition = initPosition;
result = false;
valid = false;
}
public void OnBeginDrag(PointerEventData eventData)
{
//开始拖动的位置
startPosition = dragTransform.localPosition;
//设置UI最后渲染
dragTransform.SetAsLastSibling();
}
public void OnDrag(PointerEventData eventData)
{
dragTransform.localPosition = GetLocalPosition(eventData.position);
}
public void OnEndDrag(PointerEventData eventData)
{
result = RectTransformUtility.RectangleContainsScreenPoint(targetArea, eventData.position);
#if UNITY_EDITOR
Debug.Log($"拖动结果: {result}");
#endif
if (result)
{
//吸附到目标位置
dragTransform.position = targetArea.position;
valid = true;
return;
}
else
{
foreach (var item in targetOtherArea)
{
if (RectTransformUtility.RectangleContainsScreenPoint(item, eventData.position))
{
//吸附到目标位置
dragTransform.position = item.position;
valid = true;
return;
}
}
//原始位置,拖动无效
if (RectTransformUtility.RectangleContainsScreenPoint(originalArea, eventData.position))
{
//吸附到目标位置
dragTransform.position = originalArea.position;
valid = false;
return;
}
}
//其它情况还原为开始拖动的位置
valid = false;
dragTransform.localPosition = startPosition;
}
private Vector2 GetLocalPosition(Vector2 screenPosition)
{
Vector2 localPosition = Vector2.zero;
RectTransformUtility.ScreenPointToLocalPointInRectangle(dragTransform.parent as RectTransform, screenPosition, null, out localPosition);
return localPosition;
}
}
Demo
using MyTool.Tools;
using UnityEngine;
using UnityEngine.UI;
public class Demo : MonoBehaviour
{
public DragAndDrop dragAndDrop;
public Button okBtn;
// Start is called before the first frame update
void Start()
{
okBtn.onClick.AddListener(OnClickOkBtn);
}
private void Update()
{
okBtn.interactable = dragAndDrop.Valid;
}
void OnClickOkBtn()
{
if (dragAndDrop.Result)
{
Debug.Log("恭喜你答对了!");
}
else
{
Debug.Log("很遗憾,没有答对!");
}
}
}
ui搭建
效果