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

前言

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

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

  1. PlantSO脚本化对象存储植物名称、生长阶段预制体、生长时间等数据;
  2. PlantObject控制器管理植物生长状态,处理阶段切换和实例化;
  3. TimeManager时间管理器统一控制所有植物的生长进度。测试使用不同形状的立方体和圆形模拟植物各生长阶段,通过GIF展示了植物从种子到成熟的动态生长效果。该方案采用模块化设计,便于扩展不同植物类型和生长逻辑,适用于农场模拟等游戏开发场景。

实践

1、植物脚本化对象,用于存储植物数据

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、植物生长控制器

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、时间管理器,控制所有植物的生长

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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向宇it

创作不易,感谢你的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值