主题
物品系统
物品系统管理游戏中的所有物品,包括可拾取物品、装备/模组物品和增益消耗品。物品挂载在单位上,通过背包系统进行拾取、装备和丢弃,并支持品质、等级、堆叠和动态属性修改。
核心类型
| 类型 | 说明 |
|---|---|
GameDataItem | 物品数编基类(抽象),定义显示信息、关联单位、品质、等级和过滤器 |
GameDataItemPickable | 可拾取物品数编,定义堆叠、丢弃、出售等行为 |
GameDataItemMod | 装备/模组物品数编,定义各槽位属性修改和装备需求 |
GameDataItemPowerUp | 增益消耗品数编,使用后对目标施加效果 |
GameDataItemQuality | 品质配置,定义颜色、图标装饰和地面特效 |
Item | 物品运行时基类(抽象),管理品质、等级、分类 |
ItemPickable | 可拾取物品实例,支持堆叠、背包槽位、拾取和丢弃 |
ItemMod | 装备/模组物品实例,提供属性修改、技能授予和动态修改 |
ItemPowerUp | 增益消耗品实例,使用后施加效果并可自动销毁 |
DynamicModification | 动态属性修改项(运行时通过代码添加) |
DynamicModificationManager | 管理物品上的动态属性修改(仅服务端) |
类型继承关系
GameDataItem (abstract)
└── GameDataItemPickable
└── GameDataItemMod
└── GameDataItemPowerUp
Item (abstract) : TagComponent
└── ItemPickable
└── ItemMod
└── ItemPowerUpGameDataItem 配置
所有物品数编的公共基类。
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);
#endifGameDataItemPickable
继承自 GameDataItem,添加堆叠和丢弃相关配置。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
StackStart | uint | 1 | 创建时的初始堆叠数 |
StackMax | uint? | null | 最大堆叠数,null 表示无限制 |
CanStack | bool | true | 是否允许堆叠 |
CanAbsorb | bool | true | 堆叠时是否自动吸收同种物品 |
CanDrop | bool | false | 是否允许丢弃到地面 |
CanSell | bool | false | 是否允许出售给商店 |
RemoveOnDrop | bool | false | 丢弃时直接移除(不生成地面物品) |
KillOnDepleted | bool | true | 堆叠数为 0 时自动销毁 |
GameDataItemMod
继承自 GameDataItemPickable,添加装备相关配置。
| 属性 | 类型 | 说明 |
|---|---|---|
Modifications | QuickDictionary<ItemSlotType, ItemUnitModificationData> | 各槽位的属性修改配置 |
Requirements | UnitPropertyRequirements | 装备需求条件 |
ItemUnitModificationData 包含该槽位下的属性加成、状态变更、授予技能和附属 Actor 等配置。
GameDataItemPowerUp
继承自 GameDataItem(直接继承,不经过 GameDataItemPickable)。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Effect | IGameLink<GameDataEffect>? | null | 使用后施加的效果 |
KillOnPowerUp | bool | true | 使用后是否销毁 |
GameDataItemQuality
品质视觉配置,通过 GameDataGameplay.ItemQualityList 全局注册。
| 属性 | 类型 | 说明 |
|---|---|---|
Color | Color | 品质颜色(用于名称等 UI 元素着色) |
BackgroundImage | Icon | 物品图标的背景装饰 |
BorderImage | Icon | 物品图标的边框装饰 |
ActorArray | List<IGameLink<GameDataActor>>? | 地面物品的品质特效 Actor |
物品通过 Item.Quality 值作为索引,从 ItemQualityList 中查找对应配置。
Item 运行时基类
所有物品实例的公共基类,挂载在单位上(TagComponent)。
属性
| 属性 | 类型 | 说明 |
|---|---|---|
Link | IGameLink<GameDataItem> | 物品数编链接 |
Cache | GameDataItem | 数编缓存 |
Unit | Unit | 物品所属的单位 |
Quality | uint | 品质等级(服务端可写,客户端只读) |
Level | uint | 物品等级(服务端可写,客户端只读) |
Categories | List<ItemCategory> | 分类列表(来自数编) |
QualityConfiguration | GameDataItemQuality? | 当前品质对应的视觉配置 |
方法
| 方法 | 说明 |
|---|---|
HasCategory(ItemCategory) | 检查物品是否属于指定分类 |
GetComponent<T>(Entity) | 扩展方法,从实体获取物品组件 |
获取物品组件
csharp
var item = entity.GetComponent<Item>();
var itemMod = entity.GetComponent<ItemMod>();ItemPickable
可拾取物品,支持堆叠、背包和拾取/丢弃交互。
属性
| 属性 | 类型 | 说明 |
|---|---|---|
Stack | uint | 当前堆叠数(服务端可写) |
StackMax | uint? | 最大堆叠数 |
CanStack | bool | 是否可堆叠 |
AbsorbEnabled | bool | 是否启用自动吸收 |
Slot | InventorySlot? | 当前所在的背包槽位 |
SlotType | ItemSlotType? | 当前槽位类型 |
Carrier | Unit? | 携带者单位(在背包中时非空) |
MeetRequirement | bool | 是否满足装备需求 |
方法
| 方法 | 说明 |
|---|---|
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);
#endifItemMod
装备/模组物品,装备后可修改持有者的属性并授予技能。继承自 ItemPickable。
核心机制
- 属性修改:根据装备的槽位类型(
ItemSlotType),应用对应的属性修改(ModificationManager) - 技能授予:装备后可自动创建并授予技能(
ActiveAbility) - 需求检查:可设置装备需求(
UnitPropertyRequirements),不满足时IsEnabled为 false - 堆叠影响:堆叠数变化时自动更新属性修改倍率
属性
| 属性 | 类型 | 说明 |
|---|---|---|
IsEnabled | bool | 是否启用(满足需求时为 true) |
ActiveAbility | Ability? | 当前授予的技能 |
ActiveModificationManager | ModificationManager? | 当前激活的属性修改管理器 |
ModificationManagers | QuickDictionary<ItemSlotType, ModificationManager> | 各槽位的修改管理器 |
DynamicModifications | DynamicModificationManager | 动态修改管理器(仅服务端) |
服务端方法
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);
#endifItemPowerUp
增益消耗品,被单位拾取后可施加效果。继承自 Item(不经过 ItemPickable)。
使用流程(服务端):
PreValidate— 创建效果实例并预验证Execute— 解析目标并执行效果- 如果
KillOnPowerUp为 true,执行后自动销毁
物品事件
| 事件类 | 属性 | 触发时机 |
|---|---|---|
EventItemSlotChange | Item, Slot, SlotPrevious | 物品槽位变更 |
EventItemStackChange | Item, Stack, StackPrevious | 堆叠数变更 |
EventItemLevelChange | Item, Level, LevelPrevious | 等级变更 |
EventItemQualityChange | Item, 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相关文档
- 效果系统 — ItemPowerUp 使用的效果树
- 技能系统 — ItemMod 授予的技能
- Buff 系统 — 通过效果树为物品附加 Buff
- 单位系统 — 物品挂载的宿主单位
- GameSystemUI 背包控件 — 背包窗口、快捷栏和拾取按钮的客户端 UI 接入