【Unity】基于MVC模式的双肩包系统 UGUI实现
2016-04-27 16:33
627 查看
本文基于MVC模式,用UGUI初步实现了背包系统。
Control层包含了点击和拖拽两种逻辑。
博文首发:http://blog.csdn.net/duzixi
下载地址:https://github.com/duzixi/InventorySystem
场景中Canvas上的对象:
Bag:用于显示背包内容
PickedItem:用于显示拾取道具的图片
资源中的预设体:
Item:生成背包的格子
目前还有点Bug,拖拽模式下当前物体拖拽会导致物品跟随。
另外屏幕适配还没有搞。
Control层包含了点击和拖拽两种逻辑。
博文首发:http://blog.csdn.net/duzixi
下载地址:https://github.com/duzixi/InventorySystem
一、工程准备(详见工程文件)
场景中Canvas上的对象:Bag:用于显示背包内容
PickedItem:用于显示拾取道具的图片
资源中的预设体:
Item:生成背包的格子
二、源代码
Model 层
using UnityEngine; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; /// <summary> /// 脚本功能:MVC模式——Model层,定义物品结构,保存物品数据 /// 添加对象:Bag 背包(Canvas下的空对象) /// 版权声明:Copyright (c) 2015 duzixi.com All Rights Reserved /// 创建日期:2015.5.8 /// 知识要点: /// 1. MVC /// 2. 自定义类 /// 3. 类的嵌套 /// </summary> public class ItemModel : MonoBehaviour { // 物品类的定义 public class Item { public string name; // 物品名称 public Sprite img; // 物品图片 // 构造器 public Item(string name, Sprite img) { this.name = name; this.img = img; } } public static List<Item> items; // 保存物品对象的集合 // 物品图片数组 public int size = 16; Sprite[] sprites; void Awake() // 数据初始化 { items = new List<Item>(); // 初始化List<Item> sprites = new Sprite[size]; // 根据行列值初始化物品列表 for (int i = 0; i < BagView.row; i++) { for (int j = 0; j < BagView.col; j++) { items.Add(new Item("", null)); } } // 【注意】实际开发中以下部分应由数据库代替 for (int i = 0; i < size; i++) { string name = i < 9 ? "0" + (i + 1) : "" + (i + 1); sprites[i] = Resources.Load(name, typeof(Sprite)) as Sprite; items[i] = new Item(" ", sprites[i]); } } }
View 层
using UnityEngine; using UnityEngine.UI; using System.Collections; /// <summary> /// 脚本功能:MVC模式 —— View视图,控制背包的显示方式 /// 添加对象:Bag 背包 (Canvas下的空对象) /// 版权声明:Copyright (c) 2015 duzixi.com All Rights Reserved /// 创建时间:2015.05.08 /// 修改记录:2015.05.18 添加编号 /// 修改记录:2015.07.03 封装显示物品格子方法 /// 知识要点: /// 1. MVC /// 2. UGUI /// </summary> public class BagView : MonoBehaviour { // 背包规格 public static int row = 4; // 行 public static int col = 5; // 列 // 背包格子 public GameObject grid; float width; // 格子宽度 float height; // 格子高度 // 根据格子预设体获取宽和高 void Awake() { width = grid.GetComponent<RectTransform>().rect.width; height = grid.GetComponent<RectTransform>().rect.height; } // 初始状态:平铺格子,创建背包 void Start () { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { // 计算ID值(物品列表下标) int id = j + i * col; // 实例化格子预设,按宽高布局 GameObject itemGrid = Instantiate(grid, transform.position + new Vector3(j * width, -i * height, 0), Quaternion.identity) as GameObject; // 将实例化的格子对象设置为背包的子对象 itemGrid.transform.SetParent(transform); // 调用自定义方法:显示某个id的格子内容 ShowItem(itemGrid.transform, id); // 给格子 PickUpDrop 组件编号,拾取放下时用 itemGrid.GetComponent<PickUpDrop>().gridID = id; } } } // 重新刷新背包显示(物品位置发生变化时) public void ShowItems() { for (int i = 0; i < row * col; i++) { Transform itemGrid = transform.GetChild(i); ShowItem(itemGrid, i); } } // 显示物品格子 private void ShowItem(Transform itemGrid, int id) { // 显示物品名称 Text txtUGUI = itemGrid.GetComponentInChildren<Text>(); txtUGUI.text = ItemModel.items[id].name; // 获取物品Icon的Image组件 Image imageUGUI = itemGrid.GetChild(0).GetComponent<Image>(); // 如果有物品,就显示图片 if (ItemModel.items[id].img != null) { imageUGUI.color = Color.white; } else { // 否则不显示 imageUGUI.color = Color.clear; } imageUGUI.sprite = ItemModel.items[id].img; } }
using UnityEngine; using UnityEngine.UI; using System.Collections; /// <summary> /// 脚本功能:让拾取的背包物品随鼠标移动 /// 添加对象:PickedItem 拾取的物品 /// 版权声明:Copyright (c) 2015 duzixi.com All Rights Reserved /// 创建日期:2015.05.18 /// 修改记录:2015.07.03 添加射线忽略 /// 知识要点: /// 1. UGUI RectTransform、锚点、中心点 /// 2. 忽略射线接口 ICanvasRaycastFilter /// </summary> public class MoveWithMouse : MonoBehaviour, ICanvasRaycastFilter { RectTransform rect; // 获取UGUI定位组件 Image icon; // 显示当前拾取物品的图标 void Awake() { rect = GetComponent<RectTransform>(); // 【注意】图标对象是第0个子对象 icon = transform.GetChild(0).GetComponent<Image>(); } void Update () { // 用鼠标位置给图标图片定位 rect.anchoredPosition3D = Input.mousePosition; // 根据是否有图片确定透明度 if (PickUpDrop.pickedItem.img != null) { icon.color = Color.white; } else { icon.color = Color.clear; } icon.sprite = PickUpDrop.pickedItem.img; } // 忽略鼠标图标上的射线 public bool IsRaycastLocationValid (Vector2 sp, Camera eventCamera) { return false; } }
Control 层
using UnityEngine; using UnityEngine.EventSystems; using System.Collections; /// <summary> /// 脚本功能:MVC模式 —— Control控制,背包内物品摆放 /// 添加对象:Item 物品格子预设体 /// 版权声明:Copyright (c) 2015 duzixi.com All Rights Reserved /// 创建日期:2015.05.18 duzixi.com /// 修改记录:2015.07.03 添加射线忽略 /// 知识要点: /// 1. UGUI、MVC设计模式 /// </summary> public class PickUpDrop : MonoBehaviour, IDropHandler { public int gridID; public static ItemModel.Item pickedItem; // 当前拾取的物品 void Start () { // 初始化当前拾取物品为空 pickedItem = new ItemModel.Item("", null); } // 背包核心逻辑:交换 public static void SwapItem(int gridID) { // 交换背包中的物品和拾取物品 ItemModel.Item temp = pickedItem; pickedItem = ItemModel.items[gridID]; ItemModel.items[gridID] = temp; // 刷新背包显示 GameObject.Find("Bag").GetComponent<BagView>().ShowItems(); } // 当物品按钮被点下时(点击触发模式) public void Drop() { SwapItem(gridID); } // 当物品放在格子中时(拖拽触发模式) public void OnDrop (PointerEventData eventData) { SwapItem(gridID); } }
using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections; /// <summary> /// 脚本功能:MVC模式 —— Control控制,操作逻辑,拖拽事件处理 /// 添加对象:Bag 背包 (Canvas下的空对象) /// 版权声明:Copyright (c) 2015 duzixi.com All Rights Reserved /// 创建时间:2015.07.03 /// 知识要点: /// 1. UnityEngine.EventSystem /// 2. IBeginDragHandlder, IDragHandler, IEndDragHander /// </summary> public class DragEvent : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler { int gridID = 0; // 格子编号 void Start() { gridID = GetComponentInParent<PickUpDrop>().gridID; // 获取格子编号 } // 开始拖拽 public void OnBeginDrag (PointerEventData eventData) { // 调用交换方法 PickUpDrop.SwapItem(gridID); } // 拖拽中 public void OnDrag (PointerEventData eventData) { // 【注意】即使没有任何代码处理也要实现该接口,否则拖拽不成功 } // 结束拖拽 public void OnEndDrag (PointerEventData eventData) { // 调用交换方法 PickUpDrop.SwapItem(gridID); } }
后语
目前还有点Bug,拖拽模式下当前物体拖拽会导致物品跟随。另外屏幕适配还没有搞。
相关文章推荐
- Unity3d开发(十二)使用Menu.SetCheck更改菜单勾选状态
- Unity3D 自定义事件(事件侦听与事件触发)
- Unity之Quaternion学习三
- Unity3D DFGUI根据名称获取多个子控件代码
- Unity3d 播放高质量视频解决方案
- 【小松教你手游开发】【unity实用技能】foreach为什么在unity不建议用
- 【小松教你手游开发】【unity实用技能】NGUI Depth探索
- 【小松教你手游开发】【系统模块开发】射线触发按钮
- 【小松教你手游开发】【系统模块开发】动态可拖动列表DynmicList,ScrollView
- 【小松教你手游开发】【unity实用技能】从NGUI的UIScrollview的实现原理延伸到ngui的层次,合并,drawcall生成原理
- 【小松教你手游开发】【unity实用技能】u3d 层次问题总结
- 【小松教你手游开发】【系统模块开发】做一个3d旋转菜单
- 【小松教你手游开发】【系统模块开发】图文混排 (在label中插入表情)
- 在BB10上增加对Unity游戏的手柄支持
- Unity3D中Android截图保存相册
- Unity3D——相机跟随物体移动
- Unity3D——键盘控制移动
- Unity3D——物体鼠标跟随转向
- Unity5.x 资源打包和加载
- Unity3d导入3dmax后model 的缩放为0.0254的原因以及解决办法