关于Actor Component的思考--学习斯坦佛UE+C++

发布时间 2023-10-03 22:39:44作者: XTG111

跟着B站的视频学习,感觉自己的头很混乱。所以浅浅总结一下创建Actor Component之后其的作用和相关操作。

Actor Component

首先Component为一个组件,源码就是一个类的声明和类的实现。所以对其的操作就是对类的操作。可以在其源码内部定义一些物体属性,比如一个角色的Component。我们可以定义其的血量,属性等人物属性。

就拿目前学习到的血量来说,在声明中,定义血量float和对应的实现扣血的函数。然后在类的实现内部构造函数中初始化血量,并且在类的实现中编写函数原型。

或者说所有新建的源码文件都是这样构成的。

Component接入一个角色Actor

直接在Actor的头文件中,定义一个Component类的对象。然后在构造函数中初始化这个对象。

//.h
USAttributeComponent* AttributeComp;

//.cpp
AttributeComponent = CreateDefaultSubobject<USAttributeComponent>("AttributeComponent");

至此该Component就接入了这个Actor,所以该Actor拥有了Health和改变Health的函数方法。

对子弹实现攻击扣血功能

主要实现设置Health的函数方法中,Delta的值并且确定什么时候在Actor上调用改变Health的函数。
操作实现就只用编写一个函数,在函数中接受角色参数,然后通过调用传入的角色,获取Component属性,然后再将Delta值传入改变Health的函数方法即可。
课程中采用的是Overlap来判断粒子与角色的碰撞。使用了一个委托OnComponentBeginOverlap,使用这个委托对this(粒子)添加了一个事件&ASMagicProjectile::OnActorOverlap就是我们要编写的函数

SphereComp->OnComponentBeginOverlap.AddDynamic(this, &ASMagicProjectile::OnActorOverlap);

该函数的具体参数参考了这个委托的定义源码FComponentBeginOverlapSignature;

DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);

我们编写的这个OnActorOverlap函数源码如下

void ASMagicProjectile::OnActorOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OtherActor && OtherActor!=GetInstigator()) {
		//获取除了自己的其他对象的AttributeComponent属性
		USAttributeComponent* AttributeComp = Cast<USAttributeComponent>(OtherActor->GetComponentByClass(USAttributeComponent::StaticClass()));
		//如果有进行下一步操作,减少值
		if (AttributeComp) {
			AttributeComp->ApplyHealthChange(-1.0f);
			Destroy();
		}
	}
}

一个Actor是拥有多个接口的,我们利用GetComponentByClass来获取我们想要的Component。
USAttributeComponent::StaticClass()利用StaticClass()获取USAttributeComponent的class。之后利用cast强制转换把得到的这个Actor的Component转换为一个局部变量,然后操作这个局部变量调用改变Health的函数ApplyHealthChange()改变该Actor的血量。
image