【unity小技巧】封装一套 Unity 的植物生长系统

文章目录

前言

如果你对制作生存模拟经营游戏感兴趣,那么其中比较重要的功能之一应该就是植物生长系统,本文就来封装一个植物生长系统,方便后面使用,这里我参考了youtube上JD Dev的方法。

系统通过三个核心脚本实现:

  1. PlantSO脚本化对象存储植物名称、生长阶段预制体、生长时间等数据;
  2. PlantObject控制器管理植物生长状态,处理阶段切换和实例化;
  3. 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


专栏推荐

地址
【unity游戏开发入门到精通------C#篇】
【unity游戏开发入门到精通------unity通用篇】
【unity游戏开发入门到精通------unity3D篇】
【unity游戏开发入门到精通------unity2D篇】
【unity实战】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】
【unity游戏开发------模型篇】
【unity游戏开发------InputSystem】
【unity游戏开发------Animator动画】
【unity游戏开发------UGUI】
【unity游戏开发------联网篇】
【unity游戏开发------优化篇】
【unity游戏开发------shader篇】
【unity游戏开发------编辑器扩展】
【unity游戏开发------热更新】
【unity游戏开发------网络】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

相关推荐
枫景Maple11 分钟前
Shader开发(六)什么是着色器
游戏引擎·着色器
R-G-B1 小时前
【05】VM二次开发——模块参数配置--带渲染/不带渲染(WinForm界面调用 模块参数配置)
c#·vm二次开发·vm模块参数配置·vm在winform界面调用
Ai财富密码2 小时前
AI赋能教育:低代码游戏化学习平台
人工智能·低代码·游戏
向宇it3 小时前
【unity小技巧】封装unity适合2D3D进行鼠标射线检测,获取鼠标位置信息检测工具类
游戏·3d·unity·游戏引擎
R-G-B8 小时前
【12】大恒相机SDK C#开发 ——多相机开发,枚举所有相机,并按配置文件中的相机顺序 将所有相机加入设备列表,以便于对每个指定的相机操作
c#·大恒相机sdk·大恒多相机开发·大恒多相机枚举·大恒多相机指定顺序
R-G-B8 小时前
【13】大恒相机SDK C#开发 —— Fom1中实时处理的8个图像 实时显示在Form2界面的 pictureBox中
c#·大恒相机sdk·图像实时显示在另一个界面
年少无知且疯狂9 小时前
【Unity】实现小地图
unity·游戏引擎
AA陈超9 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 #06-11:游戏后效果执行
c++·游戏·ue5·游戏引擎·虚幻
EanoJiang10 小时前
第三人称——骑马系统以及交互动画
游戏
徐子竣13 小时前
[学习记录]Unity-Shader-常量缓冲区(CBUFFER)
学习·unity·游戏引擎