Unity学习记录-背包系统简单实现

ScriptableObject

  • ScriptableObject是Unity提供的一个数据配置存储基类,可以用来保存数据资源文件
  • ScriptableObject的实例会被保存为资源文件(.asset)
  • 使用ScriptableObject,我们需要创建一个类来继承它

示例代码:创建物品类ScriptableObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "Item",menuName ="BagSystem/Item")]
public class Item : ScriptableObject
{
[Header("物品名字")]
public string itemName;
[Header("持有数量")]
public int count = 0;
[Header("是否可堆叠")]
public bool stackable = true;
[TextArea]
public string describeText;
[Header("贴图")]
public Sprite itemImage;
}
  • 在此之后我们可以使用右键来创建相关的资源

物品的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName = "Item",menuName ="BagSystem/Item")]
public class Item : ScriptableObject
{
[Header("物品名字")]
public string itemName;
[Header("持有数量")]
public int count = 0;
[Header("是否可堆叠")]
public bool stackable = true;
[TextArea]
public string describeText;
[Header("贴图")]
public Sprite itemImage;
}

创建物品资源

背包的创建

1
2
3
4
5
6
7
8
9
10
11
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName ="bag",menuName ="BagSystem/Bag")]
public class BagList : ScriptableObject
{
[Header("物品列表")]
public List<Item> bagList = new List<Item>();

}
  • 此处注意Dictionary无法被数据持久化,应该换一种数据结构(如List)

创建背包资源

创建背包UI——使用Grid Layout Group

创建Scroll View

使用Grid Layout Group

完善逻辑——模拟添加物品

  • 初始化背包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void initBag()
{
GameObject content = GameObject.Find("BagContent");
int numberOfChild = content.transform.childCount;

//先清空UI里面已经存在的
for(int i=0;i<numberOfChild;i++)
{
Destroy(content.transform.GetChild(i).gameObject);
}

foreach (var item in playerBag.bagList)
{
if (item.stackable) //可以堆叠的情况
{
GameObject temp = Instantiate(itemObject);
temp.transform.Find("itemImage").GetComponent<Image>().sprite = item.itemImage;
temp.transform.Find("count").GetComponent<Text>().text = item.count.ToString();
temp.transform.SetParent(content.transform);
}
else //不可堆叠的情况
{
for(int i=0;i< item.count;i++)
{
GameObject temp = Instantiate(itemObject);
temp.transform.Find("itemImage").GetComponent<Image>().sprite = item.itemImage;
temp.transform.Find("count").GetComponent<Text>().text = "1";
temp.transform.SetParent(content.transform);
}
}
}
}
  • 添加剑
1
2
3
4
5
6
7
8
9
10
public void addSword()
{
if(!playerBag.bagList.Contains(ice_sword))
{
ice_sword.count = 1;
playerBag.bagList.Add(ice_sword);
}
else ice_sword.count++;
initBag();
}
  • 整体代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class addItem : MonoBehaviour
{
public BagList playerBag;
public Item ice_sword;
public Item fire_lance;
public GameObject itemObject;

private void Start()
{
initBag();
}

private void initBag()
{
GameObject content = GameObject.Find("BagContent");
int numberOfChild = content.transform.childCount;

//先清空UI里面已经存在的
for(int i=0;i<numberOfChild;i++)
{
Destroy(content.transform.GetChild(i).gameObject);
}

foreach (var item in playerBag.bagList)
{
if (item.stackable) //可以堆叠的情况
{
GameObject temp = Instantiate(itemObject);
temp.transform.Find("itemImage").GetComponent<Image>().sprite = item.itemImage;
temp.transform.Find("count").GetComponent<Text>().text = item.count.ToString();
temp.transform.SetParent(content.transform);
}
else //不可堆叠的情况
{
for(int i=0;i< item.count;i++)
{
GameObject temp = Instantiate(itemObject);
temp.transform.Find("itemImage").GetComponent<Image>().sprite = item.itemImage;
temp.transform.Find("count").GetComponent<Text>().text = "1";
temp.transform.SetParent(content.transform);
}
}
}
}

public void addSword()
{
if(!playerBag.bagList.Contains(ice_sword))
{
ice_sword.count = 1;
playerBag.bagList.Add(ice_sword);
}
else ice_sword.count++;
initBag();
}

public void addLance()
{
if (!playerBag.bagList.Contains(fire_lance))
{
fire_lance.count = 1;
playerBag.bagList.Add(fire_lance);
}
else fire_lance.count++;
initBag();
}
}