您的位置:首页 > 产品设计 > UI/UE

使用UGUI实现拖拽功能(拼图小游戏)

2015-10-06 19:47 501 查看
实现方式

1、引入UGUI自带的事件系统  UnityEngine.EventSystems

2、为我们的类添加接口  IBeginDragHandler, IDragHandler, IEndDragHandler

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class DragOnPic : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler {

public void OnBeginDrag (PointerEventData eventData)
{
throw new System.NotImplementedException ();
}

void IDragHandler.OnDrag (PointerEventData eventData)
{
throw new System.NotImplementedException ();
}

public void OnEndDrag (PointerEventData eventData)
{
throw new System.NotImplementedException ();
}

}


拼图游戏实例

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类用于实现随机生成图片的功能

public class GameManager  {

/// <summary>
/// Randoms the array.
/// </summary>
static public void RandomArray(Sprite[] sprites)
{
for (int i = 0; i < sprites.Length; i++) {
//随机抽取数字中的一个位置,并将这张图片与第i张图片交换.
int index = Random.Range(i, sprites.Length);
Sprite temp = sprites[i];
sprites[i] = sprites[index];
sprites[index] = temp;
}
}
}


7、在ImageCreater中写入生产图片的方法

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ImageCreater : MonoBehaviour {

public static ImageCreater _instance;

//存储裁剪好图片的数组.
public Sprite[] sprites;

//格子的预设体.
public GameObject cellPrefab;

void Start () {
_instance = this;
CreateImages();
}

private void CreateImages()
{
//将图片数组随机排列.
GameManager.RandomArray(sprites);

//生产图片.
for (int i = 0; i < sprites.Length; i++) {
//通过预设体生成图片.
GameObject cell = (GameObject)Instantiate(cellPrefab);

//设置cell的名字方便检测是否完成拼图.
cell.name = i.ToString();

//获取cell的子物体.
Transform image = cell.transform.GetChild(0);

//设置显示的图片.
image.GetComponent<Image>().sprite = sprites[i];

//设置子物体的名称,方便检测是否完成拼图.
int tempIndex = sprites[i].name.LastIndexOf('_');
image.name = sprites[i].name.Substring(tempIndex + 1);

//将Cell设置为Panel的子物体.
cell.transform.SetParent(this.transform);

//初始化大小.
cell.transform.localScale = Vector3.one;
}
}

}


8、到这里,拼图游戏已经基本成形,下面只需要实现每张图片的拖拽功能就OK了,下面是DragOnPic的代码

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class DragOnPic : MonoBehaviour,IBeginDragHandler, IDragHandler, IEndDragHandler {

//记录下自己的父物体.
Transform myParent;

//Panel,使拖拽是显示在最上方.
Transform tempParent;

CanvasGroup cg;
RectTransform rt;

//记录鼠标位置.
Vector3 newPosition;

void Awake()
{
//添加CanvasGroup组件用于在拖拽是忽略自己,从而检测到被交换的图片.
cg = this.gameObject.AddComponent<CanvasGroup>();

rt = this.GetComponent<RectTransform>();

tempParent = GameObject.Find("Canvas").transform;
}

/// <summary>
/// Raises the begin drag event.
/// </summary>
public void OnBeginDrag (PointerEventData eventData)
{
//拖拽开始时记下自己的父物体.
myParent = transform.parent;

//拖拽开始时禁用检测.
cg.blocksRaycasts = false;

this.transform.SetParent(tempParent);
}

/// <summary>
/// Raises the drag event.
/// </summary>
void IDragHandler.OnDrag (PointerEventData eventData)
{
//推拽是图片跟随鼠标移动.
RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, Input.mousePosition, eventData.enterEventCamera, out newPosition);
transform.position = newPosition;
}

/// <summary>
/// Raises the end drag event.
/// </summary>
public void OnEndDrag (PointerEventData eventData)
{
//获取鼠标下面的物体.
GameObject target = eventData.pointerEnter;

//如果能检测到物体.
if(target)
{
GameManager.SetParent(this.transform, target.transform, myParent);
}
else {
this.transform.SetParent (myParent);
this.transform.localPosition = Vector3.zero;
}

//拖拽结束时启用检测.
cg.blocksRaycasts = true;

//检测是否完成拼图.
if(GameManager.CheckWin())
{
Debug.Log("Win!!!");
}

}

}


在GameManager中加入设置父物体的方法及检测是否完成拼图的方法:

1    /// <summary>
/// Sets the parent.
/// </summary>
static public void SetParent(Transform mine, Transform target, Transform oldParent)
{
//如果检测到图片,则交换父物体并重置位置.
switch (target.tag)
{
case "Cell":
mine.SetParent(target.parent);
target.SetParent(oldParent);
mine.localPosition = Vector3.zero;
target.localPosition = Vector3.zero;
break;
default:
mine.SetParent (oldParent);
mine.localPosition = Vector3.zero;
break;
}
}

/// <summary>
/// Checks is win.
/// </summary>
static public bool CheckWin()
{
for (int i = 0; i < ImageCreater._instance.transform.childCount; i++) {
if(ImageCreater._instance.transform.GetChild(i).name != ImageCreater._instance.transform.GetChild (i).transform.GetChild(0).name)
{
return false;
}
}
return true;
}


到这里,拼图的基本功能就算是全部完成了

网页版预览

PC版下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: