实现方式
1、引入UGUI自带的事件系统UnityEngine.EventSystems
2、为我们的类添加接口IBeginDragHandler, IDragHandler, IEndDragHandler
1 usingUnityEngine;2 usingSystem.Collections;3 usingUnityEngine.EventSystems;4
5 public classDragOnPic : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler {6
7
8 public voidOnBeginDrag (PointerEventData eventData)9 {10 throw newSystem.NotImplementedException ();11 }12
13
14 voidIDragHandler.OnDrag (PointerEventData eventData)15 {16 throw newSystem.NotImplementedException ();17 }18
19
20 public voidOnEndDrag (PointerEventData eventData)21 {22 throw newSystem.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 classGameManager {2
3 ///
4 ///Randoms the array.5 ///
6 static public voidRandomArray(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 usingUnityEngine;2 usingSystem.Collections;3 usingUnityEngine.UI;4
5 public classImageCreater : MonoBehaviour {6
7 public staticImageCreater _instance;8
9 //存储裁剪好图片的数组.
10 publicSprite[] sprites;11
12 //格子的预设体.
13 publicGameObject cellPrefab;14
15 voidStart () {16 _instance = this;17 CreateImages();18 }19
20 private voidCreateImages()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().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 usingUnityEngine;2 usingSystem.Collections;3 usingUnityEngine.EventSystems;4
5 public classDragOnPic : 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 voidAwake()20 {21 //添加CanvasGroup组件用于在拖拽是忽略自己,从而检测到被交换的图片.
22 cg = this.gameObject.AddComponent();23
24 rt = this.GetComponent();25
26 tempParent = GameObject.Find("Canvas").transform;27 }28
29
30
31
32 ///
33 ///Raises the begin drag event.34 ///
35 public voidOnBeginDrag (PointerEventData eventData)36 {37 //拖拽开始时记下自己的父物体.
38 myParent =transform.parent;39
40 //拖拽开始时禁用检测.
41 cg.blocksRaycasts = false;42
43 this.transform.SetParent(tempParent);44 }45
46 ///
47 ///Raises the drag event.48 ///
49 voidIDragHandler.OnDrag (PointerEventData eventData)50 {51 //推拽是图片跟随鼠标移动.
52 RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, Input.mousePosition, eventData.enterEventCamera, outnewPosition);53 transform.position =newPosition;54 }55
56 ///
57 ///Raises the end drag event.58 ///
59 public voidOnEndDrag (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 ///
2 ///Sets the parent.3 ///
4 static public voidSetParent(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 ///
23 ///Checks is win.24 ///
25 static public boolCheckWin()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 }
到这里,拼图的基本功能就算是全部完成了