实现方式
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 }
到这里,拼图的基本功能就算是全部完成了