您的位置:首页 > 移动开发 > Unity3D

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

2016-09-05 11:30 731 查看
    一般背包系统中,物品是依附在格子里面,即物品为格子的子物体。物品拖拽时主要是将物品拿出,跟随鼠标移动,判断落点位置完成拖拽:如果鼠标释放终点位置下检测到的是空格子,就把物体放在空格子下;如果鼠标释放终点位置下检测到的是其他物品,则交换位置;如果鼠标释放终点位置下检测到的是无效位置,包物体放回原来的位置。
    下面这个脚本是挂在物品预制体上的,可以实现拖拽效果;这些内容也都是参考了前辈们的内容,以自己的拙见进行了优化修改,有不当之处,还望指正,初学者一起相互学习。

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;
}
}

下面是运行动态图:




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity