使用UGUI实现拖拽功能(拼图小游戏)

实现方式

1、引入UGUI自带的事件系统  UnityEngine.EventSystems

2、为我们的类添加接口  IBeginDragHandler, IDragHandler, IEndDragHandler

 1 using UnityEngine;
 2 using System.Collections;
 3 using UnityEngine.EventSystems;
 4 
 5 public class DragOnPic : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler {
 6 
 7 
 8     public void OnBeginDrag (PointerEventData eventData)
 9     {
10         throw new System.NotImplementedException ();
11     }
12 
13 
14     void IDragHandler.OnDrag (PointerEventData eventData)
15     {
16         throw new System.NotImplementedException ();
17     }
18 
19 
20     public void OnEndDrag (PointerEventData eventData)
21     {
22         throw new System.NotImplementedException ();
23     }
24 
25 }

拼图游戏实例

 

1、准备一张拼图要用到的图片素材,并拖入Unity中

2、图片的TextureType选为Sprite(2D and UI), 点击Apply

3、将SpriteMode改为Multiple,点击SpriteEditor,在弹出的窗口中点Slice,Type为Grid,我这张图片分辨率是500x500的,拆分为16份,所以我的PixelSize是125x125,最终结果如下图:

4、添加一个Panel作为背景,为Panel添加GridLayoutGroup组件,具体设置如下,添加脚本ImageCreater用于生成图片

5、为Panel添加一个Image作为我们拼图的格子的背景,名字改为Cell,在这个Cell上再添加一个Image作为图片的载体,并将它的Tag设置为Cell,为Image添加拖拽脚本DragOnPic,将Cell拖成预制体备用

6、新建一个GameManager类用于实现随机生成图片的功能

 

 1 public class GameManager  {
 2 
 3     /// <summary>
 4     /// Randoms the array.
 5     /// </summary>
 6     static public void RandomArray(Sprite[] sprites)
 7     {
 8         for (int i = 0; i < sprites.Length; i++) {
 9             //随机抽取数字中的一个位置,并将这张图片与第i张图片交换.
10             int index = Random.Range(i, sprites.Length);
11             Sprite temp = sprites[i];
12             sprites[i] = sprites[index];
13             sprites[index] = temp;
14         }
15     }
16 }

 

7、在ImageCreater中写入生产图片的方法

 1 using UnityEngine;
 2 using System.Collections;
 3 using UnityEngine.UI;
 4 
 5 public class ImageCreater : MonoBehaviour {
 6 
 7     public static ImageCreater _instance;
 8 
 9     //存储裁剪好图片的数组.
10     public Sprite[] sprites;
11 
12     //格子的预设体.
13     public GameObject cellPrefab;
14 
15     void Start () {
16         _instance = this;
17         CreateImages();
18     }
19     
20     private void CreateImages()
21     {
22         //将图片数组随机排列.
23         GameManager.RandomArray(sprites);
24 
25         //生产图片.
26         for (int i = 0; i < sprites.Length; i++) {
27             //通过预设体生成图片.
28             GameObject cell = (GameObject)Instantiate(cellPrefab);
29 
30             //设置cell的名字方便检测是否完成拼图.
31             cell.name = i.ToString();
32 
33             //获取cell的子物体.
34             Transform image = cell.transform.GetChild(0);
35 
36             //设置显示的图片.
37             image.GetComponent<Image>().sprite = sprites[i];
38 
39             //设置子物体的名称,方便检测是否完成拼图.
40             int tempIndex = sprites[i].name.LastIndexOf('_');
41             image.name = sprites[i].name.Substring(tempIndex + 1);
42 
43             //将Cell设置为Panel的子物体.
44             cell.transform.SetParent(this.transform);
45 
46             //初始化大小.
47             cell.transform.localScale = Vector3.one;
48         }
49     }
50 
51 }

 

8、到这里,拼图游戏已经基本成形,下面只需要实现每张图片的拖拽功能就OK了,下面是DragOnPic的代码

 1 using UnityEngine;
 2 using System.Collections;
 3 using UnityEngine.EventSystems;
 4 
 5 public class DragOnPic : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler {
 6 
 7     //记录下自己的父物体.
 8     Transform myParent;
 9 
10     //Panel,使拖拽是显示在最上方.
11     Transform tempParent;
12 
13     CanvasGroup cg;
14     RectTransform rt;
15 
16     //记录鼠标位置.
17     Vector3 newPosition;
18 
19     void Awake()
20     {
21         //添加CanvasGroup组件用于在拖拽是忽略自己,从而检测到被交换的图片.
22         cg = this.gameObject.AddComponent<CanvasGroup>();
23 
24         rt = this.GetComponent<RectTransform>();
25 
26         tempParent = GameObject.Find("Canvas").transform;
27     }
28 
29 
30 
31 
32     /// <summary>
33     /// Raises the begin drag event.
34     /// </summary>
35     public void OnBeginDrag (PointerEventData eventData)
36     {
37         //拖拽开始时记下自己的父物体.
38         myParent = transform.parent;
39 
40         //拖拽开始时禁用检测.
41         cg.blocksRaycasts = false;
42 
43         this.transform.SetParent(tempParent);
44     }
45     
46     /// <summary>
47     /// Raises the drag event.
48     /// </summary>
49     void IDragHandler.OnDrag (PointerEventData eventData)
50     {
51         //推拽是图片跟随鼠标移动.
52         RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, Input.mousePosition, eventData.enterEventCamera, out newPosition);
53         transform.position = newPosition;
54     }
55     
56     /// <summary>
57     /// Raises the end drag event.
58     /// </summary>
59     public void OnEndDrag (PointerEventData eventData)
60     {
61         //获取鼠标下面的物体.
62         GameObject target = eventData.pointerEnter;
63 
64         //如果能检测到物体.
65         if(target)
66         {
67             GameManager.SetParent(this.transform, target.transform, myParent);
68         }
69         else {
70             this.transform.SetParent (myParent);
71             this.transform.localPosition = Vector3.zero;
72         }
73 
74         //拖拽结束时启用检测.
75         cg.blocksRaycasts = true;
76 
77         //检测是否完成拼图.
78         if(GameManager.CheckWin())
79         {
80             Debug.Log("Win!!!");
81         }
82         
83     }
84     
85 }

 

在GameManager中加入设置父物体的方法及检测是否完成拼图的方法:

 1    /// <summary>
 2     /// Sets the parent.
 3     /// </summary>
 4     static public void SetParent(Transform mine, Transform target, Transform oldParent)
 5     {
 6         //如果检测到图片,则交换父物体并重置位置.
 7         switch (target.tag)
 8         {
 9         case "Cell":
10             mine.SetParent(target.parent);
11             target.SetParent(oldParent);
12             mine.localPosition = Vector3.zero;
13             target.localPosition = Vector3.zero;
14             break;
15         default:
16             mine.SetParent (oldParent);
17             mine.localPosition = Vector3.zero;
18             break;
19         }
20     }
21 
22     /// <summary>
23     /// Checks is win.
24     /// </summary>
25     static public bool CheckWin()
26     {
27         for (int i = 0; i < ImageCreater._instance.transform.childCount; i++) {
28             if(ImageCreater._instance.transform.GetChild(i).name != ImageCreater._instance.transform.GetChild (i).transform.GetChild(0).name)
29             {
30                 return false;
31             }
32         } 
33         return true;
34     }

 

 

 到这里,拼图的基本功能就算是全部完成了

网页版预览

PC版下载

 

posted @ 2015-10-06 19:47  狭隘龙  阅读(11263)  评论(8编辑  收藏  举报