沿用Attribute设计实现物品等级
效果图
1级物品
前面已对Attribute设计做了介绍
大致示意图
增加ItemStatus
为了沿用设计,首先需要将AttributeNode封装出来
通过从UserItemEntity封装ItemStatus
public class ItemStatus : MonoBehaviour
{
private Sprite m_Icon;
private string m_ItemTypeString;
private string m_AttributeString;
private UserItemEntity m_Item;
private bool m_IsChanged = false;
private bool m_IsInit = false;
public string ItemName { get; set; }
public string Description { get; set; }
public string IconPath { get; set; }
public Sprite Icon
{
get
{
if (this.m_Icon == null || m_IsChanged)
{
this.m_Icon = Resources.Load<Sprite>(this.IconPath);
}
return m_Icon;
}
}
public int Lv { get; set; }
public int LvMax { get; set; }
public int Count { get; set; }
public ItemType ItemType { get; set; }
public int StatckCount { get; set; }
public int Price { get; set; }
public string ItemTypeString {
get
{
if (String.IsNullOrEmpty(m_ItemTypeString) || m_IsChanged)
{
m_ItemTypeString = BuildItemTypeString();
}
return m_ItemTypeString;
}
}
public string AttributeString
{
get
{
if(String.IsNullOrEmpty(m_AttributeString) || m_IsChanged)
{
m_AttributeString = BuildAttributeString();
}
return m_AttributeString;
}
}
private AttributeNode statusGrowth = new AttributeNode();
public AttributeNode status = new AttributeNode();
public void Load(UserItemEntity item)
{
if (m_IsInit)
return;
this.m_Item = item;
this.Lv = item.Lv;
this.LvMax = item.ItemInfo.MaxLv;
this.ItemName = item.ItemInfo.Name;
this.Description = item.ItemInfo.Description;
this.Count = item.Count;
this.StatckCount = item.ItemInfo.StackCount;
this.IconPath = item.ItemInfo.IconPath;
this.ItemType = item.ItemInfo.ItemType;
this.Price = item.ItemInfo.Price;
InitAllStatus();
m_IsInit = true;
}
private void InitAllStatus()
{
InitStatusGrowth();
InitStatus();
}
//升级效果
private void InitStatusGrowth()
{
this.statusGrowth.Hp = this.Lv * this.m_Item.ItemInfo.HpGrowth;
this.statusGrowth.Mp = this.Lv * this.m_Item.ItemInfo.MpGrowth;
this.statusGrowth.Atk = this.Lv * this.m_Item.ItemInfo.AtkGrowth;
this.statusGrowth.Def = this.Lv * this.m_Item.ItemInfo.DefGrowth;
this.statusGrowth.Spd = this.Lv * this.m_Item.ItemInfo.SpdGrowth;
this.statusGrowth.Hit = this.Lv * this.m_Item.ItemInfo.HitGrowth;
this.statusGrowth.CriticalRate = this.Lv * this.m_Item.ItemInfo.CriticalRateGrowth;
this.statusGrowth.AtkSpd = this.Lv * this.m_Item.ItemInfo.AtkSpdGrowth;
this.statusGrowth.AtkRange = this.Lv * this.m_Item.ItemInfo.AtkRangeGrowth;
this.statusGrowth.MoveSpd = this.Lv * this.m_Item.ItemInfo.MoveSpdGrowth;
}
//计算最终属性状态
private void InitStatus()
{
this.status.Hp = this.Lv * this.m_Item.ItemInfo.Hp;
this.status.Mp = this.Lv * this.m_Item.ItemInfo.Mp;
this.status.Atk = this.Lv * this.m_Item.ItemInfo.Atk;
this.status.Def = this.Lv * this.m_Item.ItemInfo.Def;
this.status.Spd = this.Lv * this.m_Item.ItemInfo.Spd;
this.status.Hit = this.Lv * this.m_Item.ItemInfo.Hit;
this.status.CriticalRate = this.Lv * this.m_Item.ItemInfo.CriticalRate;
this.status.AtkSpd = this.Lv * this.m_Item.ItemInfo.AtkSpd;
this.status.AtkRange = this.Lv * this.m_Item.ItemInfo.AtkRange;
this.status.MoveSpd = this.Lv * this.m_Item.ItemInfo.MoveSpd;
this.status.AddNode(this.statusGrowth);
this.status.Calculate();
}
private string BuildItemTypeString()
{
string itemTypeString = "类型: {0}";
switch (this.ItemType)
{
case ItemType.Potion:
itemTypeString = string.Format(itemTypeString, "");
break;
case ItemType.Armor:
itemTypeString = string.Format(itemTypeString, "防具");
break;
case ItemType.Necklace:
itemTypeString = string.Format(itemTypeString, "项链");
break;
case ItemType.Ring:
itemTypeString = string.Format(itemTypeString, "戒指");
break;
case ItemType.Weapon:
itemTypeString = string.Format(itemTypeString, "武器");
break;
}
return itemTypeString;
}
private string BuildAttributeString()
{
StringBuilder sbAttribute = new StringBuilder();
if (status.HpMax != 0)
{
sbAttribute.AppendLine("体力 +" + status.HpMax);
}
if (status.MpMax != 0)
{
sbAttribute.AppendLine("魔力 +" + status.MpMax);
}
if (status.AtkMax != 0)
{
sbAttribute.AppendLine("攻击 +" + status.AtkMax);
}
if (status.DefMax != 0)
{
sbAttribute.AppendLine("防御 +" + status.DefMax);
}
if (status.SpdMax != 0)
{
sbAttribute.AppendLine("速度 +" + status.SpdMax);
}
if (status.AtkRangeMax != 0)
{
sbAttribute.AppendLine("攻击范围 +" + status.AtkRangeMax);
}
if (status.AtkSpdMax != 0)
{
sbAttribute.AppendLine("攻击速度 +" + status.AtkSpdMax);
}
if (status.CriticalRateMax != 0)
{
sbAttribute.AppendFormat("暴击率 +" + status.CriticalRateMax);
}
return sbAttribute.ToString();
}
}
将ItemStatus 挂在Item预制体上
修改之前测试时对ItemEntity的调用
UIInventory
背包管理类
去掉测试方法
public class UIInventory : UIScene {
public static int gridCount = 40; //背包格子数量
private GameObject m_GridPrefab; //格子预制体
private GameObject m_ItemPrefab; //物品预制体
private Transform m_PnlGrid; //背包里层
private RectTransform m_PnlGridRectTransfom; //背包里层的RectTransform,用于动态调整它的大小
private List<Transform> m_GridList = new List<Transform>(); //所有格子
private Dictionary<int, IEntity> m_ItemList; //从缓存里取出的ItemList
private UIItemToolTip m_EquipToolTip;
protected override void Start()
{
base.Start();
InitWidget();
InitGrid();
LoadData();
}
private void InitWidget()
{
this.m_GridPrefab = (GameObject)Resources.Load("Inventory/Grid");
this.m_ItemPrefab = (GameObject)Resources.Load("Inventory/Item");
this.m_PnlGrid = this.transform.Find("pnlScrowView/pnlGrid");
this.m_PnlGridRectTransfom = m_PnlGrid.GetComponent<RectTransform>();
this.m_EquipToolTip = UIManager.Instance.GetUI<UIItemToolTip>(UIName.UIItemToolTip);
}
private void InitGrid()
{
//动态创建Grid
for (int i = 0; i < gridCount; i++)
{
GameObject grid = GameObject.Instantiate(this.m_GridPrefab);
grid.transform.SetParent(m_PnlGrid);
m_GridList.Add(grid.transform);
}
}
//从缓存中加载角色现有物品,还未做物品仓库,身上或背包的判定
private void LoadData()
{
m_ItemList = PhotonDataCache.GetAll(PhotonCacheType.UserItem);
foreach (var item in m_ItemList)
{
AddItem(item.Key);
}
}
public Transform GetEnmptyGrid()
{
return m_GridList.Find(x => x.childCount == 0);
}
public void AddItem(int id)
{
Transform grid = GetEnmptyGrid();
if (grid == null)
return;
if (!m_ItemList.ContainsKey(id))
return;
UserItemEntity item = m_ItemList[id] as UserItemEntity;
GameObject go = GameObject.Instantiate(this.m_ItemPrefab);
go.transform.SetParent(grid);
//在SetInfo里对ItemStatus进行初始化
go.GetComponent<UIItem>().SetInfo(item);
go.transform.localPosition = Vector3.zero;
go.transform.localScale = Vector3.one;
go.GetComponent<UIItem>().PointerClick += OnUIItemPointerClick;
}
//修改事件参数为ItemStatus
private void OnUIItemPointerClick(ItemStatus itemStatus)
{
m_EquipToolTip.Show(itemStatus, true);
}
}
UIItem
界面取值都改为从ItemStatus取
public class UIItem : MonoBehaviour, IPointerClickHandler {
private Image m_Icon;
private Text m_TxtName;
private Text m_TxtCount;
private Toggle m_Toggle;
private ToggleGroup m_ToggleGroup;
private ItemStatus m_ItemStatus;
public event Action<ItemStatus> PointerClick;
void Awake()
{
this.m_Icon = UIHelper.FindChild<Image>(transform, "imgIcon");
this.m_TxtName = UIHelper.FindChild<Text>(transform, "imgName/Text");
this.m_TxtCount = UIHelper.FindChild<Text>(transform, "imgCount/Text");
this.m_Toggle = transform.GetComponent<Toggle>();
this.m_ItemStatus = transform.GetComponent<ItemStatus>();
}
public void SetInfo(UserItemEntity item)
{
this.m_ItemStatus.Load(item);
this.m_TxtName.text = this.m_ItemStatus.ItemName;
this.m_Icon.overrideSprite = this.m_ItemStatus.Icon;
this.m_ToggleGroup = transform.parent.parent.GetComponent<ToggleGroup>();
this.m_Toggle.group = this.m_ToggleGroup;
this.m_TxtCount.text = this.m_ItemStatus.Count.ToString();
}
public void OnPointerClick(PointerEventData eventData)
{
if (PointerClick != null)
PointerClick(m_ItemStatus);
}
}