zoukankan      html  css  js  c++  java
  • 使用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版下载

  • 相关阅读:
    word 快捷键
    java中的各种修饰符作用范围
    pinyin4j的基本使用
    022-pinyin4j工具类模板
    测开之路一百四十五:SQLAlchemy与后台模板整合之新增、查询、删除
    测开之路一百四十四:ORM之SQLAlchemy查询
    测开之路一百四十三:ORM框架之SQLAlchemy模型及表创建
    测开之路一百四十二:ORM框架之SQLAlchemy建库、建表、数据库操作
    测开之路一百四十一:蓝图实现程序模块化
    测开之路一百四十:可拔插视图(基于类、基于方法)
  • 原文地址:https://www.cnblogs.com/zhenlong/p/4857229.html
Copyright © 2011-2022 走看看