文章目录
- Lists
- Challenge: You Have Been Named
- Challenge: Build that Object List
- Practical Presentation: Creating Inventory Item DB System
Lists
- list 和 array 非常类似
- 在运行过程中可以扩展,增加 size,或者减小 size
- array 的 size 是固定的
- 我们可以用 array 来设定我们的背包,比如有 10 个物品空间可以存放不同物品
- 但是我们希望用 list 来设计我们的道具体系,因为新的道具可能需要不断添加生成
创建一个 GameManager,在里面创建一个 list,用于存放生成的游戏对象:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public List<GameObject> enemiesList; // 设定一个存放 enemies 游戏对象的列表
// 这里括号里面设定了列表里面元素的类型,这里的类型有游戏对象
public GameObject[] objArray; // 对比 array,声明的方式不同
// Start is called before the first frame update
void Start()
{
enemiesList = new List<GameObject>(); // 初始化一个空的列表
objArray = new GameObject[10]; // 初始化一个空的数组,长度为 10
// 也可以选择不进行初始化,而是在unity 的 inspector 中设定长度
// 然后拖拽需要放到列表/数组中的元素
// 我们也可以在脚本里进行赋值操作:
objArray[0] = new GameObject(); // 数组中的 0 号元素进行赋值
enemiesList.Add(new GameObject()); // 为列表添加元素
// 除了 Add,还有 Remove, Sort, Insert 等很多 List 的方法和属性可以使用
// 对于列表中元素的属性进行操作的方法类似:
objArray[0].name = "AAA";
enemiesList[0].name = "BBB";
}
// Update is called once per frame
void Update()
{
}
}
在 unity 中 GameManager 脚本有个专属的图标:齿轮。
Challenge: You Have Been Named
- 任务说明:
- 创建一个姓名的列表,把每一个都打印出来
- 列表中包含 4 个名字
- 按下空格键,随机删除列表中的一个元素,并将其打印出来
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NameList : MonoBehaviour
{
public List<string> nameList;
// Start is called before the first frame update
void Start()
{
nameList.Add("name_1");
nameList.Add("name_2");
nameList.Add("name_3");
nameList.Add("name_4");
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
int len = nameList.Count; // 获取列表长度
if (len > 0)
{
int index = Random.Range(0, len); // 获取随机序号
Debug.Log("remove name: " + nameList[index]); // 打印
nameList.RemoveAt(index); // 移除元素
}
}
}
}
Challenge: Build that Object List
- 任务说明:
- 创建一个 list/array
- 包含 3 个游戏对象
- 按下空格键,使得程序可以随机生成其中一个游戏对象,位置随机(-10~10之间)
- 所有生成的游戏对象存储到一个 objsCreated 的 List 中
- 生成的游戏对象达到 10 个的时候,按下空格键不再生成新的游戏对象,而是把现有游戏对象都变为红色
- 再次按下空格键,清除这个这个 List 中的所有游戏对象
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjsList : MonoBehaviour
{
public GameObject[] preArray = new GameObject[3]; // 数组用于存放 prefab
public List<GameObject> objsCreated; // 列表用于存放生成的游戏对象
private bool _colorChanged; // 已经改变颜色的指示
// Start is called before the first frame update
void Start()
{
// 在 unity 中设置 3 种 prefab
// 3 个元素分别为 cube,capsule,sphere,都把 Tag 设置为 Enemy
// 把本脚本挂载到 Main Camera 下
// 把 3 个 prefab 拖拽赋值到 preArray 中
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) // 按下空格键
{
int lenArray = preArray.Length; // 获取数组长度
Vector3 position = new Vector3(Random.Range(-10, 10), Random.Range(-10, 10), Random.Range(-10, 10)); // 随机位置
GameObject obj = preArray[Random.Range(0, lenArray)]; // 随机序号
if (objsCreated.Count < 10) // 不到 10 个的时候
{
GameObject objCreated = Instantiate(obj, position, obj.transform.rotation); // 生成游戏对象
objsCreated.Add(objCreated); // 添加到列表
}
else if(_colorChanged == false)
{
foreach (GameObject item in objsCreated)
{
item.GetComponent<MeshRenderer>().material.color = Color.red; // 改变颜色
}
_colorChanged = true;
}
else
{
foreach(var item in objsCreated) // 销毁所有游戏对象
{
Destroy(item);
}
objsCreated.Clear(); // 清空列表
_colorChanged = false;
}
}
}
}
Practical Presentation: Creating Inventory Item DB System
- 任务说明:
- 创建一个 item 数据库
- 使用该数据库来 check 某个 item 是否存在
创建一个脚本叫做 Item,用作定义道具的模版:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable] // 使得在 inspector 中可见
public class Item
{
public string name; // 道具名
public int id; // 道具 id
public Sprite icon; // 道具图标
}
再创建一个脚本:ItemDatabase
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemDatabase : MonoBehaviour
{
public List<Item> itemDatabase = new List<Item>(); // 创建道具列表用作数据库并初始化
// Start is called before the first frame update
void Start()
{
// 进入 unity 中的 inspector,可以设定 size
// 然后编辑该数据库里的每一个元素
// 这里我们设定 3 个元素,并填入信息
}
// Update is called once per frame
void Update()
{
}
public void AddItem(int itemId, Player player) // 用于为 player 增加 item
{
// 首先需要检查 id 在不在列表里面
foreach(var item in itemDatabase)
{
if(item.id == itemId) // 数据库中寻找到了该道具
{
player.inventory[0] = item; // 添加道具到物品栏的 0 号位置
return; // 跳出方法
}
}
Debug.Log("Item does not exist"); // 数据库里没找到该道具
}
public void RemoveItem(int itemId,Player player) // 用于移除 item
{
// 首先需要检查 id 在不在列表里面
foreach (var item in itemDatabase)
{
if (item.id == itemId) // 数据库中寻找到了该道具
{
player.inventory[0] = null; // 移除物品栏的 0 号位置道具
}
}
}
}
创建一个空的游戏对象,命名为 ItemDatabase,并挂载上面的同名脚本
创建一个脚本 Player,玩家可以有背包携带 10 件道具:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public Item[] inventory; // 玩家的物品栏
private ItemDatabase _itemDatabase;
// Start is called before the first frame update
void Start()
{
_itemDatabase = GameObject.Find("ItemDatabase").GetComponent<ItemDatabase>();
inventory = new Item[10]; // 初始化 10 格空的物品栏
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A)) // 按下 A 键
{
_itemDatabase.AddItem(0,this); // 在数据库里添加 0 号道具
}
else if (Input.GetKeyDown(KeyCode.R)) // 按下 R 键
{
_itemDatabase.RemoveItem(0, this); // 在数据库里移除 0 号道具
}
}
}
创建一个 cube,命名为 Player,并挂载同名脚本,运行游戏后,按下 A 键可以添加道具,按下R键可以移除道具。
这里是最基础的设计方法,还可以添加很多升级功能,比如检查物品栏是否有空格,然后把添加的新物品放到空格上,没有空格给出提示。还比如可以选择去除物品栏的哪个位置的道具等。