#include"PhysicsEngine/RadialForceComponent.h"
//将ForceComp附加到MeshComp上
ForceComp->SetupAttachment(MeshComp);
//设置force的半径
ForceComp->Radius = 750.0f;
//设置force的力度
ForceComp->ImpulseStrength = 2500.f;
//设置效果是否与物理相关,比如是否考虑质量
ForceComp->bImpulseVelChange = true;
//设置作用对象的碰撞类型
ForceComp->AddCollisionChannelToAffect(ECC_WorldDynamic);
//是否考虑将力作用到组件的拥有者
ForceComp->bIgnoreOwningActor = false;
源码分析:
ForceComp->FireImpulse();
对于FireImpulse
void URadialForceComponent::FireImpulse()
{
const FVector Origin = GetComponentLocation();
// Find objects within the sphere
TArray<FOverlapResult> Overlaps;
FCollisionQueryParams Params(SCENE_QUERY_STAT(FireImpulseOverlap), false);
// Ignore owner actor if desired
if (bIgnoreOwningActor)
{
Params.AddIgnoredActor(GetOwner());
}
GetWorld()->OverlapMultiByObjectType(Overlaps, Origin, FQuat::Identity, CollisionObjectQueryParams, FCollisionShape::MakeSphere(Radius), Params);
// A component can have multiple physics presences (e.g. destructible mesh components).
// The component should handle the radial force for all of the physics objects it contains
// so here we grab all of the unique components to avoid applying impulses more than once.
TArray<UPrimitiveComponent*, TInlineAllocator<1>> AffectedComponents;
AffectedComponents.Reserve(Overlaps.Num());
for(FOverlapResult& OverlapResult : Overlaps)
{
if(UPrimitiveComponent* PrimitiveComponent = OverlapResult.Component.Get())
{
AffectedComponents.AddUnique(PrimitiveComponent);
}
}
for(UPrimitiveComponent* PrimitiveComponent : AffectedComponents)
{
if(DestructibleDamage > SMALL_NUMBER)
{
if(IDestructibleInterface* DestructibleInstance = Cast<IDestructibleInterface>(PrimitiveComponent))
{
DestructibleInstance->ApplyRadiusDamage(DestructibleDamage, Origin, Radius, ImpulseStrength, Falloff == RIF_Constant);
}
}
// Apply impulse
PrimitiveComponent->AddRadialImpulse(Origin, Radius, ImpulseStrength, Falloff, bImpulseVelChange);
// See if this is a target for a movement component, if so apply the impulse to it
if (PrimitiveComponent->bIgnoreRadialImpulse == false)
{
TInlineComponentArray<UMovementComponent*> MovementComponents;
if(AActor* OwningActor = PrimitiveComponent->GetOwner())
{
OwningActor->GetComponents<UMovementComponent>(MovementComponents);
for(const auto& MovementComponent : MovementComponents)
{
if(MovementComponent->UpdatedComponent == PrimitiveComponent)
{
MovementComponent->AddRadialImpulse(Origin, Radius, ImpulseStrength, Falloff, bImpulseVelChange);
break;
}
}
}
}
}
}
大概可以理解为先判断组件拥有者是否受力,然后按照半径,获取半径内的Actor【这个要碰撞类型符合】,然后按照给定的设置【比如是否考虑物理】,最后受力
GetWorld()->OverlapMultiByObjectType(Overlaps, Origin, FQuat::Identity, CollisionObjectQueryParams, FCollisionShape::MakeSphere(Radius), Params);