Skip to content

物品系统 ​

物品系统管理游戏中的所有物品,包括可拾取物品、装备/模组物品和增益消耗品。物品挂载在单位上,通过背包系统进行拾取、装备和丢弃,并支持品质、等级、堆叠和动态属性修改。

核心类型 ​

类型说明
GameDataItem物品数编基类(抽象),定义显示信息、关联单位、品质、等级和过滤器
GameDataItemPickable可拾取物品数编,定义堆叠、丢弃、出售等行为
GameDataItemMod装备/模组物品数编,定义各槽位属性修改和装备需求
GameDataItemPowerUp增益消耗品数编,使用后对目标施加效果
GameDataItemQuality品质配置,定义颜色、图标装饰和地面特效
Item物品运行时基类(抽象),管理品质、等级、分类
ItemPickable可拾取物品实例,支持堆叠、背包槽位、拾取和丢弃
ItemMod装备/模组物品实例,提供属性修改、技能授予和动态修改
ItemPowerUp增益消耗品实例,使用后施加效果并可自动销毁
DynamicModification动态属性修改项(运行时通过代码添加)
DynamicModificationManager管理物品上的动态属性修改(仅服务端)

类型继承关系 ​

GameDataItem (abstract)
 └── GameDataItemPickable
      └── GameDataItemMod
 └── GameDataItemPowerUp

Item (abstract) : TagComponent
 └── ItemPickable
      └── ItemMod
 └── ItemPowerUp

GameDataItem 配置 ​

所有物品数编的公共基类。

csharp
public abstract partial class GameDataItem
{
    public LocalizedString? DisplayName { get; set; }
    public LocalizedString? Description { get; set; }
    public Icon? Icon { get; set; }
    public required IGameLink<GameDataUnit> Unit { get; set; }   // 物品在场景中的单位表现
    public uint Quality { get; set; }                            // 默认品质
    public uint Level { get; set; }                              // 默认等级
    public TargetFilterComplex Filter { get; set; } = [];        // 交互过滤器
    public SyncType SyncType { get; set; } = SyncType.SelfOrSight;
    public List<ItemCategory> Categories { get; set; } = [];     // 分类标签(可扩展枚举)
}

服务端创建方法:

csharp
#if SERVER
// 在指定位置创建物品(自动创建关联单位)
public Item CreateItem(ScenePoint scene, Player? player = null);

// 仅创建关联单位(不创建物品组件)
protected Unit CreateItemUnit(ScenePoint scene, Player? player);
#endif

GameDataItemPickable ​

继承自 GameDataItem,添加堆叠和丢弃相关配置。

属性类型默认值说明
StackStartuint1创建时的初始堆叠数
StackMaxuint?null最大堆叠数,null 表示无限制
CanStackbooltrue是否允许堆叠
CanAbsorbbooltrue堆叠时是否自动吸收同种物品
CanDropboolfalse是否允许丢弃到地面
CanSellboolfalse是否允许出售给商店
RemoveOnDropboolfalse丢弃时直接移除(不生成地面物品)
KillOnDepletedbooltrue堆叠数为 0 时自动销毁

GameDataItemMod ​

继承自 GameDataItemPickable,添加装备相关配置。

属性类型说明
ModificationsQuickDictionary<ItemSlotType, ItemUnitModificationData>各槽位的属性修改配置
RequirementsUnitPropertyRequirements装备需求条件

ItemUnitModificationData 包含该槽位下的属性加成、状态变更、授予技能和附属 Actor 等配置。

GameDataItemPowerUp ​

继承自 GameDataItem(直接继承,不经过 GameDataItemPickable)。

属性类型默认值说明
EffectIGameLink<GameDataEffect>?null使用后施加的效果
KillOnPowerUpbooltrue使用后是否销毁

GameDataItemQuality ​

品质视觉配置,通过 GameDataGameplay.ItemQualityList 全局注册。

属性类型说明
ColorColor品质颜色(用于名称等 UI 元素着色)
BackgroundImageIcon物品图标的背景装饰
BorderImageIcon物品图标的边框装饰
ActorArrayList<IGameLink<GameDataActor>>?地面物品的品质特效 Actor

物品通过 Item.Quality 值作为索引,从 ItemQualityList 中查找对应配置。

Item 运行时基类 ​

所有物品实例的公共基类,挂载在单位上(TagComponent)。

属性 ​

属性类型说明
LinkIGameLink<GameDataItem>物品数编链接
CacheGameDataItem数编缓存
UnitUnit物品所属的单位
Qualityuint品质等级(服务端可写,客户端只读)
Leveluint物品等级(服务端可写,客户端只读)
CategoriesList<ItemCategory>分类列表(来自数编)
QualityConfigurationGameDataItemQuality?当前品质对应的视觉配置

方法 ​

方法说明
HasCategory(ItemCategory)检查物品是否属于指定分类
GetComponent<T>(Entity)扩展方法,从实体获取物品组件

获取物品组件 ​

csharp
var item = entity.GetComponent<Item>();
var itemMod = entity.GetComponent<ItemMod>();

ItemPickable ​

可拾取物品,支持堆叠、背包和拾取/丢弃交互。

属性 ​

属性类型说明
Stackuint当前堆叠数(服务端可写)
StackMaxuint?最大堆叠数
CanStackbool是否可堆叠
AbsorbEnabledbool是否启用自动吸收
SlotInventorySlot?当前所在的背包槽位
SlotTypeItemSlotType?当前槽位类型
CarrierUnit?携带者单位(在背包中时非空)
MeetRequirementbool是否满足装备需求

方法 ​

方法说明
AddStack(int)增减堆叠数,返回新值
CanAbsorb(ItemPickable)检查是否可以吸收另一物品的堆叠
Absorb(ItemPickable)吸收另一物品的堆叠,返回吸收量
Drop(ReasonItemDrop, InventorySlot?)从背包丢弃
TestRequirement(Unit)检查指定单位是否满足装备需求

事件 ​

事件说明
Assigned物品被放入背包槽位时触发
Dropped物品从背包槽位移除时触发

拾取接口(IPickUpItem) ​

csharp
#if SERVER
// 检查是否可以拾取
CmdResult CanPickUp(InventoryManager manager, bool isRequest = false);

// 执行拾取
bool PickUp(InventoryManager manager, bool isRequest = false);
#endif

ItemMod ​

装备/模组物品,装备后可修改持有者的属性并授予技能。继承自 ItemPickable。

核心机制 ​

  1. 属性修改:根据装备的槽位类型(ItemSlotType),应用对应的属性修改(ModificationManager)
  2. 技能授予:装备后可自动创建并授予技能(ActiveAbility)
  3. 需求检查:可设置装备需求(UnitPropertyRequirements),不满足时 IsEnabled 为 false
  4. 堆叠影响:堆叠数变化时自动更新属性修改倍率

属性 ​

属性类型说明
IsEnabledbool是否启用(满足需求时为 true)
ActiveAbilityAbility?当前授予的技能
ActiveModificationManagerModificationManager?当前激活的属性修改管理器
ModificationManagersQuickDictionary<ItemSlotType, ModificationManager>各槽位的修改管理器
DynamicModificationsDynamicModificationManager动态修改管理器(仅服务端)

服务端方法 ​

csharp
#if SERVER
// 强制刷新所有属性修改
public void UpdateModifications(bool forced = false);
#endif

客户端 Actor 管理 ​

ItemMod 在客户端管理两类 Actor:

  • HostedActors:物品被装备时,为持有者创建的附属 Actor(如武器模型、光效)
  • SelfActors:物品作为地面单位时的自身 Actor

两者互斥——物品要么在背包中(显示 HostedActors),要么在地面上(显示 SelfActors)。

如果要让物品被携带或装备后自动显示在持有者身上,把附加模型 Actor 配到该槽位的 ItemUnitModificationData.ActorArray。完整配方见 自动挂载模型表现。

装备/卸下生命周期 ​

创建 ItemMod
    ↓
放入背包槽位 (OnInternalAssigned)
    ↓ SERVER: UpdateModifications() → 应用属性修改 + 创建技能
    ↓ CLIENT: 清除 SelfActors → 创建 HostedActors
    ↓
从背包移除 (OnInternalDropped)
    ↓ SERVER: UpdateModifications() → 移除属性修改 + 销毁技能
    ↓ CLIENT: 清除 HostedActors → 恢复 SelfActors

动态修改系统 ​

动态修改允许通过代码在运行时为 ItemMod 添加属性加成,与数编配置的静态修改互补。

DynamicModificationKey ​

唯一标识一个动态修改:(ItemSlotType, IGameLink<GameDataUnitProperty>, PropertySubType)。

三者组合在一个物品上是唯一的。

DynamicModificationManager(仅服务端) ​

方法说明
SetModification(slotType, property, value, subType)设置修改(存在则更新)
AddModification(slotType, property, value, subType)在现有基础上增加值,返回最终值
RemoveModification(slotType, property, subType)移除指定修改
RemoveModificationsBySlot(slotType)移除指定槽位的所有修改
ClearAll()清除所有动态修改
HasModification(slotType, property, subType)检查是否存在
GetModification(slotType, property, subType)获取指定修改
GetModifications(slotType)获取指定槽位的所有修改
AllModifications所有动态修改的枚举

修改会根据物品当前槽位状态自动应用或移除——仅当 CurrentSlotType 与修改的 slotType 匹配时才生效。

客户端动态修改查询 ​

客户端通过属性同步机制获取动态修改数据:

csharp
#if CLIENT
// ItemMod 实例方法
bool HasDynamicModification(ItemSlotType slotType, IGameLink<GameDataUnitProperty> property, PropertySubType subType);
DynamicModification? GetDynamicModification(ItemSlotType slotType, IGameLink<GameDataUnitProperty> property, PropertySubType subType);
IEnumerable<DynamicModification> GetDynamicModifications(ItemSlotType slotType);
#endif

ItemPowerUp ​

增益消耗品,被单位拾取后可施加效果。继承自 Item(不经过 ItemPickable)。

使用流程(服务端):

  1. PreValidate — 创建效果实例并预验证
  2. Execute — 解析目标并执行效果
  3. 如果 KillOnPowerUp 为 true,执行后自动销毁

物品事件 ​

事件类属性触发时机
EventItemSlotChangeItem, Slot, SlotPrevious物品槽位变更
EventItemStackChangeItem, Stack, StackPrevious堆叠数变更
EventItemLevelChangeItem, Level, LevelPrevious等级变更
EventItemQualityChangeItem, Quality, QualityPrevious品质变更

使用 Trigger<T> 订阅:

csharp
Game.OnGameTriggerInitialization += () =>
{
    Trigger<EventItemQualityChange>.Subscribe(e =>
    {
        Game.Logger.LogInformation("物品品质变更: {Quality} -> {NewQuality}",
            e.QualityPrevious, e.Quality);
    });
};

完整示例 ​

创建物品并放入背包 ​

csharp
#if SERVER
var item = myItemPickableLink.Data!.CreateItem(spawnPoint);
var pickable = item as ItemPickable;
if (pickable != null)
{
    var inventory = targetUnit.GetComponent<InventoryManager>();
    if (inventory != null)
    {
        pickable.PickUp(inventory);
    }
}
#endif

配置装备物品(数编代码) ​

csharp
#if SERVER
var itemMod = new ItemMod(unit, myItemModLink);
// 装备后自动应用 Modifications 中配置的属性修改
// 如需动态添加额外加成:
itemMod.DynamicModifications.SetModification(
    ItemSlotType.Equip,
    myPropertyLink,       // IGameLink<GameDataUnitProperty>
    (Fixed)100,
    PropertySubType.Base
);
#endif

使用增益消耗品 ​

增益消耗品通过 IPickUpItem 接口拾取,拾取后自动触发效果:

csharp
#if SERVER
// 创建增益物品
var powerUp = myPowerUpLink.Data!.CreateItem(spawnPoint);
// 当单位拾取时,自动执行 Effect 并销毁(如果 KillOnPowerUp = true)
#endif

品质特效管理 ​

csharp
#if CLIENT
// 品质特效自动管理:
// - 地面物品:根据 GameDataItemQuality.ActorArray 显示品质特效
// - 背包物品:不显示品质特效
// - 品质变更时:自动刷新特效
// 手动更新(通常不需要):
item.UpdateQualityActors();
#endif

相关文档 ​