本章内容较多,且更新幅度巨大,所以,我们现在看看先结果好了,这样大家有个直接点的感觉。
那么下载好附件之后,打开测试,如图1,
这几个界面的交互操作请看彩色剪头。
这里,我们将那个水晶球作为通货,在交易过程中,大家看见通货的数量会发生变化,而且,这个商店是不回收武器(这里树枝是武器),所以丢武器过去的时候,商店是没有反应了,这样我们可以自定义NPC的回收项目了。
细心的你们还会发现,背包中的道具时可以分栏的,不一定是强制叠堆的,这里的API都已经提供完全了,大家可以根据项目的实际需求来使用和修改,如图2,
这个Demo基本上实现了道具系统的交互操作了。(每次只能操作单组道具,日后如有需要,会添加更多操作。这里有个小小的非致命bug,当背包满格后,就不能替换装备,因为在程序上来说,是先卸载后装备的,所以程序会认为没有空位,所以卸载失败,就不能装备了,这个bug大家有兴趣可以尝试修复下,这里茶水留在以后再修复吧,因为考虑到如果装备也可以叠堆的话,则这个逻辑是没有错的,所以视实际情况吧。)
那么,为了适应这种道具分栏的操作,我们需要更新一下我们的UISlot的设计,使其能对某些操作做出适当的反应。
然后,更新UISlot代码部分,其中比较重要的是,修改和添加了新的代理函数,代码:
[C#] 纯文本查看 复制代码
public delegate void OnFunction(int id); public OnFunction onClick, onEnter, onExit;
[C#] 纯文本查看 复制代码
#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
最后,当然要更新一下他的初始化函数,这样,UIStroage在初始化UISlot的时候,就可以赋值代理函数了,代码:
[C#] 纯文本查看 复制代码
// 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的代码了,首先,我们添加一些参数,代码:
通货何以有好多,类似WOW中的各种牌子,所以自定义通货可以灵活设计NPC的交易货币,增加游戏乐趣吧。
[C#] 纯文本查看 复制代码
// 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,""); } }
[C#] 纯文本查看 复制代码
virtual public void Sync() { for(int i=0;i<slots.Count;i++) { slots[i].SetIconEmpty(); } }
[C#] 纯文本查看 复制代码
// 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<UISlot>(); return us; } return null; }
最后还有点时间,那么我们快速将UIDescrption过一遍吧,如图5,
至于UIDescrption的代码,没有什么特别,目前就一个函数,用于设置显示的Icon和文字而已,代码:
[C#] 纯文本查看 复制代码
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; }
PS:为了保持数据系统的通用性,所以UI面板中的交互操作成为了很重要的一个道具类型限制的手段,例如商店,背包和装备栏是使用一样的数据系统,所以我们需要在其对应的UI面板中,限制其操作方式,例如装备中,武器和护甲需要分别装备在指定的UISlot中,而且不能叠堆(如果该道具原本支持叠堆的话),同类装备可以替换,替换出来的道具会自动放到背包中,等等,这些操作都会在UI面板(UIStorage)中实现,从而保证我们的数据系统一致性,和便于维护。下次我们就来更新我们的背包数据系统吧。
本项目基于 Unity 5.1.2,
新建一个空项目,然后覆盖 Assets ,和 ProjectSettings 就好了。
下载地址,原文:http://www.taidous.com/forum.php?mod=viewthread&tid=32190