使用UGUI实现拖拽功能(拼图小游戏)
实现方式
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 = ; 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 = ; i < sprites.Length; i++) {
//通过预设体生成图片.
GameObject cell = (GameObject)Instantiate(cellPrefab); //设置cell的名字方便检测是否完成拼图.
cell.name = i.ToString(); //获取cell的子物体.
Transform image = cell.transform.GetChild(); //设置显示的图片.
image.GetComponent<Image>().sprite = sprites[i]; //设置子物体的名称,方便检测是否完成拼图.
int tempIndex = sprites[i].name.LastIndexOf('_');
image.name = sprites[i].name.Substring(tempIndex + ); //将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 = ; i < ImageCreater._instance.transform.childCount; i++) {
if(ImageCreater._instance.transform.GetChild(i).name != ImageCreater._instance.transform.GetChild (i).transform.GetChild().name)
{
return false;
}
}
return true;
}
到这里,拼图的基本功能就算是全部完成了
使用UGUI实现拖拽功能(拼图小游戏)的更多相关文章
- 使用NGUI实现拖拽功能(拼图小游戏)
上一次用UGUI实现了拼图小游戏,这次,我们来用NGUI来实现 实现原理 NGUI中提供了拖拽的基类UIDragDropItem,所以我们要做的就是在要拖拽的图片上加一个继承于该类的脚本,并实现其中的 ...
- canvas drag 实现拖拽拼图小游戏
博主一直心心念念想做一个小游戏- 前端时间终于做了一个小游戏,直到现在才来总结,哈哈- 以后要勤奋点更新博客! 实现原理 1.如何切图? 用之前的方法就是使用photoshop将图片切成相应大小的图 ...
- React Editor 应用编辑器(1) - 拖拽功能剖析
这是可视化编辑器 Gaea-Editor 的第一篇连载分析文章,希望我能在有限的篇幅讲清楚制作这个网页编辑器的动机,以及可能带来的美好使用前景(画大饼).它会具有如下几个特征: 运行在网页 文档流布局 ...
- JQuery UI的拖拽功能
JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互.动画.特效等API,并且封装了一些Web小部件(Widget).同时,JQuery UI继承了jquery的插件支持,有大量 ...
- Js元素拖拽功能实现
Js元素拖拽功能实现 需要解决的问题 最近项目遇到了一个问题,就是用户某个操作需要弹出一个自定义的内容输入框,但是有个缺点,当浏览太大的时候没办法点击确认和取消按钮,应为这个弹出框是采用绝对定位的,取 ...
- (Demo分享)利用JavaScript(JS)实现一个九宫格拖拽功能
利用JavaScript(JS)实现一个九宫格拖拽功能 Demo实现了对任意方格进行拖拽,可以交换位置,其中Demo-1利用了勾股定理判断距离! Demo-1整体思路: 1.首先div实现自由移动 ...
- html5中的拖拽功能
拖拽元素支持的事件 ondrag 应用于拖拽元素,整个拖拽过程都会调用 ondragstart 应用于拖拽元素,当拖拽开始时调用 ondragleave 应用于拖拽元素,当鼠标离开拖拽元素是调用 on ...
- 使用 vue3 的自定义指令给 element-plus 的 el-dialog 增加拖拽功能
element-plus 提供的 el-dialog 对话框功能非常强大,只是美中不足不能通过拖拽的方式改变位置,有点小遗憾,那么怎么办呢?我们可以通过 vue 的自定义指令来实现一个可以拖拽的对话框 ...
- RCP:拖拽功能的实现 Drag and Drop
SWT中的拖拽是使用的org.eclipse.swt.dnd. 有三个需要密切注意的类: 1.DragSource 2.DropTarget 3.Transfer DragSource封装了需要被拖拽 ...
随机推荐
- [转]Numpy使用MKL库提升计算性能
from:http://unifius.wordpress.com.cn/archives/5 系统:Gentoo Linux (64bit, Kernel 3.7.1)配置:Intel(R) Cor ...
- HOOK(钩子)函数
安装.卸载钩子的相关函数 钩子类型 按功能分: 1.WH_CALLWNDPROC和WH_CALLWNDPROCRET:使你可以监视发送到窗口过程的消息3.WH_DEBUG 调试钩子4.WH_FO ...
- 采用Jenkins搭建持续集成环境
Jenkins介绍 Jenkins是一个CI工具.它可以根据设定持续定期编译,运行相应代码:运行UT或集成测试:将运行结果发送至邮件,或展示成报告... 这样做的最终目的是: 让项目保持健康的状态.如 ...
- ubuntu_虚拟机和SD卡链接失败,可能的原因
这个问题很简单吧,但是自己解决却用了很长时间,说一下方法吧! 1.有的虚拟机不兼容USB3.0的接口,所以在接SD卡(读卡器)时,请将读卡器拔出,插入笔记本USB2.0的接口上(当时自己没注意到这点, ...
- 关于Trie Tree简单实现
最近突然有兴致hiho一下了,实现了下trie tree,感觉而言,还是挺有意思的,个人觉得这货不光可以用来查单词吧,其实也可以用来替代Hash,反正查找,插入复杂度都挺低的,哈哈,啥都不懂,瞎扯.. ...
- NET 2.0(C#)调用ffmpeg处理视频的方法
另外:ffmpeg的net封装库 http://www.intuitive.sk/fflib/ NET 2.0 调用FFMPEG,并异步读取输出信息的代码...public void ConvertV ...
- jQuery基础与常用方法学习笔记
JQ与JS的关系:可以共存,不可混用.jq源码,源生JS面向对象写的 JQ写法 链式操作 $(‘#div’).html(‘hello’).css().click() 赋值取值合体 .html(‘h ...
- ios 开发证书 appids 描述文件关系
当你准备进行真机测试或者发布应用到App Store上去的时候, 免不了要申请相应的证书.(Development--测试证书. Distribution--发布证书) 进入证书管理相应网站https ...
- CSS行高line-height的一些深入理解及应用
一.一些字面意思. “行高”大约是指:一行文字的高度.具体来说是指两行文字间基线之间的距离.基线是在英文字母中用到的一个概念,我们刚学英语使用的那个英语本子每行有四条线,其中底部第二条线就是基线,是a ...
- Jenkins2.32.1+svn+maven安装配置与构建部署
这两天学习了一下持久化集成工具Jenkins,在自己的本地搭建一个简单的Jenkins环境. 使用环境:Windows64系统,JDK1.8,eclipse,svn(Windows版本VisualSV ...