文章目录
前言
如果你对制作生存模拟经营游戏感兴趣,那么其中比较重要的功能之一应该就是植物生长系统,本文就来封装一个植物生长系统,方便后面使用,这里我参考了youtube上JD Dev
的方法。
系统通过三个核心脚本实现:
- PlantSO脚本化对象存储植物名称、生长阶段预制体、生长时间等数据;
- PlantObject控制器管理植物生长状态,处理阶段切换和实例化;
- TimeManager时间管理器统一控制所有植物的生长进度。测试使用不同形状的立方体和圆形模拟植物各生长阶段,通过GIF展示了植物从种子到成熟的动态生长效果。该方案采用模块化设计,便于扩展不同植物类型和生长逻辑,适用于农场模拟等游戏开发场景。
实践
1、植物脚本化对象,用于存储植物数据
csharp
using UnityEngine;
using System.Collections.Generic;
// 植物脚本化对象,用于存储植物数据
[CreateAssetMenu(fileName = "PlantSO", menuName = "Data/PlantSo")]
public class PlantSO : ScriptableObject
{
public string PlantName; // 植物名称
public List<GameObject> PlantPrefabs; // 植物各阶段预制体列表
public float CropTime; // 每个生长阶段所需时间
public int CropReward; // 收获奖励
// 最大生长阶段数(根据预制体数量自动计算)
public int MaxStage { get { return PlantPrefabs.Count; } }
// 根据阶段获取植物预制体
public GameObject GetPlantByStage(int stage)
{
if (stage >= MaxStage)
{
return null;
}
return PlantPrefabs[stage];
}
}
2、植物生长控制器
csharp
using UnityEngine;
// 植物生长控制器
public class PlantObject : MonoBehaviour
{
[SerializeField] private PlantSO plant; // 关联的植物数据
private int currentStage; // 当前生长阶段
private float currentTime; // 当前阶段已生长时间
private GameObject currentPlant; // 当前显示的植物对象
// 初始化
private void Start()
{
TimeManager.instance.RegisterPlant(this);
currentPlant = Instantiate(plant.GetPlantByStage(currentStage), transform);
}
// 检查植物生长状态(由TimeManager定期调用)
public void CheckPlant(float deltaTime)
{
currentTime += deltaTime;
// 检查是否达到生长时间
if (currentTime > plant.CropTime)
{
currentStage++;
currentTime = 0;
// 销毁当前植物并实例化下一阶段的植物
Destroy(currentPlant);
// 检查是否还有下一阶段
GameObject nextStagePrefab = plant.GetPlantByStage(currentStage);
if (nextStagePrefab)
{
currentPlant = Instantiate(nextStagePrefab, transform);
Debug.Log($"当前阶段: {currentStage}");
}
else
{
Debug.Log($"植物已完全成熟,收获奖励: {plant.CropReward}");
// 通知TimeManager立即移除自己
TimeManager.instance.UnregisterPlant(this);
}
}
}
// 检查是否已达到最大生长阶段
public bool HasMaxLevel()
{
return currentStage >= plant.MaxStage;
}
}
3、时间管理器,控制所有植物的生长
csharp
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
// 时间管理器,控制所有植物的生长
public class TimeManager : MonoBehaviour
{
private List<PlantObject> plantObjects = new List<PlantObject>();
public static TimeManager instance;
// 初始化单例
private void Awake()
{
if (instance == null)
instance = this;
}
// 注册植物到管理列表
public void RegisterPlant(PlantObject plantObject)
{
plantObjects.Add(plantObject);
}
// 从管理列表移除植物
public void UnregisterPlant(PlantObject plantObject)
{
plantObjects.Remove(plantObject);
}
// 每帧更新所有植物的生长状态
private void Update()
{
foreach (PlantObject plantObject in plantObjects.ToList())
{
plantObject.CheckPlant(Time.deltaTime);
}
// 移除已经完成生长的植物
plantObjects.RemoveAll(x => x.HasMaxLevel());
}
}
4、调用测试
我们新增两种测试植物,不同大小的立方体和圆形作为测试,模拟植物生长的不同阶段
挂载脚本
效果
参考
https://www.youtube.com/watch?v=aG_HMFWPDaM\&t=1s
专栏推荐
完结
好了,我是向宇
,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!