使用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版下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM