一、UGUI背包系统展示##
二、背包系统的搭建##
三、加载预支物的制作##
通过按键模拟拾取物品的代码:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class KnapsackManager : MonoBehaviour
{
public static Dictionary<int, BaseItem> ItemList;//用键值对承储信息
GameObject item;//实例化的物体
public GameObject[] Cells;//获取格子信息
Image imagesingle;//获取预支物身上的图片
Text textNum;//获取预支物子物体的文字显示信息
int textInt;//承储变量
public GameObject PoolCanvas;
void Awake()
{
Load();//加载
}
void Start()
{
}
void Update()
{
if (Input.GetKeyDown(KeyCode.X))//通过按下X键模拟拾取物品
{
int index = Random.Range(0, 5);
Pickup(ItemList[index]);
//print(index);
}
}
private void Load()//加载需要的资源,如果过多需要保存在数据库。
{
ItemList = new Dictionary<int, BaseItem>();
Weapons sword_blade = new Weapons(0, "魔剑", "最厉害的魔剑", 20000, 12000, "Pictures/blade_sword", 280);
Weapons sword_blood = new Weapons(1, "嗜血剑", "偷取敌人10%生命值的嗜血剑", 18000, 9000, "Pictures/blood_sword", 250);
Weapons sword_double = new Weapons(2, "重影剑", "每次攻击都会有几率出现攻击了2次的重影剑", 22000, 13000, "Pictures/double_sword", 300);
Consumables HP_back = new Consumables(3, "诺顿的血药", "立马回复生命值100", 5, 3, "Pictures/add_HP", 100, 0);
Consumables Mp_back = new Consumables(4, "诺顿的大蓝药", "立马回复蓝量100", 4, 2, "Pictures/add_MP", 0, 100);
ItemList.Add(sword_blade.ID, sword_blade);
ItemList.Add(sword_blood.ID, sword_blood);
ItemList.Add(sword_double.ID, sword_double);
ItemList.Add(HP_back.ID, HP_back);
ItemList.Add(Mp_back.ID, Mp_back);
}
public void Pickup(BaseItem baseItem)
{
bool isFind = false;
//实例化物体
//item = Instantiate(Resources.Load("Prefabs/Item"), transform.position, transform.rotation) as GameObject;
item = PoolManager.Get("Item", transform.position, transform.rotation) as GameObject;//通过对象池来实现物体的创建与回收
imagesingle = item.transform.GetComponent<Image>();//获取实例化物体的图片信息
//imagesingle.overrideSprite = Resources.Load("Pictres/blade_sword",typeof(Sprite));
imagesingle.overrideSprite = Resources.Load(baseItem.Icon, typeof(Sprite)) as Sprite;//找到对应的物体名字
for (int i = 0; i < Cells.Length; i++)
{
if (Cells[i].transform.childCount > 0)
{
//如果格子里面有物体,下标进行数据管理
if (imagesingle.overrideSprite.name == Cells[i].transform.GetChild(0).transform.GetComponent<Image>().overrideSprite.name)
{
isFind = true;
textNum = Cells[i].transform.GetChild(0).transform.GetChild(0).GetComponent<Text>();
textInt = int.Parse(textNum.text);
textInt += 1;
textNum.text = textInt.ToString();//实现了获取相同物品,下标相应变化过程
//Destroy(item);
// PoolManager.Return(item);
StartCoroutine(ReturnToPoll());
item.transform.SetParent(PoolCanvas.transform);
break;
}
}
}
if (isFind == false)
{
for (int i = 0; i < Cells.Length; i++)
{
if (Cells[i].transform.childCount == 0)
{
item.transform.SetParent(Cells[i].transform);
item.transform.localPosition = Vector3.zero;
//保留格子;
StorItem.Store(Cells[i].transform.name, baseItem);//把格子保留到商店里面去,还有物品
print(Cells[i].transform.name);
print(baseItem.Description);
break;
}
}
}
}
IEnumerator ReturnToPoll()
{
yield return new WaitForSeconds(0.0f);
PoolManager.Return(item);
}
}
四、预支物基类的建立以及各种相应的类处理##
基类的建立:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BaseItem {
public int ID {
get;
private set;
}
public string Name {
get;
private set;
}
public string Description
{
get;
private set;
}
public int BuyPrice {
get;
private set;
}
public int SellPrice {
get;
private set;
}
public string Icon {
get;
private set;
}
public BaseItem(int id,string name,string description,int buyPrice,int sellPrice,string icon)
{
this.ID = id;
this.Name = name;
this.Description = description;
this.BuyPrice = buyPrice;
this.SellPrice = sellPrice;
this.Icon = icon;
}
}
防具类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Armors : BaseItem {
public int Defense {
get;
private set;
}
public Armors(int id, string name, string description, int buyPrice, int sellPrice, string icon, int defense) : base(id, name, description, buyPrice, sellPrice, icon)
{
this.Defense = defense;
}
}
武器类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapons : BaseItem {
public int Attack {
get;
private set;
}
public Weapons(int id, string name, string description, int buyPrice, int sellPrice, string icon,int attack):base(id,name,description,buyPrice,sellPrice,icon)
{
this.Attack = attack;
}
}
消耗品类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Consumables :BaseItem {
public int BackHP {
get;
private set;
}
public int BackMP {
get;
private set;
}
public Consumables(int id, string name, string description, int buyPrice, int sellPrice, string icon,int backHP,int backMP) : base(id, name, description, buyPrice, sellPrice, icon)
{
this.BackHP = backHP;
this.BackMP = backMP;
}
}
五、物品(预支物)之间的拖拽交换实现##
1.给预支物添加拖拽脚本,以及实现各种交换功能.
2.给格子,和预支物添加Tag值以便进行交换处理.
3.添加CanvasGroup防止射线检测正确的物体.
交换逻辑代码处理:
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine;
using System;
public class DragMove : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{
GameObject PoolCanvas = null;//用来管理生成物体
GameObject Instead_gameObject = null;//交换变量
//交换物品,格子里面的信息
BaseItem item;
BaseItem itemInstead;
void start()
{
PoolCanvas = GameObject.Find("Knapsack").transform.Find("PoolCanvas").gameObject;
print(PoolCanvas.name+"123");
}
public void OnBeginDrag(PointerEventData eventData)
{
if (eventData.button==PointerEventData.InputButton.Left)
{
//格子里面信息处理
item = StorItem.GetItem(transform.parent.name);
StorItem.DeleteItem(transform.parent.name);
//transform.SetParent(PoolCanvas.transform, true);
transform.localScale = new Vector3(0.7f,0.7f,0.7f);
Instead_gameObject = transform.parent.gameObject;
transform.GetComponent<CanvasGroup>().blocksRaycasts = false;//给预支物添加CanvasGroup,防止出现物体检测不正确
}
}
public void OnDrag(PointerEventData eventData)
{
if (eventData.button==PointerEventData.InputButton.Left)
{
GetComponent<RectTransform>().pivot.Set(0,0);
transform.position = Input.mousePosition;
}
}
public void OnEndDrag(PointerEventData eventData)
{
transform.localScale = new Vector3(1f, 1f, 1f);
if (eventData.button==PointerEventData.InputButton.Left)//空格子之间的交换
{
if (eventData.pointerCurrentRaycast.gameObject.tag=="cell")
{
transform.SetParent(eventData.pointerCurrentRaycast.gameObject.transform);
//处理格子信息
StorItem.Store(eventData.pointerCurrentRaycast.gameObject.transform.name,item);
}
else if (eventData.pointerCurrentRaycast.gameObject.tag == "Item")//物品之间的交换
{
Transform transform_A = eventData.pointerCurrentRaycast.gameObject.transform;
Transform transform_B_parent = transform_A.parent.transform;
//处理格子信息
itemInstead = StorItem.GetItem(eventData.pointerCurrentRaycast.gameObject.transform.parent.name);
StorItem.DeleteItem(eventData.pointerCurrentRaycast.gameObject.transform.parent.name);
transform_A.SetParent(Instead_gameObject.transform, true);
transform_A.localPosition = Vector3.zero;
//处理格子信息
StorItem.Store(Instead_gameObject.transform.name,itemInstead);
transform.SetParent(transform_B_parent);
//处理格子信息
StorItem.Store(transform_B_parent.name,item);
}
else
{
transform.SetParent(Instead_gameObject.transform,true);
//处理格子信息
StorItem.Store(Instead_gameObject.name,item);
}
transform.localPosition = Vector3.zero;
transform.GetComponent<CanvasGroup>().blocksRaycasts = true;
}
}
}
六、对象池的应用###
1.在模拟按键拾取物品时,我们一直在Instantiate物品,并且Destory.这会对性能进行一个很大的消耗,那么我们通过对象池可以进行性能的提高。
2.回收方法一般通过协程调用。
对象池的2个方法:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoolManager : MonoBehaviour {
private static Dictionary<string, ArrayList> pool = new Dictionary<string, ArrayList>();//字典承储信息
public static Object Get(string prefabName,Vector3 position,Quaternion rotation)//获取方法
{
string key = prefabName + "(Clone)";
Object obj;
if (pool.ContainsKey(key) && pool[key].Count > 0)
{
ArrayList list = pool[key];
obj = list[0] as Object;
list.RemoveAt(0);
if (obj == null)
{
obj = Instantiate(Resources.Load("Prefabs/" + prefabName), position, rotation);
}
(obj as GameObject).SetActive(true);
(obj as GameObject).transform.position = position;
(obj as GameObject).transform.rotation = rotation;
}
else
{
obj = Instantiate(Resources.Load("Prefabs/" + prefabName), position, rotation);
}
return obj;
}
public static Object Return(GameObject obj)//回收方法
{
string key = obj.name;
if (pool.ContainsKey(key))
{
ArrayList list = pool[key];
list.Add(obj);
}
else
{
pool[key] = new ArrayList { obj };
}
obj.SetActive(false);
return obj;
}
}
七、界面的延伸功能##
八、物品的消耗,展示功能##
1.通过点击按键模拟消耗物品的功能.
2.物品功能通过KnapsackInfo面板上的展示.
消耗处理脚本:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ConsumManager : MonoBehaviour,IPointerDownHandler {
GameObject item;
Text indexInt;
int index;
public GameObject PoolCanvas;
void start()
{
PoolCanvas = GameObject.Find("Knapsack").transform.Find("PoolCanvas").gameObject;
}
public void OnPointerDown(PointerEventData eventData)
{
if (Input.GetMouseButtonDown(1))
{
indexInt=transform.GetChild(0).GetComponent<Text>();
index = int.Parse(indexInt.text);
if (index != 1)
{
index -= 1;
indexInt.text = index.ToString();
}
else
{
item = eventData.pointerCurrentRaycast.gameObject;
PoolManager.Return(item);
StorItem.DeleteItem(item.transform.parent.name);
//StartCoroutine(ReturnToPoll());
//item.transform.SetParent(PoolCanvas.transform);
//Destroy(item);
}
}
}
IEnumerator ReturnToPoll()
{
yield return new WaitForSeconds(0.0f);
PoolManager.Return(item);
}
}
展示处理信息脚本:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class ShowInfo : MonoBehaviour,IPointerEnterHandler,IPointerExitHandler {
Text ItemInfo;
public void OnPointerEnter(PointerEventData eventData)
{
BaseItem item = StorItem.GetItem(eventData.pointerEnter.transform.parent.name);
//ItemInfo.text=item.Description;
}
public void OnPointerExit(PointerEventData eventData)
{
}
// Use this for initialization
void Start () {
ItemInfo = GameObject.Find("Bg").transform.Find("Info").gameObject.GetComponent<Text>();
}
// Update is called once per frame
void Update () {
}
}
九、承储数据,商店物品信息管理##
1.通过代码,承储显示面板上的信息。
商店代码处理.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StorItem {
private static Dictionary<string,BaseItem> GridItem=new Dictionary<string,BaseItem>();//保存物品的仓库
public static void Store(string name,BaseItem item)//保存处理
{
if (GridItem.ContainsKey(name))
{
GridItem.Add(name, item);
return;
}
}
public static void DeleteItem(string name)//删掉处理
{
if (GridItem.ContainsKey(name))
{
GridItem.Remove(name);
}
}
public static BaseItem GetItem(string name)//获取处理
{
if (GridItem.ContainsKey(name))
{
return GridItem[name];
}
else
{
return null;
}
}
}
总结##
1.对UGUI的控件有了更深入的了解学习.
2.对类的建立,处理有了进一步的认知.
3.对象池的了解及学习.
4.加强了自己的代码能力.