项目02《游戏-07-开发》Unity3D
基于 项目02《游戏-06-开发》Unity3D ,
接下来做UI框架的逻辑系统,管理器和UI背包,
首先闯将UI框架的两个重要脚本 BasePanel.cs 和 UIManager.cs ,
双击BasePanel.cs脚本修改代码:
using UnityEngine;
public class BasePanel : MonoBehaviour{
protected bool isRemove = false;
protected new string name;
protected virtual void Awake() { }
public virtual void SetActive(bool active){
gameObject.SetActive(active);
}
public virtual void OpenPanel(string name){
this.name = name;
SetActive(true);
}
public virtual void ClosePanel(){
isRemove = true;
SetActive(false);
Destroy(gameObject);
//移除缓存 表示界面未打开
if (UIManager.Instance.panelDict.ContainsKey(name))
UIManager.Instance.panelDict.Remove(name);
}
}
双击UIManager.cs脚本修改代码:
using System.Collections.Generic;
using UnityEngine;
public class UIManager{
static UIManager _instance;
Transform _uiRoot;
//路径配置字典
Dictionary<string, string> pathDict;
//预制体缓存字典
Dictionary<string, GameObject> prefabDict;
//已打开界面的缓存字典
public Dictionary<string, BasePanel> panelDict;
public static UIManager Instance{
get{
if (_instance == null)
_instance = new UIManager();
return _instance;
}
}
public Transform UIRoot{
get{
if (_uiRoot == null){
if (GameObject.Find("Canvas"))
_uiRoot = GameObject.Find("Canvas").transform;
else
_uiRoot = new GameObject("Canvas").transform;
};
return _uiRoot;
}
}
UIManager(){
InitDicts();
}
void InitDicts(){
prefabDict = new Dictionary<string, GameObject>();
panelDict = new Dictionary<string, BasePanel>();
pathDict = new Dictionary<string, string>(){
//{ UIConst.PackagePanel,"Package/PackagePanel"},//**
};
}
public BasePanel GetPanel(string name){
BasePanel panel = null;
//检查是否已打开
if (panelDict.TryGetValue(name, out panel))
return panel;
return null;
}
public BasePanel OpenPanel(string name){
BasePanel panel = null;
//检查是否已打开
if (panelDict.TryGetValue(name, out panel)){
Debug.Log($"界面已打开 {name}");
return null;
}
//检查路径是否配置
string path = "";
if (!pathDict.TryGetValue(name, out path)){
Debug.Log($"界面名称错误 或未配置路径 {name}");
return null;
}
//使用缓存的预制体
GameObject panelPrefab = null;
if (!prefabDict.TryGetValue(name, out panelPrefab)){
string realPath = "Prefabs/Panel/" + path;
panelPrefab = Resources.Load<GameObject>(realPath) as GameObject;
prefabDict.Add(name, panelPrefab);
}
//打开界面
GameObject panelObject = GameObject.Instantiate(panelPrefab, UIRoot, false);
panel = panelObject.GetComponent<BasePanel>();
panelDict.Add(name, panel);
panel.OpenPanel(name);
return panel;
}
//关闭界面
public bool ClosePanel(string name){
BasePanel panel = null;
if (!panelDict.TryGetValue(name, out panel)){
Debug.LogError($"界面未打开 {name}");
return false;
}
panel.ClosePanel();
return true;
}
public class UIConst{
//public const string PackagePanel = "PackagePanel";//**
}
}
接下来就是使用这个框架,
首先配置这个框架的常量,在UIManger.cs修改代码:
新增PackagePanel这个常量后,接下来配置这个界面的路径,
整体修改代码为:
using System.Collections.Generic;
using UnityEngine;
public class UIManager{
static UIManager _instance;
Transform _uiRoot;
//路径配置字典
Dictionary<string, string> pathDict;
//预制体缓存字典
Dictionary<string, GameObject> prefabDict;
//已打开界面的缓存字典
public Dictionary<string, BasePanel> panelDict;
public static UIManager Instance{
get{
if (_instance == null)
_instance = new UIManager();
return _instance;
}
}
public Transform UIRoot{
get{
if (_uiRoot == null){
if (GameObject.Find("Canvas"))
_uiRoot = GameObject.Find("Canvas").transform;
else
_uiRoot = new GameObject("Canvas").transform;
};
return _uiRoot;
}
}
UIManager(){
InitDicts();
}
void InitDicts(){
prefabDict = new Dictionary<string, GameObject>();
panelDict = new Dictionary<string, BasePanel>();
pathDict = new Dictionary<string, string>(){
{ UIConst.PackagePanel,"Package/PackagePanel"},//**
};
}
public BasePanel GetPanel(string name){
BasePanel panel = null;
//检查是否已打开
if (panelDict.TryGetValue(name, out panel))
return panel;
return null;
}
public BasePanel OpenPanel(string name){
BasePanel panel = null;
//检查是否已打开
if (panelDict.TryGetValue(name, out panel)){
Debug.Log($"界面已打开 {name}");
return null;
}
//检查路径是否配置
string path = "";
if (!pathDict.TryGetValue(name, out path)){
Debug.Log($"界面名称错误 或未配置路径 {name}");
return null;
}
//使用缓存的预制体
GameObject panelPrefab = null;
if (!prefabDict.TryGetValue(name, out panelPrefab)){
string realPath = "Prefabs/Panel/" + path;
panelPrefab = Resources.Load<GameObject>(realPath) as GameObject;
prefabDict.Add(name, panelPrefab);
}
//打开界面
GameObject panelObject = GameObject.Instantiate(panelPrefab, UIRoot, false);
panel = panelObject.GetComponent<BasePanel>();
panelDict.Add(name, panel);
panel.OpenPanel(name);
return panel;
}
//关闭界面
public bool ClosePanel(string name){
BasePanel panel = null;
if (!panelDict.TryGetValue(name, out panel)){
Debug.LogError($"界面未打开 {name}");
return false;
}
panel.ClosePanel();
return true;
}
public class UIConst{
//配置常量
public const string PackagePanel = "PackagePanel";//**
}
}
回到unity编辑器中新创建一个脚本文件,PackagePanel.cs脚本,
功能是处理背包界面相关的逻辑处理,
双击PackagPanel.cs脚本修改代码:
它是继承BasePanel.cs脚本的,具体逻辑先不写,
public class PackagePanel : BasePanel{
}
保存后绑定在unity编辑器中的PackagePanel对象身上,
为了测试背包数据是否正确运行,
我们需要在修改器GMCmd.cs脚本中添加一个打开背包界面的方法,
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using static UIManager;
public class GMCmd{
[MenuItem("CMCmd/读取表格")]
public static void ReadTable(){
PackageTable packageTable = Resources.Load<PackageTable>("TableData/PackageTable");
foreach (PackageTableItem packageItem in packageTable.dataList)
Debug.Log(string.Format($"[id] {packageItem.id} [name] {packageItem.name}"));
}
[MenuItem("CMCmd/创建背包测试数据")]
public static void CreateLocalPackageData(){
//保存数据
PackageLocalData.Instance.items = new List<PackageLocalItem>();
for (int i = 1; i < 9; i++){
PackageLocalItem packageLocalItem = new(){
uid = Guid.NewGuid().ToString(),
id = i,
num = i,
level = i,
isNew = i % 2 == i
};
PackageLocalData.Instance.items.Add(packageLocalItem);
}
PackageLocalData.Instance.SavaPackage();
}
[MenuItem("CMCmd/读取背包测试数据")]
public static void ReadLocalPackageData(){
//读取数据
List<PackageLocalItem> readItems = PackageLocalData.Instance.LoadPackage();
foreach (PackageLocalItem item in readItems)
Debug.Log(item);
}
[MenuItem("CMCmd/打开背包主界面")]
public static void OpenPackagePanel(){
UIManager.Instance.OpenPanel(UIConst.PackagePanel);
}
}
回到unity编辑器中,先把PackagePanel保存在预制体中,然后选择隐藏PackagePanel对象,
运行项目点击修改器GMCmd打开背包即可实现背包的打开,
这样框架已经初步完成,下面开始界面初始化,
界面初始化的第一步就是拿到这些东西,首先在PackagePanel.cs脚本中属性初始化,
using UnityEngine;
using UnityEngine.UI;
public class PackagePanel : BasePanel{
Transform UIMenu;
Transform UIMenuWeapon;
Transform UIMenuFood;
Transform UITabName;
Transform UICloseBtn;
Transform UICenter;
Transform UIScrollView;
Transform UIDetailPanel;
Transform UILeftBtn;
Transform UIRightBtn;
Transform UIDeletePanel;
Transform UIDeleteBackBtn;
Transform UIDeleteInfoText;
Transform UIDeleteConfirmBtn;
Transform UIBottomMenus;
Transform UIDeleteBtn;
Transform UIDetailBtn;
override protected void Awake(){
base.Awake();
InitUI();
}
void InitUI(){
InitUIName();
InitClick();
}
void InitUIName(){
UIMenu = transform.Find("TopCenter/Menu");
UIMenuWeapon = transform.Find("TopCenter/Menus/Weapon");
UIMenuFood = transform.Find("TopCenter/Menus/Food");
UITabName = transform.Find("LeftTop/TabName");
UICloseBtn = transform.Find("RightTop/Close");
UICenter = transform.Find("Center");
UIScrollView = transform.Find("Center/Scroll View");
UIDetailPanel = transform.Find("Center/DetailPanel");
UILeftBtn = transform.Find("Left/Button");
UIRightBtn = transform.Find("Right/Button");
UIDeletePanel = transform.Find("Bottom/DeletePanel");
UIDeleteBackBtn = transform.Find("Bottom/DeletePanel/Back");
UIDeleteInfoText = transform.Find("Bottom/DeletePanel/InfoText");
UIDeleteConfirmBtn = transform.Find("Bottom/DeletePanel/ConfirmBtn");
UIBottomMenus = transform.Find("Bottom/BottomMenus");
UIDeleteBtn = transform.Find("Bottom/BottomMenus/DeleteBtn");
UIDetailBtn = transform.Find("Bottom/BottomMenus/DetailBtn");
UIDeletePanel.gameObject.SetActive(false);
UIBottomMenus.gameObject.SetActive(true);
}
void InitClick(){
UIMenuWeapon.GetComponent<Button>().onClick.AddListener(OnClickWeapon);
UIMenuFood.GetComponent<Button>().onClick.AddListener(OnClickFood);
UICloseBtn.GetComponent<Button>().onClick.AddListener(OnClickClose);
UILeftBtn.GetComponent<Button>().onClick.AddListener(OnClickLeft);
UIRightBtn.GetComponent<Button>().onClick.AddListener(OnClickRight);
UIDeleteBackBtn.GetComponent<Button>().onClick.AddListener(OnDeleteBack);
UIDeleteConfirmBtn.GetComponent<Button>().onClick.AddListener(OnDeleteConfirm);
UIDeleteBtn.GetComponent<Button>().onClick.AddListener(OnDelete);
UIDetailBtn.GetComponent<Button>().onClick.AddListener(OnDetail);
}
void OnDetail(){
print(">>>>>>> OnDetail()");
}
void OnDelete(){
print(">>>>>>> OnDelete()");
}
void OnDeleteConfirm(){
print(">>>>>>> OnDeleteConfirm()");
}
void OnDeleteBack(){
print(">>>>>>> OnDeleteBack()");
}
void OnClickRight(){
print(">>>>>>> OnClickRight()");
}
void OnClickLeft(){
print(">>>>>>> OnClickLeft()");
}
void OnClickWeapon(){
print(">>>>>>> OnClickWeapon()");
}
void OnClickFood(){
print(">>>>>>> OnClickFood()");
}
void OnClickClose(){
print(">>>>>>> OnClickClose()");
ClosePanel();
}
}
接下来添加脚本PackageCell.cs脚本用来处理具体道具,
双击PackageCell.cs脚本修改代码:
using UnityEngine;
public class PackageCell : MonoBehaviour{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
PackageLocalItem packageLocalData;
PackageTableItem packageTableItem;
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
UIDeleteSelect.gameObject.SetActive(false);
}
}
保存代码将PackageCell.cs脚本绑定在unity编辑器的PackageItem对象身上,
解压缩PackagePanel,将PackagePanel对象和PackageItem对象重新放入自己的预制体包中,
检查层级是否正确,
检查是否按键都添加了Button按钮,
回到unity场景中重设PackagePanel对象和PackageItem对象的预制体,
运行项目,打开背包界面,如果没有报错,证明已成功连接,
接下来做控制器逻辑,
也就是说取到动态数据,再配合静态数据,对滚动容器进行初始化,
所以现在要做的就是获取数据,
我们采用一个中间管理器来统一处理这些数据,
修改MainGame.cs脚本:
using System.Collections.Generic;
using UnityEngine;
using static UIManager;
public class MainGame : MonoBehaviour{
public static Player player;
void Awake(){
player = GameObject.Find("Player").GetComponent<Player>();
//背包系统
_instance = this;
DontDestroyOnLoad(gameObject);
}
//背包系统
static MainGame _instance;
PackageTable packageTable;
public static MainGame Instance{
get{
return _instance;
}
}
void Start(){
UIManager.Instance.OpenPanel(UIConst.PackagePanel);
}
//对静态数据加载
public PackageTable GetPackageTable(){
if (packageTable == null)
packageTable = Resources.Load<PackageTable>("TableData/PackageTable");
return packageTable;
}
//对动态数据加载
public List<PackageLocalItem> GetPackageLocalData(){
return PackageLocalData.Instance.LoadPackage();
}
//根据ID去表格中拿到指定的数据
public PackageTableItem GetPackageItemById(int id){
List<PackageTableItem> packageDataList = GetPackageTable().dataList;
foreach (PackageTableItem item in packageDataList){
if (item.id == id)
return item;
}
return null;
}
//根据uid去本地数据中拿到动态数据
public PackageLocalItem GetPackageLocalItemByUId(string uid){
List<PackageLocalItem> packageDataList = GetPackageLocalData();
foreach (PackageLocalItem item in packageDataList){
if (item.uid == uid)
return item;
}
return null;
}
public List<PackageLocalItem> GetSortPackageLocalData(){
List<PackageLocalItem> localItems = PackageLocalData.Instance.LoadPackage();
//localItems.Sort(new PackageItemComparer());
return localItems;
}
public class PackageItemComparer : IComparer<PackageLocalItem>{
public int Compare(PackageLocalItem a, PackageLocalItem b){
PackageTableItem x = MainGame.Instance.GetPackageItemById(a.id);
PackageTableItem y = MainGame.Instance.GetPackageItemById(b.id);
//首先按star从大到小排序
int starComparison = y.star.CompareTo(x.star);
//如果star相同,则按id从大到小排序
if (starComparison == 0){
int idComparison = y.id.CompareTo(x.id);
if (idComparison == 0)
return b.level.CompareTo(a.level);
return idComparison;
}
return starComparison;
}
}
}
修改PackagePanel.cs脚本:添加一个子物体的预制体,
这样在PackagePanel预制体中就可以看到一个公开的属性,
我们将PackageItem预制体拖拽进去,
下一步是添加背包页面PackagePanel.cs的背包滚动容器部分,
把这部分逻辑添加在Start()函数中,
再添加两个方法,
具体代码如下:
using UnityEngine;
using UnityEngine.UI;
public class PackagePanel : BasePanel{
Transform UIMenu;
Transform UIMenuWeapon;
Transform UIMenuFood;
Transform UITabName;
Transform UICloseBtn;
Transform UICenter;
Transform UIScrollView;
Transform UIDetailPanel;
Transform UILeftBtn;
Transform UIRightBtn;
Transform UIDeletePanel;
Transform UIDeleteBackBtn;
Transform UIDeleteInfoText;
Transform UIDeleteConfirmBtn;
Transform UIBottomMenus;
Transform UIDeleteBtn;
Transform UIDetailBtn;
//添加
public GameObject PackageUIItemPrefab;
override protected void Awake(){
base.Awake();
InitUI();
}
//添加1
void Start(){
RefreshUI();
}
//添加1
void RefreshUI(){
RefreshScroll();
}
//添加1
void RefreshScroll(){
//清理滚动容器中原本的物品
RectTransform scrollContent = UIScrollView.GetComponent<ScrollRect>().content;
for (int i = 0; i < scrollContent.childCount; i++)
Destroy(scrollContent.GetChild(i).gameObject);
//获取本地数据的方法拿到自己身上背包数据 并且根据背包数据初始化滚动容器
foreach (PackageLocalItem localData in MainGame.Instance.GetSortPackageLocalData()){
Transform PackageUIItem = Instantiate(PackageUIItemPrefab.transform, scrollContent) as Transform;
PackageCell packageCell = PackageUIItem.GetComponent<PackageCell>();
//packageCell.Refresh(localData, this);
}
}
void InitUI(){
InitUIName();
InitClick();
}
void InitUIName(){
UIMenu = transform.Find("TopCenter/Menu");
UIMenuWeapon = transform.Find("TopCenter/Menus/Weapon");
UIMenuFood = transform.Find("TopCenter/Menus/Food");
UITabName = transform.Find("LeftTop/TabName");
UICloseBtn = transform.Find("RightTop/Close");
UICenter = transform.Find("Center");
UIScrollView = transform.Find("Center/Scroll View");
UIDetailPanel = transform.Find("Center/DetailPanel");
UILeftBtn = transform.Find("Left/Button");
UIRightBtn = transform.Find("Right/Button");
UIDeletePanel = transform.Find("Bottom/DeletePanel");
UIDeleteBackBtn = transform.Find("Bottom/DeletePanel/Back");
UIDeleteInfoText = transform.Find("Bottom/DeletePanel/InfoText");
UIDeleteConfirmBtn = transform.Find("Bottom/DeletePanel/ConfirmBtn");
UIBottomMenus = transform.Find("Bottom/BottomMenus");
UIDeleteBtn = transform.Find("Bottom/BottomMenus/DeleteBtn");
UIDetailBtn = transform.Find("Bottom/BottomMenus/DetailBtn");
UIDeletePanel.gameObject.SetActive(false);
UIBottomMenus.gameObject.SetActive(true);
}
void InitClick(){
UIMenuWeapon.GetComponent<Button>().onClick.AddListener(OnClickWeapon);
UIMenuFood.GetComponent<Button>().onClick.AddListener(OnClickFood);
UICloseBtn.GetComponent<Button>().onClick.AddListener(OnClickClose);
UILeftBtn.GetComponent<Button>().onClick.AddListener(OnClickLeft);
UIRightBtn.GetComponent<Button>().onClick.AddListener(OnClickRight);
UIDeleteBackBtn.GetComponent<Button>().onClick.AddListener(OnDeleteBack);
UIDeleteConfirmBtn.GetComponent<Button>().onClick.AddListener(OnDeleteConfirm);
UIDeleteBtn.GetComponent<Button>().onClick.AddListener(OnDelete);
UIDetailBtn.GetComponent<Button>().onClick.AddListener(OnDetail);
}
void OnDetail(){
print(">>>>>>> OnDetail()");
}
void OnDelete(){
print(">>>>>>> OnDelete()");
}
void OnDeleteConfirm(){
print(">>>>>>> OnDeleteConfirm()");
}
void OnDeleteBack(){
print(">>>>>>> OnDeleteBack()");
}
void OnClickRight(){
print(">>>>>>> OnClickRight()");
}
void OnClickLeft(){
print(">>>>>>> OnClickLeft()");
}
void OnClickWeapon(){
print(">>>>>>> OnClickWeapon()");
}
void OnClickFood(){
print(">>>>>>> OnClickFood()");
}
void OnClickClose(){
print(">>>>>>> OnClickClose()");
ClosePanel();
}
}
回到unity编辑器中,运行项目可见背包出现8个道具说明背包数量初始化成功,
修改PackageCell.cs脚本,
using UnityEngine;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
UIDeleteSelect.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
}
最后总结代码:
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using static UIManager;
public class GMCmd{
[MenuItem("CMCmd/读取表格")]
public static void ReadTable(){
PackageTable packageTable = Resources.Load<PackageTable>("TableData/PackageTable");
foreach (PackageTableItem packageItem in packageTable.dataList)
Debug.Log(string.Format($"[id] {packageItem.id} [name] {packageItem.name}"));
}
[MenuItem("CMCmd/创建背包测试数据")]
public static void CreateLocalPackageData(){
//保存数据
PackageLocalData.Instance.items = new List<PackageLocalItem>();
for (int i = 1; i < 9; i++){
PackageLocalItem packageLocalItem = new(){
uid = Guid.NewGuid().ToString(),
id = i,
num = i,
level = i,
isNew = i % 2 == i
};
PackageLocalData.Instance.items.Add(packageLocalItem);
}
PackageLocalData.Instance.SavaPackage();
}
[MenuItem("CMCmd/读取背包测试数据")]
public static void ReadLocalPackageData(){
//读取数据
List<PackageLocalItem> readItems = PackageLocalData.Instance.LoadPackage();
foreach (PackageLocalItem item in readItems)
Debug.Log(item);
}
[MenuItem("CMCmd/打开背包主界面")]
public static void OpenPackagePanel(){
UIManager.Instance.OpenPanel(UIConst.PackagePanel);
}
}
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Water/PackageTable", fileName = "PackageTable")]
public class PackageTable : ScriptableObject{
public List<PackageTableItem> dataList = new List<PackageTableItem>();
}
[System.Serializable]
public class PackageTableItem{
public int id;
public int type;
public int star;
public string name;
public string description;
public string skillDescription;
public string imagePath;
}
using UnityEngine;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
UIDeleteSelect.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
}
using UnityEngine;
using UnityEngine.UI;
public class PackagePanel : BasePanel{
Transform UIMenu;
Transform UIMenuWeapon;
Transform UIMenuFood;
Transform UITabName;
Transform UICloseBtn;
Transform UICenter;
Transform UIScrollView;
Transform UIDetailPanel;
Transform UILeftBtn;
Transform UIRightBtn;
Transform UIDeletePanel;
Transform UIDeleteBackBtn;
Transform UIDeleteInfoText;
Transform UIDeleteConfirmBtn;
Transform UIBottomMenus;
Transform UIDeleteBtn;
Transform UIDetailBtn;
//添加
public GameObject PackageUIItemPrefab;
override protected void Awake(){
base.Awake();
InitUI();
}
//添加1
void Start(){
RefreshUI();
}
//添加1
void RefreshUI(){
RefreshScroll();
}
//添加1
void RefreshScroll(){
//清理滚动容器中原本的物品
RectTransform scrollContent = UIScrollView.GetComponent<ScrollRect>().content;
for (int i = 0; i < scrollContent.childCount; i++)
Destroy(scrollContent.GetChild(i).gameObject);
//获取本地数据的方法拿到自己身上背包数据 并且根据背包数据初始化滚动容器
foreach (PackageLocalItem localData in MainGame.Instance.GetSortPackageLocalData()){
Transform PackageUIItem = Instantiate(PackageUIItemPrefab.transform, scrollContent) as Transform;
PackageCell packageCell = PackageUIItem.GetComponent<PackageCell>();
//添加2
packageCell.Refresh(localData, this);
}
}
void InitUI(){
InitUIName();
InitClick();
}
void InitUIName(){
UIMenu = transform.Find("TopCenter/Menu");
UIMenuWeapon = transform.Find("TopCenter/Menus/Weapon");
UIMenuFood = transform.Find("TopCenter/Menus/Food");
UITabName = transform.Find("LeftTop/TabName");
UICloseBtn = transform.Find("RightTop/Close");
UICenter = transform.Find("Center");
UIScrollView = transform.Find("Center/Scroll View");
UIDetailPanel = transform.Find("Center/DetailPanel");
UILeftBtn = transform.Find("Left/Button");
UIRightBtn = transform.Find("Right/Button");
UIDeletePanel = transform.Find("Bottom/DeletePanel");
UIDeleteBackBtn = transform.Find("Bottom/DeletePanel/Back");
UIDeleteInfoText = transform.Find("Bottom/DeletePanel/InfoText");
UIDeleteConfirmBtn = transform.Find("Bottom/DeletePanel/ConfirmBtn");
UIBottomMenus = transform.Find("Bottom/BottomMenus");
UIDeleteBtn = transform.Find("Bottom/BottomMenus/DeleteBtn");
UIDetailBtn = transform.Find("Bottom/BottomMenus/DetailBtn");
UIDeletePanel.gameObject.SetActive(false);
UIBottomMenus.gameObject.SetActive(true);
}
void InitClick(){
UIMenuWeapon.GetComponent<Button>().onClick.AddListener(OnClickWeapon);
UIMenuFood.GetComponent<Button>().onClick.AddListener(OnClickFood);
UICloseBtn.GetComponent<Button>().onClick.AddListener(OnClickClose);
UILeftBtn.GetComponent<Button>().onClick.AddListener(OnClickLeft);
UIRightBtn.GetComponent<Button>().onClick.AddListener(OnClickRight);
UIDeleteBackBtn.GetComponent<Button>().onClick.AddListener(OnDeleteBack);
UIDeleteConfirmBtn.GetComponent<Button>().onClick.AddListener(OnDeleteConfirm);
UIDeleteBtn.GetComponent<Button>().onClick.AddListener(OnDelete);
UIDetailBtn.GetComponent<Button>().onClick.AddListener(OnDetail);
}
void OnDetail(){
print(">>>>>>> OnDetail()");
}
void OnDelete(){
print(">>>>>>> OnDelete()");
}
void OnDeleteConfirm(){
print(">>>>>>> OnDeleteConfirm()");
}
void OnDeleteBack(){
print(">>>>>>> OnDeleteBack()");
}
void OnClickRight(){
print(">>>>>>> OnClickRight()");
}
void OnClickLeft(){
print(">>>>>>> OnClickLeft()");
}
void OnClickWeapon(){
print(">>>>>>> OnClickWeapon()");
}
void OnClickFood(){
print(">>>>>>> OnClickFood()");
}
void OnClickClose(){
print(">>>>>>> OnClickClose()");
ClosePanel();
}
}
using System.Collections.Generic;
using UnityEngine;
public class UIManager{
static UIManager _instance;
Transform _uiRoot;
//路径配置字典
Dictionary<string, string> pathDict;
//预制体缓存字典
Dictionary<string, GameObject> prefabDict;
//已打开界面的缓存字典
public Dictionary<string, BasePanel> panelDict;
public static UIManager Instance{
get{
if (_instance == null)
_instance = new UIManager();
return _instance;
}
}
public Transform UIRoot{
get{
if (_uiRoot == null){
if (GameObject.Find("Canvas"))
_uiRoot = GameObject.Find("Canvas").transform;
else
_uiRoot = new GameObject("Canvas").transform;
};
return _uiRoot;
}
}
UIManager(){
InitDicts();
}
void InitDicts(){
prefabDict = new Dictionary<string, GameObject>();
panelDict = new Dictionary<string, BasePanel>();
pathDict = new Dictionary<string, string>(){
{ UIConst.PackagePanel,"Package/PackagePanel"},//**
};
}
public BasePanel GetPanel(string name){
BasePanel panel = null;
//检查是否已打开
if (panelDict.TryGetValue(name, out panel))
return panel;
return null;
}
public BasePanel OpenPanel(string name){
BasePanel panel = null;
//检查是否已打开
if (panelDict.TryGetValue(name, out panel)){
Debug.Log($"界面已打开 {name}");
return null;
}
//检查路径是否配置
string path = "";
if (!pathDict.TryGetValue(name, out path)){
Debug.Log($"界面名称错误 或未配置路径 {name}");
return null;
}
//使用缓存的预制体
GameObject panelPrefab = null;
if (!prefabDict.TryGetValue(name, out panelPrefab)){
string realPath = "Prefabs/Panel/" + path;
panelPrefab = Resources.Load<GameObject>(realPath) as GameObject;
prefabDict.Add(name, panelPrefab);
}
//打开界面
GameObject panelObject = GameObject.Instantiate(panelPrefab, UIRoot, false);
panel = panelObject.GetComponent<BasePanel>();
panelDict.Add(name, panel);
panel.OpenPanel(name);
return panel;
}
//关闭界面
public bool ClosePanel(string name){
BasePanel panel = null;
if (!panelDict.TryGetValue(name, out panel)){
Debug.LogError($"界面未打开 {name}");
return false;
}
panel.ClosePanel();
return true;
}
public class UIConst{
//配置常量
public const string PackagePanel = "PackagePanel";//**
}
}
using System.Collections.Generic;
using UnityEngine;
using static UIManager;
public class MainGame : MonoBehaviour{
public static Player player;
void Awake(){
player = GameObject.Find("Player").GetComponent<Player>();
//背包系统
_instance = this;
DontDestroyOnLoad(gameObject);
}
//背包系统
static MainGame _instance;
PackageTable packageTable;
public static MainGame Instance{
get{
return _instance;
}
}
void Start(){
UIManager.Instance.OpenPanel(UIConst.PackagePanel);
}
//对静态数据加载
public PackageTable GetPackageTable(){
if (packageTable == null)
packageTable = Resources.Load<PackageTable>("TableData/PackageTable");
return packageTable;
}
//对动态数据加载
public List<PackageLocalItem> GetPackageLocalData(){
return PackageLocalData.Instance.LoadPackage();
}
//根据ID去表格中拿到指定的数据
public PackageTableItem GetPackageItemById(int id){
List<PackageTableItem> packageDataList = GetPackageTable().dataList;
foreach (PackageTableItem item in packageDataList){
if (item.id == id)
return item;
}
return null;
}
//根据uid去本地数据中拿到动态数据
public PackageLocalItem GetPackageLocalItemByUId(string uid){
List<PackageLocalItem> packageDataList = GetPackageLocalData();
foreach (PackageLocalItem item in packageDataList){
if (item.uid == uid)
return item;
}
return null;
}
public List<PackageLocalItem> GetSortPackageLocalData(){
List<PackageLocalItem> localItems = PackageLocalData.Instance.LoadPackage();
localItems.Sort(new PackageItemComparer());//添加
return localItems;
}
public class PackageItemComparer : IComparer<PackageLocalItem>{
public int Compare(PackageLocalItem a, PackageLocalItem b){
PackageTableItem x = MainGame.Instance.GetPackageItemById(a.id);
PackageTableItem y = MainGame.Instance.GetPackageItemById(b.id);
//首先按star从大到小排序
int starComparison = y.star.CompareTo(x.star);
//如果star相同,则按id从大到小排序
if (starComparison == 0){
int idComparison = y.id.CompareTo(x.id);
if (idComparison == 0)
return b.level.CompareTo(a.level);
return idComparison;
}
return starComparison;
}
}
}
using System.Collections.Generic;
using UnityEngine;
public class PackageLocalData{
static PackageLocalData _instance;
public static PackageLocalData Instance{
get{
if (_instance == null)
_instance = new PackageLocalData();
return _instance;
}
}
//存
public List<PackageLocalItem> items;
public void SavaPackage(){
string inventoryJson = JsonUtility.ToJson(this);
PlayerPrefs.SetString("PackageLocalData", inventoryJson);
PlayerPrefs.Save();
}
//取
public List<PackageLocalItem> LoadPackage(){
if (items != null)
return items;
if (PlayerPrefs.HasKey("PackageLocalData")){
string inventoryJson = PlayerPrefs.GetString("PackageLocalData");
PackageLocalData packageLocalData = JsonUtility.FromJson<PackageLocalData>(inventoryJson);
items = packageLocalData.items;
return items;
}
else{
items = new List<PackageLocalItem>();
return items;
}
}
}
[System.Serializable]
public class PackageLocalItem{
public string uid;
public int id;
public int num;
public int level;
public bool isNew;
public override string ToString(){
return string.Format($"[id] {id} [num] {num}");
}
}
using UnityEngine;
public class BasePanel : MonoBehaviour{
protected bool isRemove = false;
protected new string name;
protected virtual void Awake() { }
public virtual void SetActive(bool active){
gameObject.SetActive(active);
}
public virtual void OpenPanel(string name){
this.name = name;
SetActive(true);
}
public virtual void ClosePanel(){
isRemove = true;
SetActive(false);
Destroy(gameObject);
//移除缓存 表示界面未打开
if (UIManager.Instance.panelDict.ContainsKey(name))
UIManager.Instance.panelDict.Remove(name);
}
}
修改PackageTable组件武器编号:
运行项目即实现,
End.