ue3d游戏标签堆栈容器

游戏标签堆栈容器

分类:

这是一个非常简单的容器,它允许将游戏标签复制为堆栈计数,用于武器弹药、库存物品计数、统计点等内容。

ue3d - 游戏标签堆栈容器

这是头文件:

USTRUCT(BlueprintType)
struct FKaosGameplayTagStack : public FFastArraySerializerItem
{
    GENERATED_BODY()
 
    FKaosGameplayTagStack()
    {}
 
    FKaosGameplayTagStack(FGameplayTag InTag, int32 InCount)
        : Tag(InTag)
    {
        Tag = InTag;
        Count = InCount;
    }
 
private:
    friend FKaosGameplayTagStackContainer;
 
    UPROPERTY()
    FGameplayTag Tag;
 
    UPROPERTY()
    int32 Count = 0;
 
};
 
 
USTRUCT(BlueprintType)
struct FKaosGameplayTagStackContainer : public FFastArraySerializer
{
    GENERATED_BODY()
 
    FKaosGameplayTagStackContainer() { }
 
public:
 
    void PreReplicatedRemove(const TArrayView<int32> RemovedIndices, int32 FinalSize);
    void PostReplicatedAdd(const TArrayView<int32> AddedIndices, int32 FinalSize);
    void PostReplicatedChange(const TArrayView<int32> ChangedIndices, int32 FinalSize);
     
    bool NetDeltaSerialize(FNetDeltaSerializeInfo& DeltaParms)
    {
        return FastArrayDeltaSerialize<FKaosGameplayTagStack, FKaosGameplayTagStackContainer>(Stacks, DeltaParms, *this);
    }
 
    /* 
     * 将计数添加到标签的堆栈中
     */
    void AddStackCount(FGameplayTag Tag, int32 Count);
 
    /*
     * 从标签的堆栈中删除计数
     */
    void RemoveStackCount(FGameplayTag Tag, int32 Count);
     
    /* 
     * 如果堆栈中有一个或多个标签,则返回 true。
     */
    bool HasTag(FGameplayTag Tag) const
    {
        return TagToCountMap.Contains(Tag);
    }
     
    /*
     * 返回我们为提供的标签所拥有的堆栈数量
     */
    int32 GetStackCount(FGameplayTag Tag) const
    {
        return TagToCountMap.FindRef(Tag);
    }
     
 
private:
    // 游戏标签堆栈列表,使用加速的 TagCountMap 来检查标签计数等。
    UPROPERTY()
    TArray<FKaosGameplayTagStack> Stacks;
     
    // 查询的加速列表
    TMap<FGameplayTag, int32> TagCountMap;
};
 
template<>
struct TStructOpsTypeTraits<FKaosGameplayTagStackContainer> : public TStructOpsTypeTraitsBase2<FKaosGameplayTagStackContainer>
{
    enum
    {
        WithNetDeltaSerializer = true,
    };
};

和 CPP 文件部分:

void FKaosGameplayTagStackContainer::AddStackCount(FGameplayTag Tag, int32 Count)
{
    if (Count > 0)
    {
        for (FKaosGameplayTagStack& Stack : Stacks)
        {
            if (Stack.Tag == Tag)
            {
                const int32 NewCount = Stack.Count + Count;
                Stack.Count = NewCount;
                TagCountMap[Tag] = NewCount;
                MarkItemDirty(Stack);
                return;
            }
        }
 
        FKaosGameplayTagStack& NewStack = Stacks.Emplace_GetRef(Tag, Count);
        MarkItemDirty(NewStack);
        TagCountMap.Add(Tag, Count);
    }
}
 
void FKaosGameplayTagStackContainer::RemoveStackCount(FGameplayTag Tag, int32 Count)
{
    if (Count > 0)
    {
        for (auto It = Stacks.CreateIterator(); It; ++It)
        {
            FKaosGameplayTagStack& Stack = *It;
            if (Stack.Tag == Tag)
            {
                if (Stack.Count <= Count)
                {
                    It.RemoveCurrent();
                    TagCountMap.Remove(Tag);
                    MarkArrayDirty();
                }
                else
                {
                    const int32 NewCount = Stack.Count - Count;
                    Stack.Count = NewCount;
                    TagCountMap[Tag] = NewCount;
                    MarkItemDirty(Stack);
                }
                return;
            }
        }
    }
}
 
void FKaosGameplayTagStackContainer::PreReplicatedRemove(const TArrayView<int32> RemovedIndices, int32 FinalSize)
{
    for (const int32 Index : RemovedIndices)
    {
        const FGameplayTag Tag = Stacks[Index].Tag;
        TagCountMap.Remove(Tag);
    }
}
 
void FKaosGameplayTagStackContainer::PostReplicatedAdd(const TArrayView<int32> AddedIndices, int32 FinalSize)
{
    for (const int32 Index : AddedIndices)
    {
        const FKaosGameplayTagStack& Stack = Stacks[Index];
        TagCountMap.Add(Stack.Tag, Stack.Count);
    }
}
 
void FKaosGameplayTagStackContainer::PostReplicatedChange(const TArrayView<int32> ChangedIndices, int32 FinalSize)
{
    for (const int32 Index : ChangedIndices)
    {
        const FKaosGameplayTagStack& Stack = Stacks[Index];
        TagCountMap[Stack.Tag] = Stack.Count;
    }
}

要使用它,只需在某处添加一个复制属性:

属性使用标准的 C++ 变量语法声明,前面用 UPROPERTY 宏来定义属性元数据和变量说明符。

UPROPERTY(Replicated)
FKaosGameplayTagStackContainer GameplayStats;

可以这样类似使用它:

void AMyCharacter::AddStatTagCount(FGameplayTag Tag, int32 Count)
{
   GameplayStats.AddStack(Tag, Count);
}
 
void AMyCharacter::RemoveStatTagCount(FGameplayTag Tag, int32 Count)
{
   GameplayStats.RemoveStack(Tag, Count);
}
 
int32 AMyCharacter::GetStatTagStackCount(FGameplayTag Tag) const
{
    return GameplayStats.GetStackCount(Tag);
}
 
bool AMyCharacter::HasStatTag(FGameplayTag Tag) const
{
    return GameplayStats.ContainsTag(Tag);
}

相关信息

  • 类型:知识
  • 字数:199
  • 字符:4655
  • 适用软件:虚幻引擎
  • 说明:无
  • 编号:87083

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!