[3D UI 之道具系统系列] 4. 简单的交易系统 (1)

2015年08月25日 12:16 0 点赞 0 评论 更新于 2025-11-21 18:52

作者:quincyhuanghk 原文:点击查看

茶水君干货系列,小白必学,大神必喷。

首发泰斗:http://www.taidous.com,欢迎转发,请注明出处。

交易系统的 UI 设计和数据交互的代码已大幅更新,因此茶水君会分几个小章节来分析更新后的代码以及交易系统的 UI 设计。

交易系统展示

本章内容较多且更新幅度大,我们先来看一下结果,以便有更直观的感受。

下载好附件后进行测试,会看到 3 个主要界面:商店、装备栏、背包,以及一个次要界面——最下方的描述面板。这些界面的交互操作如下:

  • 红色箭头:从背包出售道具到商店。
  • 蓝色箭头:从商店购买道具到背包。
  • 绿色箭头:装备与卸载。

另外,在背包中双击消耗品(如黄金鸭)会直接使用。在交易过程中,以水晶球作为通货,其数量会发生变化。且该商店不回收武器(如树枝),将武器丢到商店时,商店无反应,这样我们可以自定义 NPC 的回收项目。

细心的读者会发现,背包中的道具可以分栏,并非强制叠堆,相关 API 已全部提供,可根据项目实际需求使用和修改。

当鼠标滑过 UISlot 时,描述面板会显示相应信息,该 Demo 基本实现了道具系统的交互操作(每次只能操作单组道具,后续如有需要会添加更多操作)。这里存在一个小的非致命 bug:当背包满格后,无法替换装备,因为程序逻辑是先卸载后装备,会认为没有空位,导致卸载失败,进而无法装备。若装备支持叠堆,此逻辑无误,可根据实际情况修复,茶水君后续再处理。

UISlot 设计更新

为适应道具分栏操作,需更新 UISlot 的设计,使其能对某些操作做出适当反应。

  1. 添加 Box Collider:直接为 UISlot 添加一个 Box Collider,其 size 等于 UISlot 的长宽,厚度 Z 为 1(只要比 UIStorage 的厚度厚即可,主要是避免被 UIStorage 遮挡,防止射线检测出现问题),并勾选 Trigger。
  2. 调整层级结构(非必要):为达到更好的效果,可重新调整其层级结构,主要将 BG Frame 提出来,放到 UISlot 首位。
  3. 更新 UISlot 代码
    • 添加代理函数
      public delegate void OnFunction(int id);
      public OnFunction onClick, onEnter, onExit;
      
    • 添加鼠标事件函数
      #region IPointerClickHandler implementation
      public void OnPointerClick (PointerEventData eventData)
      {
      if (clickable && eventData.clickCount == 2)
      {
      if (onClick!= null)
      {
      onClick(slot_id);
      }
      }
      }
      #endregion
      

region IPointerEnterHandler implementation

public void OnPointerEnter (PointerEventData eventData) { if (onEnter!= null) { onEnter(slot_id); } }

endregion

region IPointerExitHandler implementation

public void OnPointerExit (PointerEventData eventData) { if (onExit!= null) { onExit(slot_id); } }

endregion

- **更新初始化函数**:

// this is called by storage public void Init(UIStorageBase sb, int id, OnFunction clickFunc, OnFunction enterFunc, OnFunction exitFunc) { slot_id = id; storage = sb; AddOnClick(clickFunc); AddOnEnter(enterFunc); AddOnExit(exitFunc); // more here }


## UIStorageBase 代码更新
### 添加参数

public BackpackSystem backpackSys = null; public string moneyID = "Money"; public UIDescrption descrption;

按顺序,每个面板对应一个指定的背包数据、交易用的通货(主要用于商店)以及一个描述面板。通货可以有多种,类似 WOW 中的各种牌子,自定义通货可灵活设计 NPC 的交易货币,增加游戏乐趣。

### 添加虚函数

// this is called by slot, need to assign to slot first virtual public void Slot_OnClick(int id) { Debug.Log("Slot " + id + " on click!"); }

// this is called by slot, need to assign to slot first virtual public void Slot_OnEnter(int id) { if (descrption) { ItemBase item = ItemDatabase.GetItem(slots[id].item_id); if (item != null) { string info = "[" + item.displayName + "]\n\n" + item.comment; descrption.Set(slots[id], info); } } }

// this is called by slot, need to assign to slot first virtual public void Slot_OnExit(int id) { if (descrption) { descrption.Set(null, ""); } }


### 添加同步虚函数

virtual public void Sync() { for (int i = 0; i < slots.Count; i++) { slots[i].SetIconEmpty(); } }


### 添加获取被交互 UISlot 的函数

// get the ui slot which will be hit by the ray after the draging action. virtual public UISlot Get_UISlot_On_End_Drag() { // set current camera if (Camera.current == null) Camera.SetupCurrent(Camera.main);

RaycastHit hitinfo; Ray ray = Camera.current.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hitinfo)) { UISlot us = hitinfo.collider.gameObject.GetComponent(); return us; }

return null; }

以上虚函数将根据实际情况在子类中重写。

## UIDescrption 介绍
### 界面结构
从界面上看,UIDescrption 包含一些前景背景、一个没有 Text Info Group 的 UISlot 以及一个用于显示文字的文本框。
### 脚本配置
为其添加上 UIDescrption 的脚本并配置好。由于不需要和描述中的 UISlot 交互,将其 UISlot 的 3 个参数(Dragable、Clickable、Infoable)全部反选。
### 代码实现

public void Set(UISlot _slot, string _info) { if (_slot == null) { slot.SetIconEmpty(); slot.gameObject.SetActive(false); } else { slot.gameObject.SetActive(true); slot.SetIcon(_slot.icon.texture); slot.SetAtt1(_slot.att1.texture); slot.SetColor(_slot.fg.color); info.color = _slot.fg.color; }

info.text = _info; }


## 总结与展望
今天我们更新了 UISlot 和 UIStorage 的代码,新设计了 UIDescrption 这 3 个基本组件。

为保持数据系统的通用性,UI 面板中的交互操作是道具类型限制的重要手段。例如,商店、背包和装备栏使用相同的数据系统,需要在对应的 UI 面板中限制操作方式,如武器和护甲需分别装备在指定的 UISlot 中,且不能叠堆(若道具原本支持叠堆),同类装备可替换,替换出的道具会自动放入背包等,这些操作将在 UI 面板(UIStorage)中实现,以保证数据系统的一致性和可维护性。下次我们将更新背包数据系统。

本项目基于 Unity 5.1.2,新建一个空项目,然后覆盖 Assets 和 ProjectSettings 即可。
下载地址:[点击查看](http://www.taidous.com/forum.php?mod=viewthread&tid=32190)

PS:茶水君发现 UIDescrption 拼写错误,就先让它错着吧。

作者信息

洞悉

洞悉

共发布了 3994 篇文章