Unity使用碰撞开发类拖拽拼图逻辑

Unity使用碰撞开发类拖拽拼图逻辑

前言

在进行之前的项目时候,有一个需求就是做一个拖拽Image组件做一个类似于拼图游戏的逻辑。由于我之前开发过一个拼图的游戏,本来想利用判断位置开发这个功能,后来我突发奇想,可不可以通过碰撞实现这个拖拽的功能。花了几天时间,我实现了这个功能,不说了,先直接上效果图:
效果图1:
效果图
效果图2:
在这里插入图片描述
效果图3:
在这里插入图片描述

开发步骤

1.创建RankColliderManager.cs脚本,使用bool值记录碰撞状态,核心代码如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Function;

    public class RankColliderManager : MonoBehaviour
    {
        #region 参数
        /// <summary>
        /// 存储拖拽类
        /// </summary>
        public bool[] isHaveCard;
        #endregion


        #region 私有方法
        /// <summary>
        /// 碰撞检测
        /// </summary>
        /// <param name="other"></param>
        void OnTriggerEnter2D(Collider2D other)
        {
       
                if (!isHaveCard[0])
                {
                    if (other.gameObject.name == "frameToImage")
                    {
                        isHaveCard[0] = true;
                    }
                }
                if (!isHaveCard[1])
                {
                    if (other.gameObject.name == "frameToImage0")
                    {
                        isHaveCard[1] = true;
                    }
                }
                if (!isHaveCard[2])
                {
                    if (other.gameObject.name == "frameToImage1")
                    {
                        isHaveCard[2] = true;
                    }
                }
            if (!isHaveCard[3])
            {
                if (other.gameObject.name == "frameToImage2")
                {
                    isHaveCard[3] = true;
                }
            }
            if (!isHaveCard[4])
            {
                if (other.gameObject.name == "frameToImage3")
                {
                    isHaveCard[4] = true;
                }
            }
            if (!isHaveCard[5])
            {
                if (other.gameObject.name == "frameToImage4")
                {
                    isHaveCard[5] = true;
                }
            }
            if (!isHaveCard[6])
            {
                if (other.gameObject.name == "frameToImage5")
                {
                    isHaveCard[6] = true;
                }
            }
        }

        /// <summary>
        /// 离开检测
        /// </summary>
        void OnTriggerExit2D(Collider2D other)
        {
                if (isHaveCard[0])
                {
                    if (other.gameObject.name == "frameToImage")
                    {
                        isHaveCard[0] = false;
                    }
                }
                if (isHaveCard[1])
                {
                    if (other.gameObject.name == "frameToImage0")
                    {
                        isHaveCard[1] = false;
                    }
                }
                if (isHaveCard[2])
                {
                    if (other.gameObject.name == "frameToImage1")
                    {
                        isHaveCard[2] = false;
                    }
                }
            if (isHaveCard[3])
            {
                if (other.gameObject.name == "frameToImage2")
                {
                    isHaveCard[3] = false;
                }
            }
            if (isHaveCard[4])
            {
                if (other.gameObject.name == "frameToImage3")
                {
                    isHaveCard[4] = false;
                }
            }
            if (isHaveCard[5])
            {
                if (other.gameObject.name == "frameToImage4")
                {
                    isHaveCard[5] = false;
                }
            }
            if (isHaveCard[6])
            {
                if (other.gameObject.name == "frameToImage5")
                {
                    isHaveCard[6] = false;
                }
            }
        }
        #endregion
}

2.将此脚本挂载到拖拽区域物体上,添加bool数组值,添加BoxCollider2D组件,设置如图所示:
在这里插入图片描述
3.创建UIDragThis.cs脚本,它的功能主要是实现拖拽已经碰撞触发移动到位置效果等,核心代码如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using Function;
using PlaneManager;

namespace RankManager
{
    public class UIDragThis : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler
    {
        #region 参数
        [Header("是否精确拖拽")]
        internal bool m_isPrecision;
        //存储图片中心点与鼠标点的偏移量
        private Vector3 m_offset;
        //存储当前拖拽图片的RectTransform组件
        private RectTransform m_rt;
        //是否可以拖动
        internal bool canMove = true;
        //自身起始位置
        public Vector3 thisPosition;
        //自身的id
        public int thisID = 0;
        //拖动组件父物体
        public Transform content;
        //碰撞物体数组
        public RankColliderManager[] rankColliderManager;
        #endregion
        #region 常规方法
        void Start()
        {
            //初始化
            m_rt = gameObject.GetComponent<RectTransform>();
}
        #endregion

        #region 公共方法
        public void OnBeginDrag(PointerEventData eventData)
        {
            //this.transform.parent = otherThis;
            this.transform.SetParent(otherThis);
            if (canMove)
            {
                //如果精确拖拽则进行计算偏移量操作
                if (m_isPrecision)
                {
                    //存储点击时的鼠标坐标
                    Vector3 tWorldPos;
                    //UI屏幕坐标转换为世界坐标
                    RectTransformUtility.ScreenPointToWorldPointInRectangle(m_rt, eventData.position, eventData.pressEventCamera, out tWorldPos);
                    //计算偏移量
                    m_offset = transform.position - tWorldPos;
                    
                }
                //否则,默认偏移量为0
                else
                {
                    m_offset = Vector3.zero;
                }
                SetDraggedPosition(eventData);
            }
        }

        /// <summary>
        /// 拖拽过程中触发
        /// </summary>
        /// <param name="eventData"></param>
        public void OnDrag(PointerEventData eventData)
        {
            if (canMove)
            {
                
                SetDraggedPosition(eventData);
            }
        }

        /// <summary>
        /// 结束拖拽触发
        /// </summary>
        /// <param name="eventData"></param>
        public void OnEndDrag(PointerEventData eventData)
        {
            if (canMove)
            {
                SetDraggedPosition(eventData);
                ChangePosition();
            }
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 设置图片位置方法
        /// </summary>
        /// <param name="eventData"></param>
        private void SetDraggedPosition(PointerEventData eventData)
        {
            //存储当前鼠标所在的位置
            Vector3 globalMousePos;
            //UI屏幕坐标转换为世界坐标
            if (RectTransformUtility.ScreenPointToWorldPointInRectangle(m_rt,eventData.position,eventData.pressEventCamera,out globalMousePos))
            {
                m_rt.position = m_offset + globalMousePos;
            }
        }

        /// <summary>
        /// 判断改变自身位置
        /// </summary>
        void ChangePosition()
        {
            if (thisID == 0)
            {
                if (rankColliderManager[0].isHaveCard[0] && !rankColliderManager[0].isHaveCard[1] &&
                    !rankColliderManager[0].isHaveCard[2] && !rankColliderManager[0].isHaveCard[3] &&
                    !rankColliderManager[0].isHaveCard[4] && !rankColliderManager[0].isHaveCard[5] &&
                    !rankColliderManager[0].isHaveCard[5])
                {
                    m_rt.localPosition = new Vector3(0f, 220.0f, 0f);
                }
                else if (rankColliderManager[1].isHaveCard[0] && !rankColliderManager[1].isHaveCard[1] &&
                    !rankColliderManager[1].isHaveCard[2] && !rankColliderManager[1].isHaveCard[3] &&
                    !rankColliderManager[1].isHaveCard[4] && !rankColliderManager[1].isHaveCard[5] &&
                    !rankColliderManager[1].isHaveCard[5])
                {
                    m_rt.localPosition = new Vector3(0f, 150.0f, 0f);
                }
                else if (rankColliderManager[2].isHaveCard[0] && !rankColliderManager[2].isHaveCard[1] &&
                    !rankColliderManager[2].isHaveCard[2] && !rankColliderManager[2].isHaveCard[3] &&
                    !rankColliderManager[2].isHaveCard[4] && !rankColliderManager[2].isHaveCard[5] &&
                    !rankColliderManager[2].isHaveCard[5])
                {          
                    m_rt.localPosition = new Vector3(0f, 80.0f, 0f);
                }
                else
                {
                    ToRecoverPosition();
                }

            }
            if (thisID == 1)
            {
                if (!rankColliderManager[0].isHaveCard[0] && rankColliderManager[0].isHaveCard[1] &&
                    !rankColliderManager[0].isHaveCard[2] && !rankColliderManager[0].isHaveCard[3] &&
                    !rankColliderManager[0].isHaveCard[4] && !rankColliderManager[0].isHaveCard[5] &&
                    !rankColliderManager[0].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 220.0f, 0f);
                }
                else if (!rankColliderManager[1].isHaveCard[0] && rankColliderManager[1].isHaveCard[1] &&
                    !rankColliderManager[1].isHaveCard[2] && !rankColliderManager[1].isHaveCard[3] &&
                    !rankColliderManager[1].isHaveCard[4] && !rankColliderManager[1].isHaveCard[5] &&
                    !rankColliderManager[1].isHaveCard[6])
                {                 
                    m_rt.localPosition = new Vector3(0f, 150.0f, 0f);
                }
                else if (!rankColliderManager[2].isHaveCard[0] && rankColliderManager[2].isHaveCard[1] &&
                    !rankColliderManager[2].isHaveCard[2] && !rankColliderManager[2].isHaveCard[3] &&
                    !rankColliderManager[2].isHaveCard[4] && !rankColliderManager[2].isHaveCard[5] &&
                    !rankColliderManager[2].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 80.0f, 0f);
                }
                else
                {
                    ToRecoverPosition();
                }
            }
            if (thisID == 2)
            {
                if (!rankColliderManager[0].isHaveCard[0] && !rankColliderManager[0].isHaveCard[1] &&
                    rankColliderManager[0].isHaveCard[2] && !rankColliderManager[0].isHaveCard[3] &&
                    !rankColliderManager[0].isHaveCard[4] && !rankColliderManager[0].isHaveCard[5]&&
                    !rankColliderManager[0].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 220.0f, 0f);      
                }
                else if (!rankColliderManager[1].isHaveCard[0] && !rankColliderManager[1].isHaveCard[1] &&
                    rankColliderManager[1].isHaveCard[2] && !rankColliderManager[1].isHaveCard[3] &&
                    !rankColliderManager[1].isHaveCard[4] && !rankColliderManager[1].isHaveCard[5] &&
                    !rankColliderManager[1].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 150.0f, 0f);
                }
                else if (!rankColliderManager[2].isHaveCard[0] && !rankColliderManager[2].isHaveCard[1] &&
                    rankColliderManager[2].isHaveCard[2] && !rankColliderManager[2].isHaveCard[3] &&
                    !rankColliderManager[2].isHaveCard[4] && !rankColliderManager[2].isHaveCard[5] &&
                    !rankColliderManager[2].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 80.0f, 0f);
                }
                else
                {         
                    ToRecoverPosition();
                }
            }
            if (thisID == 3)
            {
                if (!rankColliderManager[0].isHaveCard[0] && !rankColliderManager[0].isHaveCard[1] &&
                    !rankColliderManager[0].isHaveCard[2] && rankColliderManager[0].isHaveCard[3]&&
                    !rankColliderManager[0].isHaveCard[4] && !rankColliderManager[0].isHaveCard[5] &&
                    !rankColliderManager[0].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 220.0f, 0f);
                }
                else if (!rankColliderManager[1].isHaveCard[0] && !rankColliderManager[1].isHaveCard[1] &&
                    !rankColliderManager[1].isHaveCard[2] && rankColliderManager[1].isHaveCard[3] &&
                    !rankColliderManager[1].isHaveCard[4] && !rankColliderManager[1].isHaveCard[5] &&
                    !rankColliderManager[1].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 150.0f, 0f);
                }
                else if (!rankColliderManager[2].isHaveCard[0] && !rankColliderManager[2].isHaveCard[1] &&
                    !rankColliderManager[2].isHaveCard[2] && rankColliderManager[2].isHaveCard[3] &&
                    !rankColliderManager[2].isHaveCard[4] && !rankColliderManager[2].isHaveCard[5] &&
                    !rankColliderManager[2].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 80.0f, 0f);
                }
                else
                {
                    ToRecoverPosition();
                }
            }
            if (thisID == 4)
            {
                if (!rankColliderManager[0].isHaveCard[0] && !rankColliderManager[0].isHaveCard[1] &&
                    !rankColliderManager[0].isHaveCard[2] && !rankColliderManager[0].isHaveCard[3] &&
                    rankColliderManager[0].isHaveCard[4] && !rankColliderManager[0].isHaveCard[5] &&
                    !rankColliderManager[0].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 220.0f, 0f);
                }
                else if (!rankColliderManager[1].isHaveCard[0] && !rankColliderManager[1].isHaveCard[1] &&
                    !rankColliderManager[1].isHaveCard[2] && !rankColliderManager[1].isHaveCard[3] &&
                    rankColliderManager[1].isHaveCard[4] && !rankColliderManager[1].isHaveCard[5] &&
                    !rankColliderManager[1].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 150.0f, 0f);
                }
                else if (!rankColliderManager[2].isHaveCard[0] && !rankColliderManager[2].isHaveCard[1] &&
                    !rankColliderManager[2].isHaveCard[2] && !rankColliderManager[2].isHaveCard[3] &&
                    rankColliderManager[2].isHaveCard[4] && !rankColliderManager[2].isHaveCard[5] &&
                    !rankColliderManager[2].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 80.0f, 0f);
                }
                else
                {
                    ToRecoverPosition();
                }
            }
            if (thisID == 5)
            {
                if (!rankColliderManager[0].isHaveCard[0] && !rankColliderManager[0].isHaveCard[1] &&
                    !rankColliderManager[0].isHaveCard[2] && !rankColliderManager[0].isHaveCard[3] &&
                    !rankColliderManager[0].isHaveCard[4] && rankColliderManager[0].isHaveCard[5] &&
                    !rankColliderManager[0].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 220.0f, 0f);
                }
                else if (!rankColliderManager[1].isHaveCard[0] && !rankColliderManager[1].isHaveCard[1] &&
                    !rankColliderManager[1].isHaveCard[2] && !rankColliderManager[1].isHaveCard[3] &&
                    !rankColliderManager[1].isHaveCard[4] && rankColliderManager[1].isHaveCard[5] &&
                    !rankColliderManager[1].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 150.0f, 0f);
                }
                else if (!rankColliderManager[2].isHaveCard[0] && !rankColliderManager[2].isHaveCard[1] &&
                    !rankColliderManager[2].isHaveCard[2] && !rankColliderManager[2].isHaveCard[3] &&
                    !rankColliderManager[2].isHaveCard[4] && rankColliderManager[2].isHaveCard[5] &&
                    !rankColliderManager[2].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 80.0f, 0f);
                }
                else
                {
                    ToRecoverPosition();
                }
            }
            if (thisID == 6)
            {
                if (!rankColliderManager[0].isHaveCard[0] && !rankColliderManager[0].isHaveCard[1] &&
                    !rankColliderManager[0].isHaveCard[2] && !rankColliderManager[0].isHaveCard[3] &&
                    !rankColliderManager[0].isHaveCard[4] && !rankColliderManager[0].isHaveCard[5] &&
                    rankColliderManager[0].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 220.0f, 0f);
                }
                else if (!rankColliderManager[1].isHaveCard[0] && !rankColliderManager[1].isHaveCard[1] &&
                           !rankColliderManager[1].isHaveCard[2] && !rankColliderManager[1].isHaveCard[3] &&
                           !rankColliderManager[1].isHaveCard[4] && !rankColliderManager[1].isHaveCard[5] &&
                           rankColliderManager[1].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 150.0f, 0f);
                }
                else if (!rankColliderManager[2].isHaveCard[0] && !rankColliderManager[2].isHaveCard[1] &&
                    !rankColliderManager[2].isHaveCard[2] && !rankColliderManager[2].isHaveCard[3] &&
                    !rankColliderManager[2].isHaveCard[4] && !rankColliderManager[0].isHaveCard[5] &&
                    rankColliderManager[2].isHaveCard[6])
                {
                    m_rt.localPosition = new Vector3(0f, 80.0f, 0f);
                }
                else
                {
                    ToRecoverPosition();
                }
            }
        /// <summary>
        /// 恢复原始位置
        /// </summary>
        void ToRecoverPosition()
        {
            m_rt.localPosition = thisPosition;
            canMove = true;
        }

        #endregion
    }
}

4.将此脚本挂载到拖拽物体组件上,设置如下图所示,切记加上Rigidbody2D组件,其他拖拽物体组件也是相同设置:
在这里插入图片描述
5.这样就基本实现了拖拽功能,若需完善,还需要自己在代码丰富,我就不在这啰嗦了。
在这里插入图片描述

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波波斯维奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值