Unity C#农场游戏列表相关作物生长逻辑报错求助
Unity农场游戏作物生长阶段实现方案
1. 核心代码修正与实现
作物数据类定义
明确存储播种时间、位置、当前生长阶段及场景对象引用,避免数据与显示分离导致的逻辑错误:
public class CropsPlanted { // 用游戏运行时间(适合单局游戏,重启后进度重置) public float TimeWhenSeeded { get; set; } public Vector3 Position { get; set; } public int CurrentGrowthStage { get; set; } public GameObject CropObject { get; set; } }
全局作物管理集合
通过单例模式实现全局访问,确保集合已初始化:
public class FarmManager : MonoBehaviour { public static FarmManager Instance; public List<CropsPlanted> PlantedCrops = new List<CropsPlanted>(); void Awake() { Instance = this; } // 修正后的CreateObjectSeeded函数 public void CreateObjectSeeded(Vector3 position, float timeWhenSeeded) { // 实例化作物预制体(替换为你的预制体路径) GameObject cropPrefab = Resources.Load<GameObject>("Prefabs/CropSeed"); GameObject cropObj = Instantiate(cropPrefab, position, Quaternion.identity); // 创建作物数据并加入管理集合 CropsPlanted cropData = new CropsPlanted { TimeWhenSeeded = timeWhenSeeded, Position = position, CurrentGrowthStage = 0, // 初始为播种阶段 CropObject = cropObj }; PlantedCrops.Add(cropData); } }
时间检查与阶段切换逻辑
采用倒序遍历避免集合修改时的索引异常,明确时间差判断规则:
// 可放在FarmManager或单独的生长检测脚本中 void Update() { CheckTimeCrops(); } void CheckTimeCrops() { var plantedCrops = FarmManager.Instance.PlantedCrops; // 倒序遍历,防止删除元素触发索引错误 for (int i = plantedCrops.Count - 1; i >= 0; i--) { CropsPlanted crop = plantedCrops[i]; float timeElapsed = Time.time - crop.TimeWhenSeeded; // 替换为你的实际阶段阈值(示例:10秒进入生长阶段,20秒成熟) if (timeElapsed >= 20f && crop.CurrentGrowthStage != 2) { UpdateCropStage(crop, 2); // 切换到成熟阶段 } else if (timeElapsed >= 10f && crop.CurrentGrowthStage != 1) { UpdateCropStage(crop, 1); // 切换到生长阶段 } } } // 单独处理阶段切换,便于扩展显示逻辑 void UpdateCropStage(CropsPlanted crop, int newStage) { crop.CurrentGrowthStage = newStage; // 替换作物显示(示例:切换Sprite) SpriteRenderer renderer = crop.CropObject.GetComponent<SpriteRenderer>(); switch (newStage) { case 1: renderer.sprite = Resources.Load<Sprite>("Sprites/CropStage1"); break; case 2: renderer.sprite = Resources.Load<Sprite>("Sprites/CropStage2"); // 成熟后添加采摘交互逻辑 crop.CropObject.AddComponent<CropHarvest>(); break; } }
2. 跨会话生长进度保存(可选)
若需关闭游戏后保留生长状态,改用真实时间存储:
// 修改CropsPlanted类的时间属性 public DateTime TimeWhenSeeded { get; set; } // CreateObjectSeeded中赋值 TimeWhenSeeded = DateTime.Now; // CheckTimeCrops中计算时间差 TimeSpan timeElapsed = DateTime.Now - crop.TimeWhenSeeded; float totalSeconds = (float)timeElapsed.TotalSeconds; // 后续阶段判断逻辑不变
3. 常见报错排查
- NullReferenceException:检查
PlantedCrops是否初始化、FarmManager.Instance是否有效、CropObject是否正确实例化 - InvalidOperationException:禁止用foreach遍历并修改集合,改用倒序for循环
- 时间对比无效果:若需不受游戏暂停影响,将
Time.time替换为Time.realtimeSinceStartup
内容的提问来源于stack exchange,提问作者yantape123
相关产品推荐
相关产品推荐

