【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,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

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

相关推荐
小龙报2 小时前
《数组和函数的实践游戏---扫雷游戏(基础版附源码)》
c语言·开发语言·windows·游戏·创业创新·学习方法·visual studio
津津有味道3 小时前
ISO18000-6C协议UHF6C超高频RFID读写C#源码
c#·uhf6c·超高频·iso18000-6c
白雪公主的后妈3 小时前
Auto CAD二次开发——创建圆弧对象
c#·cad二次开发·创建圆弧对象
2501_929157683 小时前
Switch 20.5.0系统最新PSP模拟器懒人包
android·游戏·ios·pdf
weixin_307779136 小时前
C#程序实现将MySQL的存储过程转换为Azure Synapse Dedicated SQL Pool的T-SQL存储过程
c#·自动化·云计算·运维开发·azure
"菠萝"8 小时前
C#知识学习-018(方法参数传递)
学习·c#·1024程序员节
CiLerLinux8 小时前
第三章 FreeRTOS 任务相关 API 函数
开发语言·单片机·物联网·c#
.NET修仙日记8 小时前
C#/.NET 微服务架构:从入门到精通的完整学习路线
微服务·c#·.net·.net core·分布式架构·技术进阶
歪歪10018 小时前
在C#中详细介绍一下Visual Studio中如何使用数据可视化工具
开发语言·前端·c#·visual studio code·visual studio·1024程序员节
Eiceblue18 小时前
如何通过 C# 高效读写 Excel 工作表
c#·visual studio·1024程序员节