本节将深入探讨C#的高级集合类型和LINQ查询功能在游戏开发中的应用,帮助您掌握数据处理的核心技术,编写更简洁、高效的代码。通过本节的学习,您将能够熟练运用各种集合类型,掌握LINQ的高级特性,并了解如何优化游戏中的查询性能。
在学习本节内容前,您应该已经掌握:
通过本节的学习,您将能够:
在游戏开发中,我们经常需要管理大量的游戏对象。使用合适的集合类型可以显著提高性能:
using UnityEngine;
using System.Collections.Generic;
using System.Collections.Concurrent;
public class GameManager : MonoBehaviour
{
// 使用ConcurrentDictionary管理游戏对象
private ConcurrentDictionary<int, GameObject> _gameObjects =
new ConcurrentDictionary<int, GameObject>();
// 使用不可变集合存储静态游戏数据
private ImmutableDictionary<string, GameConfig> _gameConfigs;
// 使用线程安全集合处理异步加载的资源
private ConcurrentBag<GameObject> _loadedResources = new ConcurrentBag<GameObject>();
void Start()
{
// 初始化游戏配置
var configBuilder = ImmutableDictionary.CreateBuilder<string, GameConfig>();
configBuilder.Add("Player", new GameConfig { Health = 100, Speed = 5 });
configBuilder.Add("Enemy", new GameConfig { Health = 50, Speed = 3 });
_gameConfigs = configBuilder.ToImmutable();
// 注册游戏对象
RegisterGameObject(player);
RegisterGameObject(enemy);
}
public void RegisterGameObject(GameObject obj)
{
int id = obj.GetInstanceID();
_gameObjects.TryAdd(id, obj);
}
public void UnregisterGameObject(GameObject obj)
{
int id = obj.GetInstanceID();
_gameObjects.TryRemove(id, out _);
}
// 使用线程安全的方式获取游戏对象
public GameObject GetGameObject(int id)
{
return _gameObjects.TryGetValue(id, out var obj) ? obj : null;
}
// 使用不可变配置获取游戏数据
public GameConfig GetGameConfig(string type)
{
return _gameConfigs.TryGetValue(type, out var config) ? config : null;
}
}
public class GameConfig
{
public float Health { get; set; }
public float Speed { get; set; }
}
使用不可变集合管理游戏状态,确保状态变更的线程安全性:
public class GameStateManager : MonoBehaviour
{
// 使用不可变字典存储游戏状态
private ImmutableDictionary<string, object> _gameState;
// 使用线程安全集合存储状态变更历史
private ConcurrentStack<ImmutableDictionary<string, object>> _stateHistory;
void Start()
{
// 初始化游戏状态
var stateBuilder = ImmutableDictionary.CreateBuilder<string, object>();
stateBuilder.Add("Score", 0);
stateBuilder.Add("Level", 1);
stateBuilder.Add("PlayerHealth", 100f);
_gameState = stateBuilder.ToImmutable();
_stateHistory = new ConcurrentStack<ImmutableDictionary<string, object>>();
_stateHistory.Push(_gameState);
}
public void UpdateGameState(string key, object value)
{
// 创建新的状态副本
var newState = _gameState.SetItem(key, value);
// 更新当前状态
_gameState = newState;
// 保存历史记录
_stateHistory.Push(newState);
}
public bool TryUndoState()
{
if (_stateHistory.Count > 1)
{
_stateHistory.TryPop(out _); // 移除当前状态
return _stateHistory.TryPeek(out _gameState); // 恢复上一个状态
}
return false;
}
public T GetStateValue<T>(string key)
{
if (_gameState.TryGetValue(key, out var value))
{
return (T)value;
}
return default;
}
}
使用特殊用途集合管理游戏资源:
public class ResourceManager : MonoBehaviour
{
// 使用KeyedCollection管理游戏资源
private class ResourceCollection : KeyedCollection<string, GameResource>
{
protected override string GetKeyForItem(GameResource item) => item.Id;
}
private ResourceCollection _resources = new ResourceCollection();
// 使用SortedSet管理资源加载优先级
private SortedSet<GameResource> _loadingQueue =
new SortedSet<GameResource>(new ResourcePriorityComparer());
// 使用ObservableCollection监控资源状态变化
private ObservableCollection<GameResource> _loadedResources =
new ObservableCollection<GameResource>();
void Start()
{
// 订阅资源加载完成事件
_loadedResources.CollectionChanged += OnResourceLoaded;
// 加载初始资源
LoadInitialResources();
}
private void LoadInitialResources()
{
// 添加资源到加载队列
_loadingQueue.Add(new GameResource { Id = "Player", Priority = 1 });
_loadingQueue.Add(new GameResource { Id = "Enemy", Priority = 2 });
_loadingQueue.Add(new GameResource { Id = "UI", Priority = 3 });
// 按优先级加载资源
foreach (var resource in _loadingQueue)
{
StartCoroutine(LoadResource(resource));
}
}
private IEnumerator LoadResource(GameResource resource)
{
// 模拟资源加载
yield return new WaitForSeconds(1f);
// 添加到已加载资源集合
_loadedResources.Add(resource);
}
private void OnResourceLoaded(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (GameResource resource in e.NewItems)
{
Debug.Log($"资源加载完成: {resource.Id}");
}
}
}
}
public class GameResource
{
public string Id { get; set; }
public int Priority { get; set; }
}
public class ResourcePriorityComparer : IComparer<GameResource>
{
public int Compare(GameResource x, GameResource y)
{
return x.Priority.CompareTo(y.Priority);
}
}
使用LINQ高效查询游戏对象:
public class GameQuerySystem : MonoBehaviour
{
private List<GameObject> _gameObjects = new List<GameObject>();
// 使用延迟执行优化性能
public IEnumerable<GameObject> GetNearbyEnemies(Vector3 position, float radius)
{
return _gameObjects
.Where(obj => obj.CompareTag("Enemy"))
.Where(obj => Vector3.Distance(obj.transform.position, position) <= radius)
.OrderBy(obj => Vector3.Distance(obj.transform.position, position));
}
// 使用即时执行处理实时数据
public List<GameObject> GetDamagedEnemies()
{
return _gameObjects
.Where(obj => obj.CompareTag("Enemy"))
.Where(obj => obj.GetComponent<Health>().CurrentHealth < obj.GetComponent<Health>().MaxHealth)
.ToList(); // 强制即时执行
}
// 使用复合查询处理复杂游戏逻辑
public IEnumerable<GameObject> GetTargetableEnemies()
{
return _gameObjects
.Where(obj => obj.CompareTag("Enemy"))
.Where(obj => obj.GetComponent<Health>().CurrentHealth > 0)
.Where(obj => !obj.GetComponent<StatusEffects>().HasEffect(StatusEffect.Invulnerable))
.Where(obj => IsInLineOfSight(obj.transform.position))
.OrderByDescending(obj => obj.GetComponent<EnemyAI>().ThreatLevel);
}
// 使用分组查询处理游戏状态
public Dictionary<EnemyType, int> GetEnemyTypeCounts()
{
return _gameObjects
.Where(obj => obj.CompareTag("Enemy"))
.GroupBy(obj => obj.GetComponent<Enemy>().Type)
.ToDictionary(g => g.Key, g => g.Count());
}
}
使用LINQ处理游戏数据和配置:
public class GameDataManager : MonoBehaviour
{
private List<GameData> _gameData = new List<GameData>();
// 使用LINQ处理游戏存档数据
public GameSaveData CreateSaveData()
{
return new GameSaveData
{
PlayerStats = _gameData
.Where(d => d.Type == DataType.Player)
.Select(d => new PlayerStats
{
Health = d.GetValue<float>("Health"),
Experience = d.GetValue<int>("Experience"),
Level = d.GetValue<int>("Level")
})
.FirstOrDefault(),
Inventory = _gameData
.Where(d => d.Type == DataType.Inventory)
.Select(d => new InventoryData
{
Items = d.GetValue<List<Item>>("Items"),
Gold = d.GetValue<int>("Gold")
})
.FirstOrDefault(),
Quests = _gameData
.Where(d => d.Type == DataType.Quest)
.Select(d => new QuestData
{
Id = d.GetValue<string>("Id"),
Progress = d.GetValue<int>("Progress"),
IsCompleted = d.GetValue<bool>("IsCompleted")
})
.ToList()
};
}
// 使用LINQ处理游戏配置
public void ApplyGameSettings(GameSettings settings)
{
var audioSettings = _gameData
.Where(d => d.Type == DataType.Audio)
.FirstOrDefault();
if (audioSettings != null)
{
audioSettings.SetValue("MasterVolume", settings.MasterVolume);
audioSettings.SetValue("MusicVolume", settings.MusicVolume);
audioSettings.SetValue("SFXVolume", settings.SFXVolume);
}
var graphicsSettings = _gameData
.Where(d => d.Type == DataType.Graphics)
.FirstOrDefault();
if (graphicsSettings != null)
{
graphicsSettings.SetValue("Quality", settings.GraphicsQuality);
graphicsSettings.SetValue("Resolution", settings.Resolution);
graphicsSettings.SetValue("Fullscreen", settings.IsFullscreen);
}
}
}
使用LINQ优化游戏性能:
public class GamePerformanceOptimizer : MonoBehaviour
{
private List<GameObject> _gameObjects = new List<GameObject>();
private Dictionary<string, List<GameObject>> _objectCache;
void Start()
{
// 预计算和缓存常用查询结果
_objectCache = _gameObjects
.GroupBy(obj => obj.tag)
.ToDictionary(g => g.Key, g => g.ToList());
}
// 使用缓存优化频繁查询
public List<GameObject> GetObjectsByTag(string tag)
{
if (_objectCache.TryGetValue(tag, out var objects))
{
return objects;
}
// 如果缓存未命中,执行查询并缓存结果
var result = _gameObjects.Where(obj => obj.CompareTag(tag)).ToList();
_objectCache[tag] = result;
return result;
}
// 使用并行LINQ处理大量数据
public void ProcessGameObjects()
{
var damagedObjects = _gameObjects
.AsParallel()
.Where(obj => obj.GetComponent<Health>().CurrentHealth < obj.GetComponent<Health>().MaxHealth)
.ToList();
foreach (var obj in damagedObjects)
{
// 处理受损对象
ProcessDamagedObject(obj);
}
}
// 使用延迟执行优化内存使用
public IEnumerable<GameObject> GetVisibleEnemies()
{
return _gameObjects
.Where(obj => obj.CompareTag("Enemy"))
.Where(obj => IsInViewFrustum(obj.transform.position))
.Where(obj => IsInLineOfSight(obj.transform.position));
}
}
游戏对象管理:
ConcurrentDictionary
管理动态游戏对象ImmutableDictionary
存储游戏配置ConcurrentBag
处理异步加载的资源游戏状态管理:
ObservableCollection
监控状态变化资源管理:
KeyedCollection
管理游戏资源SortedSet
管理加载优先级ConcurrentQueue
处理资源加载队列查询性能:
内存管理:
代码可读性:
在本章中,我们深入探讨了C#高级集合类型和LINQ在游戏开发中的应用。通过学习这些内容,您应该已经掌握:
这些知识将帮助您构建更高效、可维护的游戏系统。
上一节:4.1 泛型编程深入指南 | 返回章节目录 | 下一节:4.3 委托与事件深入指南