unity——UI拖拽实现拼图

摘要:
使用System.Collections;tempParent=GameObject.Find(“画布”).transform;outnewPosition);transform.position=新位置;this.transform.localPosition=矢量3.zero;

拿一张图片剪切好备用

在Canvas下新建panel作为父物体

在下面建一个Image名为——Cell

在Cell下新建image,改Tag为Cell

unity——UI拖拽实现拼图第1张

unity——UI拖拽实现拼图第2张

在这个image上挂脚本:

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

public class DragOnPic : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{


    //记录下自己的父物体.
    Transform myParent;

    //Panel,使拖拽是显示在最上方.
    Transform tempParent;

    CanvasGroup cg;
    RectTransform rt;

    //记录鼠标位置.
    Vector3 newPosition;

    void Awake()
    {
        //添加CanvasGroup组件用于在拖拽是忽略自己,从而检测到被交换的图片.
        cg = this.gameObject.AddComponent<CanvasGroup>();

        rt = this.GetComponent<RectTransform>();

        tempParent = GameObject.Find("Canvas").transform;
    }




    /// <summary>
    /// Raises the begin drag event.
    /// </summary>
    public void OnBeginDrag(PointerEventData eventData)
    {
        //拖拽开始时记下自己的父物体.
        myParent = transform.parent;

        //拖拽开始时禁用检测.
        cg.blocksRaycasts = false;
        
        this.transform.SetParent(tempParent);
    }

    /// <summary>
    /// Raises the drag event.
    /// </summary>
    void IDragHandler.OnDrag(PointerEventData eventData)
    {
        //推拽是图片跟随鼠标移动.
        RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, Input.mousePosition, eventData.enterEventCamera, out newPosition);
        transform.position = newPosition;
    }

    /// <summary>
    /// Raises the end drag event.
    /// </summary>
    public void OnEndDrag(PointerEventData eventData)
    {
        //获取鼠标下面的物体.
        GameObject target = eventData.pointerEnter;

        //如果能检测到物体.
        if (target)
        {
            //如果检测到图片,则交换父物体并重置位置.
            GameManager.SetParent(this.transform, target.transform, myParent);
        }
        else
        {
            this.transform.SetParent(myParent);
            this.transform.localPosition = Vector3.zero;
        }

        //拖拽结束时启用检测.
        cg.blocksRaycasts = true;

       
        
        //检测是否完成拼图.
        if (GameManager.CheckWin())
        {
            Debug.Log("Win!!!");

        }

        if (!GameManager.CheckWin())
        {
            Debug.Log("没拼好");

        }



    }

    

}

新建个脚本GameManager类,随机生成图片位置和拖拽时交换父物体和位置,不需要挂,

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

public class GameManager
{

    /// <summary>
    /// Randoms the array.
    /// </summary>
    static public void RandomArray(Sprite[] sprites)
    {
        for (int i = 0; i < sprites.Length; i++)
        {
            //随机抽取数字中的一个位置,并将这张图片与第i张图片交换.
            int index = Random.Range(i, sprites.Length);
            Sprite temp = sprites[i];
            sprites[i] = sprites[index];
            sprites[index] = temp;
        }
    }

    /// <summary>
    /// Sets the parent.
    /// </summary>
    static public void SetParent(Transform mine, Transform target, Transform oldParent)
    {
        //如果检测到图片,则交换父物体并重置位置.
        switch (target.tag)
        {
            case "Cell":
                mine.SetParent(target.parent);
                target.SetParent(oldParent);
                mine.localPosition = Vector3.zero;
                target.localPosition = Vector3.zero;
                break;
            default:
                mine.SetParent(oldParent);
                mine.localPosition = Vector3.zero;
                break;
        }
    }

    /// <summary>
    /// Checks is win.
    /// </summary>
    static public bool CheckWin()
    {
        for (int i = 0; i < ImageCreater._instance.transform.childCount; i++)
        {
            if (ImageCreater._instance.transform.GetChild(i).name != ImageCreater._instance.transform.GetChild(i).transform.GetChild(0).name)
            {
                return false;
            }
        }
        return true;
    }
}

在panel上添加组件:Grid Layput Group 挂上脚本:

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

public class ImageCreater : MonoBehaviour
{
    //单例模式
    public static ImageCreater _instance;

    //存储裁剪好图片的数组.
    public Sprite[] sprites;

    //格子的预设体.
    public GameObject cellPrefab;

    void Start()
    {
        _instance = this;
        CreateImages();
    }

    private void CreateImages()
    {
        //将图片数组随机排列.
        GameManager.RandomArray(sprites);

        //生产图片.
        for (int i = 0; i < sprites.Length; i++)
        {
            //通过预设体生成图片.
            GameObject cell = (GameObject)Instantiate(cellPrefab);

            //设置cell的名字方便检测是否完成拼图.
            cell.name = i.ToString();

            //获取cell的子物体.
            Transform image = cell.transform.GetChild(0);

            //设置显示的图片.
            image.GetComponent<Image>().sprite = sprites[i];

            //设置子物体的名称,方便检测是否完成拼图.
            int tempIndex = sprites[i].name.LastIndexOf('_');
            image.name = sprites[i].name.Substring(tempIndex + 1);

            //将Cell设置为Panel的子物体.
            cell.transform.SetParent(this.transform);

            //初始化大小.
            cell.transform.localScale = Vector3.one;
        }
    }

}

运行即可生成图片,并达到拖拽,换位置信息的功能:

unity——UI拖拽实现拼图第3张

免责声明:文章转载自《unity——UI拖拽实现拼图》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇对博客园(cnblogs )的评价Asp.Net WebAPI Get提交、Post提交处理下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C++ opencv高速样例学习——读图显示

1.关键函数 1. 读入图片 imread(图片或位置,显示格式)默觉得:IMREAD_COLOR 显示格式:  IMREAD_UNCHANGED =-1    // 8bit, color or not    IMREAD_GRAYSCALE    = 0    // 8bit, gray    IMREAD_COLOR           = 1  ...

关于阿里ICON矢量图(SVG)上传问题.

注意点: 1. 存储为svg格式(建议使用存储为svg,不要使用导出为svg)2. 图像位置:链接(注意哦,不要点嵌入和保留编辑功能)---确定3. AI里面选中图形,点对象-路径-轮廓化描边 软件编辑要点: 从网站下down下来,记得下  Ai  格式. 使用Ai 进行编辑.( 别用PS软件编辑 ) 否则矢量图图片会被污染,编辑后 再上传 Icon 就会...

redis如何查看主从状态信息master和salve

首先你需要连接上redis [root@localhost src]# ./redis-cli -p 6384 --第一步从客户端命令工具连接redis   127.0.0.1:6384> auth 123456    --输入登录密码,登录  [root@localhost src]# info replication   --使用命令 i...

css如何画出类似原生的线条?

做前端的程序猿特别是移动端的,都很头疼遇到一种情况就是需要div底部加一个线条但是 1px的效果很粗,跟设计案上的不符合。 我的一个伙伴查找出来的一个解决方法: 在需要加上的线条的地方加上一个div class是一下对应的类,(使用的时候自己试试就知道了) css代码: .list-up-down-line:before { content: " "; p...

毕业设计 python opencv实现车牌识别 预处理

主要代码参考https://blog.csdn.net/wzh191920/article/details/79589506 GitHub:https://github.com/yinghualuowu 首先我们需要一个函数可以随时获取图片,无论在什么地方 filename = askopenfilename(title="选择识别图片", filetyp...

关于深度值的一些需要说明的点

学习立方体贴图(skybox)的时候,在优化那里,有这么一段话:  一开始我还有些纳闷,想着透视除法不是通过透视矩阵自动操作的嘛,还有z分量怎么就是深度值了?不是应该通过上次深度测试所给的函数才对吗? 带着这些疑问,我重新查阅了一些资料,也看了透视矩阵的推导过程。 实际上,我以前的想法有些许错误,在顶点着色器中,物体只进行的MVP操作(M:model,...