要解决的问题
种田系统最难的不是「长出来」,而是让它长得像活的:
- 一根茎要从幼苗慢慢抽长,而不是几帧之间突然变大
- 叶子要随机、要不对称,否则一排种下去像复制粘贴
- 缺水、缺肥、生病的状态要看得见,玩家不用点开面板才知道
- 成熟了要能被收获,收获要真的产出东西
数据结构
作物的定义放在 DT_Farmables 里,每行对应一种可种植植物:
USTRUCT(BlueprintType)
struct FPlantData : public FTableRowBase
{
GENERATED_BODY()
/** 显示名 */
UPROPERTY(EditAnywhere, BlueprintReadOnly)
FText DisplayName;
/** 从播种到成熟需要经过的生长阶段数 */
UPROPERTY(EditAnywhere, BlueprintReadOnly)
int32 GrowthStages = 4;
/** 每个阶段需要的水分累积量 */
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TArray<float> StageWaterCost;
/** 成熟后产出的物品与数量 */
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TMap<FName, int32> HarvestYield;
/** 病害抗性 0~1,越高越不容易生病 */
UPROPERTY(EditAnywhere, BlueprintReadOnly)
float DiseaseResistance = 0.5f;
};
用 DataTable 而不是散落的蓝图变量,是因为配方会一直改 —— 到最后一定会出现「策划想加第 12 种作物」这种事,那时候你希望它只是往表里加一行。
分节生长
植株不是一整个模型缩放的,而是按节拼出来的:
BP_PlantStem_Segment—— 单节茎段,负责自己的长度插值与叶序偏移BP_Farming_Master—— 按GrowthStages生成对应数量的节,逐节驱动生长
每一节记录自己是第几节,据此计算:
- 长度缩放(越往上越短,符合真实作物比例)
- 叶片的旋转与相位偏移(用节序号做伪随机种子,保证每次生成结果一致)
- 生长插值曲线(缓入缓出,避免匀速的机械感)
这样一根茎的形态是算出来的而不是摆出来的,改一个参数整片田的观感都会变。
病害可视化
病害不是弹个 UI 图标,而是直接长在叶子上 —— 用材质表现:
| 状态 | 表现 |
|---|---|
| 缺水 | 叶片向叶脉收拢、颜色向灰绿偏移 |
| 缺肥 | 叶缘泛黄,从外圈向内扩散 |
| 真菌感染 | 随机斑块,斑块随时间扩大并互相吞噬 |
M_FoliageDiseaseVisualEffect 接收一个病害强度标量,内部混合三种表现。
好处是不需要在蓝图层写一堆分支 —— 浇水、施肥、喷药都只是改这个标量。
目前的进展
-
FPlantData结构 +DT_Farmables表 - 分节生长逻辑,幼苗到成熟四阶段
- 病害材质与三种病理表现
- 病害传播(相邻植株互相感染)
- 收获产出与背包对接