unity——UI拖拽实现拼图

拿一张图片剪切好备用

在Canvas下新建panel作为父物体

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

在Cell下新建image,改Tag为Cell

在这个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;
        }
    }

}

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

莫说我穷的叮当响,大袖揽清风。 莫讥我困时无处眠,天地做床被。 莫笑我渴时无美酒,江湖来做壶。
原文地址:https://www.cnblogs.com/huang--wei/p/11133857.html