原文链接:https://www.cnblogs.com/xinzhilinger/p/14654454.html
在学习的过程中呢,也比较局域懒,没有去做素材的整理,所以在照着写的过程中,部分还是改成了自己的有的元件。
好吧,不多废话了,直接开始吧。
文件结构
实现效果
首先呢,先做本地数据库,2个配置脚本,要注意脚本名的匹配
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName ="New Item",menuName ="Bag/New Item")]
public class Item : ScriptableObject
{
//物体名、需要在UI中显示的图片、持有物体的数量、物体信息的描述
public string itemName;
public Sprite itemImage;
public int itemNum;
[TextArea] //改变输入框格式,提示输入框容量
public string itemInfo;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName ="New MainItem",menuName ="Bag/New MainItem")]
public class MainItem : ScriptableObject
{
public List<Item> itemList=new List<Item>();
}
这个就是使用这个代码建的
ok,那么接下来就是放数据了,点开这两个,然后按照数据类型输入正常的测试数据就行了,效果如下图
预制件类,本意就是直接获取当前预制件的控件,这个挂在做好的ui图标上,预制件就是image+text的简单组合,至于sprite的变化,就直接在之前的数据库中来配置,想配什么样子的就拖什么样子的
public class Grid : MonoBehaviour
{
// Start is called before the first frame update
public Image gridImage;
public Text girdNum;
}
接下来就是重头戏了,ui的控制脚本,这里的单例没有用单例基类来做封装,所以就是直接一个静态类来做调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class uimanager : MonoBehaviour
{
// Start is called before the first frame update
bool isPlay;
public GameObject myBagUI;
void Start()
{
isPlay=false;
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.B))
{
isPlay = !isPlay;
myBagUI.SetActive(isPlay);
}
ui_contorl();
}
public Item item;
//背包的数据仓库
public MainItem mainItem;
private void ui_contorl()
{
if(Input.GetKeyDown("a")){
if(!mainItem.itemList.Contains(item))
{
mainItem.itemList.Add(item);
}
item.itemNum += 1;
BagDisplayUI.updateItemToUI();
}
if(Input.GetKeyDown("s")){
if(!mainItem.itemList.Contains(item))
{
mainItem.itemList.Add(item);
}
item.itemNum --;
BagDisplayUI.updateItemToUI();
}
}
}
控制ui的脚本,原理上就是不停的创建与删除当前ui
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BagDisplayUI : MonoBehaviour
{
//单例模式
static BagDisplayUI bagDisplayUI;
private void Awake()
{
if(bagDisplayUI!=null)
{
Destroy(this);
}
bagDisplayUI = this;
}
//每次游戏启动前,动态的更新背包UI元素
private void OnEnable()
{
updateItemToUI();
}
//背包数据仓库、格子中物体预制体、和UI中显示物体元素的父元素
public MainItem mainItem;
public GameObject gridPrefab;
public GameObject myBag;
/// <summary>
/// 在UI中将一个物体的数据仓库显示出来
/// </summary>
/// <param name="item"></param>
public static void insertItemToUI(Item item)
{
if(item.itemNum<=0){
return ;
}
GameObject grid = Instantiate(bagDisplayUI.gridPrefab, bagDisplayUI.myBag.transform);
grid.GetComponent<Grid>().gridImage.sprite = item.itemImage;
grid.GetComponent<Grid>().girdNum.text = item.itemNum.ToString();
}
/// <summary>
/// 将背包数据仓库中所有物体显示在UI上
/// </summary>
public static void updateItemToUI()
{
for (int i = 0; i < bagDisplayUI.myBag.transform.childCount; i++)
{
Destroy(bagDisplayUI.myBag.transform.GetChild(i).gameObject);
}
for (int i = 0; i < bagDisplayUI.mainItem.itemList.Count; i++)
{
insertItemToUI(bagDisplayUI.mainItem.itemList[i]);
}
}
}
创建好后进行挂载,把每个属性对应好就能用,mybag是ui的放置控件图层
挂好以后就能直接跑了,如果有不对的地方么,自己再手动调整,调成合适自己的代码
总结
上述代码里,缺点也很明显
1.单例没有用基类来做
2.本地数据库配置需要手动配就很烦
解决方案
1.所以后面耦合到其他代码里的时候会加个基类
2.后续配置上学习excel来做配置,实现unity自动读表,自动生成代码,自动生成本地数据库