首页 > 编程语言 >UE学习日志#3 GAS--ASC源码简要分析1

UE学习日志#3 GAS--ASC源码简要分析1

时间:2025-01-19 21:27:45浏览次数:3  
标签:-- void virtual ASC Owner 源码 override AbilityActorInfo

嘿我跟您说这坑一点也不大,AbilitySystemComponent.h也就两千行,.cpp也就三千多,乐

凡事要一点点来,我也就按每天的进度分p了。

1 类的继承关系和修饰符

先看这两行,为了方便看我加了换行

UCLASS(ClassGroup=AbilitySystem, 
hidecategories=(Object,LOD,Lighting,Transform,Sockets,TextureStreaming),
editinlinenew, 
meta=(BlueprintSpawnableComponent))
class GAMEPLAYABILITIES_API UAbilitySystemComponent : 
public UGameplayTasksComponent, 
public IGameplayTagAssetInterface, 
public IAbilitySystemReplicationProxyInterface

1.1 UCLASS里的说明符

1.ClassGroup

        这里是官方文档里的说明,看说明是用来方便视图分类的,但是我找了半天这个GroupView硬是没找到,希望有知道的大佬为我解惑

2.hidecategories

        隐藏指定Category的属性,这里隐藏的都是些渲染和Transform等属性,作为处理中心ASC当然用不到这些。

3.editinlinenew

        可以直接在编辑器中创建该类的对象,会传递给所有子类,可以用NotEditInlineNew重载覆盖。

 4.meta=(BlueprintSpawnableComponent)

        可以在蓝图中生成

1.2 继承关系

继承UGameplayTasksComponent,用于管理任务相关的操作,例如某些异步任务,找了下源文件UGameplayTasksComponent就是继承UActorComponent的

实现IGameplayTagAssetInterface接口,使支持标签的管理

实现IAbilitySystemReplicationProxyInterface,使支持网络同步和复制

2 继承自原生组件的接口

        在海量的代码里无从下手的情况下,我选择先去看UE自带的一些关于生命周期的接口,.h里也把他们都写在一起了:

	// ----------------------------------------------------------------------------------------------------------------
	//  Component overrides
	// ----------------------------------------------------------------------------------------------------------------

	virtual void InitializeComponent() override;
	virtual void UninitializeComponent() override;
	virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
	virtual bool GetShouldTick() const override;
	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
	virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& Objs) override;
	virtual bool ReplicateSubobjects(class UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
	/** Force owning actor to update it's replication, to make sure that gameplay cues get sent down quickly. Override to change how aggressive this is */
	virtual void ForceReplication() override;
	virtual void PreNetReceive() override;
	virtual void PostNetReceive() override;
	virtual void OnRegister() override;
	virtual void OnUnregister() override;
	virtual void ReadyForReplication() override;
	virtual void BeginPlay() override;

这里除了网络相关的几个其他的都是继承自UActorComponent里的,顺序大概是这样:

OnRegister()-->

InitializeComponent()-->

BeginPlay()-->

TickComponent()-->

UninitializeComponent()-->

OnUnregister()-->

OnComponentDestroyed()

2.1 OnRegister

总的来说就是处理GA、GE、GC要注册的东西,根据数据表初始化AS

void UAbilitySystemComponent::OnRegister()
{
	Super::OnRegister();

	// Cached off netrole to avoid constant checking on owning actor
    //缓存网络角色避免持续检测owning actor
	CacheIsNetSimulated();

	// Init starting data
    //就是实现用数据表初始化AS
	for (int32 i=0; i < DefaultStartingData.Num(); ++i)
	{
		if (DefaultStartingData[i].Attributes && DefaultStartingData[i].DefaultStartingTable)
		{
			UAttributeSet* Attributes = const_cast<UAttributeSet*>(GetOrCreateAttributeSubobject(DefaultStartingData[i].Attributes));
			Attributes->InitFromMetaDataTable(DefaultStartingData[i].DefaultStartingTable);
		}
	}

    //ActiveGameplayEffects是FActiveGameplayEffectsContainer类型的
    //用Owner注册
	ActiveGameplayEffects.RegisterWithOwner(this); 
                ActiveGameplayEffects.SetIsUsingReplicationCondition(bUseReplicationConditionForActiveGameplayEffects);
    //FGameplayAbilitySpecContainer ActivatableAbilities
	ActivatableAbilities.RegisterWithOwner(this);
    //FActiveGameplayCueContainer ActiveGameplayCues
	ActiveGameplayCues.bMinimalReplication = false;
	ActiveGameplayCues.SetOwner(this);	
/** Replicated gameplaycues when in minimal replication mode. These are cues that would come normally come from ActiveGameplayEffects (but since we do not replicate AGE in minimal mode, they must be replicated through here)
	UPROPERTY(Replicated)
	FActiveGameplayCueContainer MinimalReplicationGameplayCues;*/
	MinimalReplicationGameplayCues.bMinimalReplication = true;
	MinimalReplicationGameplayCues.SetOwner(this);

	UpdateActiveGameplayEffectsReplicationCondition();
	UpdateMinimalReplicationGameplayCuesCondition();

PRAGMA_DISABLE_DEPRECATION_WARNINGS
	// This field is not replicated (MinimalReplicationTags has a custom serializer),
	// so we don't need to mark it dirty.
	MinimalReplicationTags.Owner = this;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
	ReplicatedLooseTags.Owner = this;

	/** Allocate an AbilityActorInfo. Note: this goes through a global function and is a SharedPtr so projects can make their own AbilityActorInfo */
    // 分配一个 AbilityActorInfo 实例。这个实例通过全局函数创建,并且是一个共享指针,允许项目自           //定义 AbilityActorInfo。
	// 如果 AbilityActorInfo 无效(即未创建过),则创建一个新的实例
	if(!AbilityActorInfo.IsValid())
	{
		AbilityActorInfo = TSharedPtr<FGameplayAbilityActorInfo>(UAbilitySystemGlobals::Get().AllocAbilityActorInfo());
	}

	// Ensure bDestroyActiveStateInitiated is clear in case component is re-entering play 
	bDestroyActiveStateInitiated = false; 
}

2.2 InitializeComponent 

(1.19补充)先贴在这,大概就是处理一些AS相关的初始化,之后看了AS部分会细化

void UAbilitySystemComponent::InitializeComponent()
{
	Super::InitializeComponent();

	// Look for DSO AttributeSets (note we are currently requiring all attribute sets to be subobjects of the same owner. This doesn't *have* to be the case forever.
	AActor *Owner = GetOwner();
	InitAbilityActorInfo(Owner, Owner);	// Default init to our outer owner

	// cleanup any bad data that may have gotten into SpawnedAttributes
	for (int32 Idx = SpawnedAttributes.Num()-1; Idx >= 0; --Idx)
	{
		if (SpawnedAttributes[Idx] == nullptr)
		{
			SpawnedAttributes.RemoveAt(Idx);
		}
	}

	TArray<UObject*> ChildObjects;
	GetObjectsWithOuter(Owner, ChildObjects, false, RF_NoFlags, EInternalObjectFlags::Garbage);

	for (UObject* Obj : ChildObjects)
	{
		UAttributeSet* Set = Cast<UAttributeSet>(Obj);
		if (Set)  
		{
			SpawnedAttributes.AddUnique(Set);
		}
	}

	SetSpawnedAttributesListDirty();
}

2.3 BeginPlay

void UAbilitySystemComponent::BeginPlay()
{
	Super::BeginPlay();

	// Cache net role here as well since for map-placed actors on clients, the Role may not be set correctly yet in OnRegister.
// 缓存网络角色因为对于在客户端放置的地图Actor
	// 其角色可能尚未在 OnRegister 中正确设置,因此我们在 BeginPlay 中再做一次缓存
	CacheIsNetSimulated();
}

2.4 TickComponent

大概是这样:

1.更新动画蒙太奇的数据

2.调用父类TickComponent

3.Tick实现了ITickableAttributeSetInterface的AS

void UAbilitySystemComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{	
	SCOPE_CYCLE_COUNTER(STAT_TickAbilityTasks);
	CSV_SCOPED_TIMING_STAT_EXCLUSIVE(AbilityTasks);

	if (IsOwnerActorAuthoritative())
	{
		AnimMontage_UpdateReplicatedData();
	}

	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	for (UAttributeSet* AttributeSet : GetSpawnedAttributes())
	{
		ITickableAttributeSetInterface* TickableSet = Cast<ITickableAttributeSetInterface>(AttributeSet);
		if (TickableSet && TickableSet->ShouldTick())
		{
			TickableSet->Tick(DeltaTime);
		}
	}
}

值得一提的是开发者好像打算用另一种定时器机制来管理Tick

PrimaryComponentTick.bStartWithTickEnabled = true; // FIXME! Just temp until timer manager figured out

2.5 UninitializeComponent

多在父类基础上多调用了一行这个:

ActiveGameplayEffects.Uninitialize();

GE相关的Uninitialize 

2.6 OnUnregister

void UAbilitySystemComponent::OnUnregister()
{
	Super::OnUnregister();

	DestroyActiveState();
    //取消所有能力并销毁任何剩余的实例化能力
}

2.7 OnComponentDestroyed

        核心是调用DestroyActiveState,这个函数的具体解析后边的文章里写了,然后就是AS的销毁,是为了防止移除并重新添加level的时候直接uninit并且re-init但没有销毁。

void UAbilitySystemComponent::OnComponentDestroyed(bool bDestroyingHierarchy)
{
	DestroyActiveState();

	// The MarkPendingKill on these attribute sets used to be done in UninitializeComponent,
	// but it was moved here instead since it's possible for the component to be uninitialized,
	// and later re-initialized, without being destroyed - and the attribute sets need to be preserved
	// in this case. This can happen when the owning actor's level is removed and later re-added
	// to the world, since EndPlay (and therefore UninitializeComponents) will be called on
	// the owning actor when its level is removed.
	for (UAttributeSet* Set : GetSpawnedAttributes())
	{
		if (Set)
		{
			Set->MarkAsGarbage();
		}
	}

	// Call the super at the end, after we've done what we needed to do
	Super::OnComponentDestroyed(bDestroyingHierarchy);
}

(未完待续,持续更新)

标签:--,void,virtual,ASC,Owner,源码,override,AbilityActorInfo
From: https://blog.csdn.net/Caint0/article/details/145197264

相关文章

  • 那些年我在 HL 集训做的题【某人别催了!】
    Day01.16下午到HL,居然还写了一道题?P8855[POI2002]商务旅行LCA板子。不理解当时为啥要写这个东东,可能是为了热热身吧。Day1讲整体二分,但是没听懂。貌似是魔改版CDQ...不管它。但是我似乎发现了一片新天地,一切的一切都从下面的一道题说起:P3157[CQOI2011]动态逆序对......
  • 解题报告-论对“差分约束”的新理解
    解题报告-论对“差分约束”的新理解上次说整体计数的时候,我们曾经谈到过,可以把“约束关系”看作一条条边而连之,最后形成一堆连通块。而在我们所说的“约束关系”中,有一部分是这样的:\(a_i\leb_i+c\)。这样的情况有“差分”,有“约束”,所以是“差分约束”。差分约束一般情形是,\(a......
  • Mac 刷题环境配置
    Mac刷题环境配置这篇博文主要记录自己为了更方便的在Mac上写算法题,主要是基于Clion做的一些环境配置;有些操作其实在Windows,Linux下也是通用的,如果看到的小伙伴也可以结合自己的情况参考。Clion插件推荐一下这个插件C/C++SingleFileExecution,因为刷算法题主要是单......
  • docker在网桥模式下主机端口映射到容器端口的原理
    前置知识iptables:捕获并控制容器和主机之间的流量,可以通过iptables-tnat-nL命令查看iptables的(S/D)NAT规则docker0:虚拟交换机veth1b62ff4@if56:虚拟交换机的虚拟接口上下两个虚拟接口成对出现eth0@if57:容器的虚拟接口网络环境CentOS:ens33->192.168.40.180/24、docker......
  • 7-50 三天打鱼两天晒网PTA
    中国有句俗语叫“三天打鱼两天晒网”。假设某人从某天起,开始“三天打鱼两天晒网”,问这个人在以后的第N天中是“打鱼”还是“晒网”?输入格式:输入在一行中给出一个不超过1000的正整数N。输出格式:在一行中输出此人在第N天中是“Fishing”(即“打鱼”)还是“Drying”(即“晒网”),并......
  • 7-51 输出三角形面积和周长PTA
    本题要求编写程序,根据输入的三角形的三条边a、b、c,计算并输出面积和周长。注意:在一个三角形中,任意两边之和大于第三边。三角形面积计算公式:area=s(s−a)(s−b)(s−c)​,其中s=(a+b+c)/2。输入格式:输入为3个正整数,分别代表三角形的3条边a、b、c。输出格式:如果输入的边能构成......
  • 蓝桥杯备赛笔记(九)动态规划(一)
    1.动态规划基础(1)线性DP1)什么是DP(动态规划)DP(动态规划)全称DynamicProgramming,是运筹学的一个分支,是一种将复杂问题分解成很多重叠的子问题,并通过子问题的解得到整个问题的解的算法。在动态规划中有一些概念:状态:就是形如dp[i][j]=val的取值,其中i,j为下标,也是用于描述、......
  • CISCO基础
    CISCO基础1、连接状态这张图片中,展示了Cisco的设备集合以及连线集合其中,黄色小箭头为自动连线连接状态:每个小圆点为一个设备的不同端口,圆点颜色代表连接状态,例如,圆点为绿色,则为联通状态。在cisco中有一些不能自动连接的设备,如:路由器(正常连接呈现的颜色为红色,即为关闭......
  • 【SLAM】扩展卡尔曼滤波器机器人SLAM滤波跟踪(维多利亚公园为基准,地标是激光扫描仪探测
    ......
  • 【潮流计算】牛顿拉夫逊法解潮流【含GUI Matlab源码 11034期】
    ......