UE4 范围伤害RadiusDamage及碰撞检测通道ECollisionChanel

UE4的RadiusDamage函数在进行范围伤害计算时,首先通过物理检测获取所有非WorldStatic的Component,然后在特定的碰撞通道上进行射线检测。若某个Component的碰撞类型匹配特定过滤条件,例如ECC_GameTraceChannel3,则该Component不会受到伤害。这种方法可以避免特定Component接收伤害,而其他Component不受范围内物体阻挡的影响。注意ECC_EngineTraceChannel1与ECC_GameTraceChannel1的区别。
部署运行你感兴趣的模型镜像

UE4的范围伤害函数为

/** Hurt locally authoritative actors within the radius. Will only hit components that block the Visibility channel.
...
 * @param DamagePreventionChannel - Damage will not be applied to victim if there is something between the origin and the victim which blocks traces on this channel
 ...
 */
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Game|Damage", meta=(WorldContext="WorldContextObject", AutoCreateRefTerm="IgnoreActors"))
static bool ApplyRadialDamageWithFalloff(const UObject* WorldContextObject, float BaseDamage, float MinimumDamage, const FVector& Origin, float DamageInnerRadius, float DamageOuterRadius, float DamageFalloff, TSubclassOf<class UDamageType> DamageTypeClass, const TArray<AActor*>& IgnoreActors, AActor* DamageCauser = NULL, AController* InstigatedByController = NULL, ECollisionChannel DamagePreventionChannel = ECC_Visibility);

函数参数除伤害值和伤害范围外还有一个DamagePreventionChannel,该值是碰撞通道枚举值ECC类型的,作用是检测伤害中心与Actor在该通道上是否有阻挡,有的话不造成伤害,该值默认是ECC_Visibility,意味着编辑器里所有勾选了Visiblity的TraceChanel的Actor均会阻挡伤害,可以改成ECC_MAX来取消掉阻挡检测
if (DamagePreventionChannel == ECC_MAX || ComponentIsDamageableFrom(Overlap.Component.Get(), Origin, DamageCauser, IgnoreActors, DamagePreventionChannel, Hit))
				{
					TArray<FHitResult>& HitList = OverlapComponentMap.FindOrAdd(OverlapActor);
					HitList.Add(Hit);
				}

但是这里有一个点,就是这个通道是在检测完球体内的component后才进行过滤的,而这个检测是调用的physics的检测,

TArray<FOverlapResult> Overlaps;
	UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject);
	World->OverlapMultiByObjectType(Overlaps, Origin, FQuat::Identity, FCollisionObjectQueryParams(FCollisionObjectQueryParams::InitType::AllDynamicObjects), FCollisionShape::MakeSphere(DamageOuterRadius), SphereParams); 

这个会检测到所有非worldstatic的component


如图,abc为伤害范围内Actor的component,引擎首先获取到这些component放到TArray<FOverlapResult> Overlaps里,再通过在特定通道上的射线检测确定能否造成伤害,如图中a如果在特定通道上被阻挡将不会接受伤害。

如果想要某个特定component不接受RadiusDamage而其他component又不受范围内物体阻挡不修改引擎是没有办法实现的,一种简单粗暴的方法是给这个特定的component设置拿一个单独的碰撞类型到Overlaps后判断其碰撞类型为这个特定类型则不处理后续的伤害

if (Overlap.Component->GetCollisionObjectType()!=ECC_GameTraceChannel3)//to filter RadiusDamage ObjectType

这里ECC_GameTraceChannel3即使特定的碰撞类型,在C++里定义在EngineTypes.h里,注意ECC_EngineTraceChannel1与ECC_GameTraceChannel1的区别。

UENUM(BlueprintType)
enum ECollisionChannel
{

	ECC_WorldStatic UMETA(DisplayName="WorldStatic"),
	ECC_WorldDynamic UMETA(DisplayName="WorldDynamic"),
	ECC_Pawn UMETA(DisplayName="Pawn"),
	ECC_Visibility UMETA(DisplayName="Visibility" , TraceQuery="1"),
	ECC_Camera UMETA(DisplayName="Camera" , TraceQuery="1"),
	ECC_PhysicsBody UMETA(DisplayName="PhysicsBody"),
	ECC_Vehicle UMETA(DisplayName="Vehicle"),
	ECC_Destructible UMETA(DisplayName="Destructible"),

	/** Reserved for gizmo collision */
	ECC_EngineTraceChannel1 UMETA(Hidden),

	ECC_EngineTraceChannel2 UMETA(Hidden),
	...
	ECC_EngineTraceChannel6 UMETA(Hidden),

	ECC_GameTraceChannel1 UMETA(Hidden),
	ECC_GameTraceChannel2 UMETA(Hidden),
	ECC_GameTraceChannel3 UMETA(Hidden),
	...
	ECC_GameTraceChannel18 UMETA(Hidden),
	
	/** Add new serializeable channels above here (i.e. entries that exist in FCollisionResponseContainer) */
	/** Add only nonserialized/transient flags below */

	// NOTE!!!! THESE ARE BEING DEPRECATED BUT STILL THERE FOR BLUEPRINT. PLEASE DO NOT USE THEM IN CODE

	ECC_OverlapAll_Deprecated UMETA(Hidden),
	ECC_MAX,
};


在编辑器里定义在Project\Config\DefaultEngine.ini里

+DefaultChannelResponses=(Channel=ECC_GameTraceChannel3,Name="RadiusDamage",...

在编辑器里设置好默认值,默认对所有其他通道忽略,只有特定component的碰撞类型设置为这个"RadiusDamage"即可。

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值