實現方式
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 }
到這里,拼圖的基本功能就算是全部完成了