unity背包系统中物体拖拽效果实现(初学者)

    一般背包系统中,物品是依附在格子里面,即物品为格子的子物体。物品拖拽时主要是将物品拿出,跟随鼠标移动,判断落点位置完成拖拽:如果鼠标释放终点位置下检测到的是空格子,就把物体放在空格子下;如果鼠标释放终点位置下检测到的是其他物品,则交换位置;如果鼠标释放终点位置下检测到的是无效位置,包物体放回原来的位置。

    下面这个脚本是挂在物品预制体上的,可以实现拖拽效果;这些内容也都是参考了前辈们的内容,以自己的拙见进行了优化修改,有不当之处,还望指正,初学者一起相互学习。

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class PetItemMove : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, ICanvasRaycastFilter
{
    private static Transform canvasTra;
    private Transform nowParent;//物品是格子的子物体,nowParent记录的是当前物品属于哪个格子(格子1)
    private bool isRaycastLocationValid = true;//默认射线不能穿透物品
    private Camera canvasCamera = null;
    void Start()
    {

    }

    public void OnBeginDrag(PointerEventData eventData)//开始拖拽
    {
        if (canvasTra == null) canvasTra = GameObject.Find("Canvas").transform;
        canvasCamera = canvasTra.GetComponentInChildren<Camera>();
        //Debug.Log(Input.mousePosition);
        nowParent = transform.parent;//nowparent为被拖拽物体的原始父物体
        transform.SetParent(canvasTra);//将当前拖拽的物品放在canvas下
        isRaycastLocationValid = false;//ui穿透:置为可以穿透  【拖拽物体移动的时候鼠标下是有物体一直跟随遮挡的,如果不穿透就获取不到放置位置(OnEndDrag中判断是空格子,物体,还是无效位置)】

    }

    public void OnDrag(PointerEventData eventData)//拖拽过程中
    {
       transform.position = canvasCamera.ScreenToWorldPoint(Input.mousePosition);//鼠标左键按住拖拽的时候,物体跟着鼠标移动
        //transform.position = Input.mousePosition;//鼠标左键按住拖拽物体的时候不显示物体

    }

    public void OnEndDrag(PointerEventData eventData)//
    {
        GameObject go = eventData.pointerCurrentRaycast.gameObject;//获取到鼠标终点位置下 可能的物体

        
        if (go != null)
        {
            Debug.Log(go.name);
            if (go.tag.Equals("Grid"))//鼠标终点位置下是: 空格子(所以直接放进去)
            {
                SetParentAndPosition(transform, go.transform);
            }
            else if (go.tag.Equals("PlayerPetItem"))//鼠标终点位置下是: 也是一个物体(所以需要交换位置)
            {//交换位置要注意可能需要把物品下的子物体的Raycast Target关掉(不去掉可能无法交换)
                SetParentAndPosition(transform, go.transform.parent);//将被拖拽的物体1放到鼠标终点下的格子2里面
                SetParentAndPosition(go.transform, nowParent);//将鼠标终点格子2里面物体2 放到 原来物体1的格子1里面
                if (transform.position == go.transform.position)
                {
                    Debug.Log("error");
                }
            }
            else//鼠标终点是:无效位置(所以物体放回原来的位置)
            {
                SetParentAndPosition(transform, nowParent);
            }
        }
        else//
        {
            SetParentAndPosition(transform, nowParent);
        }
        isRaycastLocationValid = true;//ui事件穿透:置为不能穿透
    }

    private void SetParentAndPosition(Transform child, Transform parent)//将child放到parent下作为子物体
    {
        child.SetParent(parent);
        child.position = parent.position;
    }

    public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)//UI事件穿透:如置为false即可以穿透,被图片覆盖的按钮可以被点击到
    {
        return isRaycastLocationValid;
    }
}

下面是运行动态图:




猜你喜欢

转载自blog.csdn.net/u012761191/article/details/52438785