依旧是拖拽UI的功能。
这次是将UI拖入指定的位置。
主要实现的实际释放拖拽后的操作。
要实现的功能如下,以流程图形式展现:
——汉字写的不美观,就不拿出来献丑了。索性用英语写
该脚本挂载在技能Icon上面。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class SkillItemIcon : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
/// <summary>
/// 用于拖拽的预设体,创建被拖拽的副本
/// </summary>
public GameObject dragPrefab;
/// <summary>
/// 是否为副本,如果是原本,则创建副本,如果是副本,则直接拖拽,而不创建副本
/// </summary>
public bool isCopyRight = true;
/// <summary>
/// 是否曾经放入过快捷栏。如果放入过,则为true,此时将该物体拖出来则会放回原位而不是销毁。
/// </summary>
public bool didPutCutGrid = false;
/// <summary>
/// 当前正在被拖拽的对象
/// </summary>
private GameObject draggingItem;
/// <summary>
/// 物体的目前父物体
/// </summary>
private Transform nowParent;
/// <summary>
/// 图标的RectTransform组件
/// </summary>
private RectTransform rectTransform;
/// <summary>
/// Canvas组件,用于确定拖拽的缩放因子
/// </summary>
private Canvas canvas;
private void Start()
{
rectTransform = GetComponent<RectTransform>(); // 获取图标的RectTransform组件
canvas = GetComponentInParent<Canvas>(); // 获取父级Canvas组件
//originalPosition = rectTransform.anchoredPosition; // 记录图标的初始位置
}
public void OnBeginDrag(PointerEventData eventData)
{
if (isCopyRight)
{
draggingItem = Instantiate(dragPrefab, transform.parent);
draggingItem.GetComponent<SkillItemIcon>().isCopyRight = false;
}
else
{
draggingItem = gameObject;
}
if (draggingItem.transform.GetComponent<Image>().raycastTarget)
{
//让被拖拽的物体屏蔽射线检测,这样就能获得鼠标悬停下的UI对象
draggingItem.transform.GetComponent<Image>().raycastTarget = false;
}
nowParent = draggingItem.transform.parent; //nowparent为被拖拽物体的当前父物体
draggingItem.transform.SetParent(canvas.transform);//将当前拖拽的物体放在canvas下
//isRaycastPass = false;//设置ui可穿透
}
public void OnDrag(PointerEventData eventData)
{
draggingItem.transform.GetComponent<RectTransform>().anchoredPosition += eventData.delta / canvas.scaleFactor; // 根据鼠标移动更新图标位置
}
public void OnEndDrag(PointerEventData eventData)
{
GameObject dropTarget = eventData.pointerCurrentRaycast.gameObject;
if (dropTarget != null)
{
if (dropTarget.CompareTag(S_Tags.shortCutGrid)) // 当拖放到了一个空的格子里面
{
draggingItem.transform.SetParent(dropTarget.transform);
//表示该物品曾经放入格子中过
draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid = true;
}
else if (dropTarget.CompareTag(S_Tags.shortCut)) // 当拖放到了一个有物品的格子里面
{
if (draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid)
{
//目标格子
Transform tmpTrans = dropTarget.transform.parent;
dropTarget.transform.SetParent(nowParent);
draggingItem.transform.SetParent(tmpTrans);
dropTarget.transform.localPosition = Vector3.zero;
}
else
{
Destroy(draggingItem);
return;
}
}
else
{
if (draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid)
{
draggingItem.transform.SetParent(nowParent);
}
else
{
Destroy(draggingItem);
return;
}
}
}
else
{
if (draggingItem.transform.GetComponent<SkillItemIcon>().didPutCutGrid)
{
draggingItem.transform.SetParent(nowParent);
}
else
{
Destroy(draggingItem);
return;
}
}
draggingItem.transform.GetComponent<Image>().raycastTarget = true;
//isRaycastPass = true;//设置ui不可穿透
ResetLocalPosition();
}
/// <summary>
/// 被拖拽物体返回原位置
/// </summary>
private void ResetLocalPosition()
{
draggingItem.transform.localPosition = Vector3.zero;
draggingItem.transform.SetAsFirstSibling();
}
}
为了赶进度,目前先用这种方法实现想要的功能。日后将对该部分代码进行重构,消除冗余代码,找到更简便的逻辑思路。