@export_storage
2026/4/14大约 4 分钟
最后更新日期:2026-04-16
最后同步日期:2026-04-15 | Godot 官方原文 — @export_storage
@export_storage
定义
@export_storage 是 GDScript 中的一个注解(annotation),用来将变量的值保存到场景文件中,但不在检查器面板中显示编辑控件。简单说,这个变量的值会被持久化存储,但用户无法在编辑器的检查器面板中直接看到或修改它。
想象你有一个内部计算用的变量,比如"上一次存档的时间戳"——你需要保存这个值,但不希望策划误改它。@export_storage 就是为此设计的:数据会保存,但编辑器里看不到。
在 C# 中没有直接等价的特性。C# 中可以通过 [Export] 导出变量然后在代码中处理可见性,或者使用 _Set / _GetPropertyList 等底层方法实现类似效果。
语法
C#
// C# 没有直接等价的 @export_storage
// 替代方案 1:使用 [Export] 但不在检查器中暴露(通过自定义属性列表)
// 替代方案 2:使用 _Set/_GetPropertyList 方法
// 最接近的替代方式:正常导出,但作为内部使用
[Export] public string ExInternalState = "";GDScript
# 导出存储变量(保存但不在检查器中显示)
@export_storage var _last_save_time: String = ""
# 也可以用于保存计算结果
@export_storage var _cached_score: int = 0参数说明
@export_storage 不需要任何参数——它直接写在变量声明前面即可。
| 说明项 | 详情 |
|---|---|
| 变量类型 | 支持任何可序列化的类型 |
| 检查器面板 | 不显示编辑控件 |
| 场景文件 | 变量值会保存到场景文件(.tscn)中 |
| 用途 | 保存内部状态、缓存数据、运行时生成的数据 |
返回值
@export_storage 是一个注解,没有返回值。变量的值会被保存到场景文件中,但编辑器中不可直接编辑。
代码示例
C#
using Godot;
public partial class GameState : Node
{
// ===== C# 替代方案:使用 Export 保存值 =====
// 注意:C# 中 [Export] 会在检查器中显示
// 如果需要完全隐藏,需要用 _Set/_GetPropertyList
[Export] public string ExLastSaveTime = "";
[Export] public int ExCachedScore = 0;
public override void _Ready()
{
if (!string.IsNullOrEmpty(ExLastSaveTime))
{
GD.Print($"上次保存时间: {ExLastSaveTime}");
}
}
// 运行结果: 上次保存时间: 2026-04-15 10:30:00
// ===== 实际场景:缓存计算结果 =====
[Export] public float ExCachedDifficulty = 1.0f;
[Export] public int ExPlayCount = 0;
public void RecordPlay()
{
ExPlayCount++;
ExCachedDifficulty = 1.0f + ExPlayCount * 0.1f;
GD.Print($"游玩次数: {ExPlayCount},当前难度: {ExCachedDifficulty:F1}");
}
// 运行结果: 游玩次数: 5,当前难度: 1.5
// ===== 进阶用法:运行时状态持久化 =====
[Export] public string ExUnlockedAreas = "town";
[Export] public int ExHighScore = 0;
public void UnlockArea(string areaName)
{
if (!ExUnlockedAreas.Contains(areaName))
{
ExUnlockedAreas += $",{areaName}";
GD.Print($"已解锁区域: {areaName},全部区域: {ExUnlockedAreas}");
}
}
public void UpdateHighScore(int score)
{
if (score > ExHighScore)
{
ExHighScore = score;
GD.Print($"新纪录!最高分: {ExHighScore}");
}
}
// 运行结果: 已解锁区域: forest,全部区域: town,forest
// 运行结果: 新纪录!最高分: 9800
}GDScript
extends Node
# ===== 基础用法:保存但不在检查器中显示 =====
@export_storage var _last_save_time: String = ""
func _ready():
if not _last_save_time.is_empty():
print("上次保存时间: %s" % _last_save_time)
# 运行结果: 上次保存时间: 2026-04-15 10:30:00
# ===== 实际场景:缓存计算结果 =====
@export_storage var _cached_difficulty: float = 1.0
@export_storage var _play_count: int = 0
func record_play():
_play_count += 1
_cached_difficulty = 1.0 + _play_count * 0.1
print("游玩次数: %d,当前难度: %.1f" % [_play_count, _cached_difficulty])
# 运行结果: 游玩次数: 5,当前难度: 1.5
# ===== 进阶用法:运行时状态持久化 =====
@export_storage var _unlocked_areas: String = "town"
@export_storage var _high_score: int = 0
func unlock_area(area_name: String):
if not area_name in _unlocked_areas.split(","):
_unlocked_areas += ",%s" % area_name
print("已解锁区域: %s,全部区域: %s" % [area_name, _unlocked_areas])
func update_high_score(score: int):
if score > _high_score:
_high_score = score
print("新纪录!最高分: %d" % _high_score)
# 运行结果: 已解锁区域: forest,全部区域: town,forest
# 运行结果: 新纪录!最高分: 9800注意事项
@export_storage的变量不会出现在检查器面板中,但值会保存到场景文件(.tscn)中。- 主要用途是持久化运行时数据——比如保存游戏状态、缓存计算结果等。
- C# 没有直接等价的特性。
[Export]会同时在检查器中显示,如果需要完全隐藏,需要使用 Godot 底层的_Set/_Get/_GetPropertyList方法。 - 使用
@export_storage的变量仍然可以在代码中正常读写,只是不能通过编辑器界面修改。 - 修改变量名时要小心:因为值保存在场景文件中,改名后旧的保存值会失效。
- 不要用
@export_storage替代@export——如果你需要用户在编辑器中编辑变量,请使用@export。
