实现效果
假定我们已经从实现了json存为字典,并可以通过管理类获取实体的操作。若有疑问可参考我的另一篇文章:https://blog.csdn.net/qq_41083853/article/details/104369853
了解RectTransform组件基础知识
UI在CANVAS中有两种布局方式,两种方式显示的数值是不一样的
可根据如图方式切换:
- 绝对定位
Posx,y,z就是指轴心(Pivot蓝色小圈),距离canvas轴心(一般是canvas中心)的距离 - 相对定位(非常好用)
Left指当前Ui元素的左边界距离父元素的左边界的距离,其他值也是一样的意思。
背包界面UI的搭建。
UI大致分为三个三个模块
- Scroll滚动区域
带有ScrollRect组件,负责控制道具面板的滚动显示。
viewport是可显示的区域大小,需要mask组件和image组件配合,实现区域遮罩。
这是所有道具显示的区域,使用VerticalLayoutGroup组件进行垂直布局,childAlignment可以控制子ui的对其方式。还需加上关键的ContentSizeFiltter组件,这个组件的当前设置能根据Conten内容的大小动态变换Content的高度,这对于上面的scrollRect组件很关键。
scrollbar拖动条没什么特别的。
-
道具描述区域
通过脚本BkInfoPanel来控制当前区域的逻辑显示。 -
道具使用菜单区域
与信息区域一样,采用脚本来控制逻辑显示。
道具预制件Item
采用ItemController来绘制当前UI元素。
主要脚本
预制件Item的ItemController脚本
基本思想是通过Init(Model)方法来将Model的值设置为当前UI的各元素(图标,名字,数量)的值。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ItemController : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler//单个道具Ui的逻辑层,包括了渲染和使用
{
public int itemID;
public int count;
public static string iconPath;
public ItemModel item;
public Text nametx;
public Text countText;
public Image bgImg;
public Image icon;
// Start is called before the first frame update
void Start()
{
}
public void Init(PlayerItemModel itemModel)
{
item = JsonDataCenterCL.GetModelById<ItemModel>(itemModel.id);
Sprite sp = Resources.Load(iconPath + item.icon, typeof(Sprite)) as Sprite;
if (sp == null)
{
Debug.LogError("没有找到" + item.icon + "资源");
return;
}
icon.sprite = sp;
itemID = itemModel.id;
count = itemModel.itemCount;
nametx.text = item.name;
countText.text = count.ToString();
}
public void Use()
{
PlayerItemModel itemModel =JsonDataCenterCL.GetModelById<PlayerItemModel>(itemID);
itemModel.itemCount--;
if (itemModel.itemCount <= 0)
{
GameObject.Destroy(gameObject);
return;
}
Init(itemModel);
}
public void OnPointerEnter(PointerEventData e)
{
OnFocusEnter();
}
public void OnPointerExit(PointerEventData e)
{
OnFocusOver();
}
public void OnPointerClick(PointerEventData e)
{
if (!ItemMenuController.instance.gameObject.activeInHierarchy)
ItemMenuController.ShowItemMenu(this);
else
{
ItemMenuController.HideItemMenu();
}
}
#region ui悬停事件
public void OnFocusEnter()
{
BackPackManager.selected = this;
bgImg.color = Color.black;
nametx.color = Color.white;
countText.color = Color.white;
BkInfoPanel.ShowPanel(item.description);
}
public void OnFocusOver()
{
bgImg.color = Color.white;
nametx.color = Color.black;
countText.color = Color.black;
BkInfoPanel.HidePanel();
}
#endregion
}
挂在content上的BackPackController脚本
这个脚本实现把从JsonDataCenter获取的数据生成为UI实体。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BackpackController : MonoBehaviour//挂载在背包面板上
{
public static string itemUIPrefabPath;
GameObject itemUIprefab;
private void Awake()
{
}
private void Start()
{
GameObject go = Resources.Load(itemUIPrefabPath) as GameObject;
if (go == null)
{
Debug.LogError("没有找到预制体:" + itemUIPrefabPath);
return;
}
itemUIprefab = go;
GenerateItemSlotList();//开始时生成所有的道具
}
public void GenerateItemSlot(PlayerItemModel item)//生成单个道具
{
GameObject go = GameObject.Instantiate(itemUIprefab, transform);
go.GetComponent<ItemController>().Init(item);
}
public void GenerateItemSlotList()//生成所有道具
{
Dictionary<int,PlayerItemModel> col=JsonDataCenterCL.GetModelDic<PlayerItemModel>();
foreach (PlayerItemModel im in col.Values)//遍历字典的值
{
GenerateItemSlot(im);
}
}
}