Unity中使用List
List<T>是Unity开发中最常用的数据结构之一,它提供了动态数组的功能,可以高效地存储和管理游戏对象、组件或自定义数据。面试中偶尔也会考察Unity 中如何高效使用 List<T>。
以下内容提供参考。
管理游戏对象
public class EnemyManager : MonoBehaviour {
private List<GameObject> activeEnemies = new List<GameObject>();
public void SpawnEnemy(GameObject prefab) {
GameObject enemy = Instantiate(prefab);
activeEnemies.Add(enemy);
}
public void CleanDeadEnemies() {
activeEnemies.RemoveAll(e => e == null || !e.activeSelf);
}
}
存储组件引用
List<Renderer> allRenderers = new List<Renderer>();
void Start() {
GetComponentsInChildren(allRenderers);
allRenderers.ForEach(r => r.enabled = false);
}
与协程配合使用
IEnumerator ProcessEnemies() {
foreach(GameObject enemy in enemyList) {
enemy.GetComponent<AI>().Process();
yield return new WaitForSeconds(0.1f);
}
}
预分配容量
// 预先分配足够容量
List<Vector3> pathPoints = new List<Vector3>(1000);
这可以避免频繁扩容带来的性能损耗。
使用对象池
对于频繁创建销毁的对象,使用对象池替代List的直接管理:
public class GameObjectPool {
private Stack<GameObject> pool = new Stack<GameObject>();
private GameObject prefab;
public GameObject Get() {
return pool.Count > ? pool.Pop() : Instantiate(prefab);
}
public void Release(GameObject obj) {
obj.SetActive(false);
pool.Push(obj);
}
}
避免装箱拆箱
使用泛型List而非ArrayList等非泛型集合:
// 推荐
List<int> scores = new List<int>();
// 不推荐(会导致装箱拆箱)
ArrayList scores = new ArrayList();
批量操作优先
// 批量添加
enemyList.AddRange(newEnemies);
// 批量删除
enemyList.RemoveAll(e => e == null);
批量操作比单个操作更高效。
多线程访问
List<T>不是线程安全的,多线程环境下需要使用锁或并发集合:
private List<GameObject> enemyList = new List<GameObject>();
private readonly object listLock = new object();
void AddEnemy(GameObject enemy) {
lock(listLock) {
enemyList.Add(enemy);
}
}
序列化问题
Unity默认不序列化泛型集合,需要特殊处理
[System.Serializable]
public class EnemyWrapper {
public List<GameObject> enemies;
}
// 在MonoBehaviour中
public EnemyWrapper enemyWrapper;
UI列表优化
对于长列表(如排行榜),使用循环复用技术而非直接创建所有元素:
// 使用ScrollView循环复用组件
public class RecyclableScrollView : MonoBehaviour {
[SerializeField] private RectTransform content;
[SerializeField] private GameObject itemPrefab;
[SerializeField] private float itemHeight;
private List<ItemData> dataList;
private List<GameObject> activeItems = new List<GameObject>();
public void Initialize(List<ItemData> data) {
dataList = data;
content.sizeDelta = new Vector2(content.sizeDelta.x, data.Count * itemHeight);
UpdateVisibleItems();
}
private void UpdateVisibleItems() {
// 根据滚动位置更新可见项
}
}