UE4 范围伤害RadiusDamage及碰撞检测通道ECollisionChanel
2017-10-28 17:16
651 查看
UE4的范围伤害函数为
函数参数除伤害值和伤害范围外还有一个DamagePreventionChannel,该值是碰撞通道枚举值ECC类型的,作用是检测伤害中心与Actor在该通道上是否有阻挡,有的话不造成伤害,该值默认是ECC_Visibility,意味着编辑器里所有勾选了Visiblity的TraceChanel的Actor均会阻挡伤害,可以改成ECC_MAX来取消掉阻挡检测
但是这里有一个点,就是这个通道是在检测完球体内的component后才进行过滤的,而这个检测是调用的physics的检测,
这个会检测到所有非worldstatic的component
![](https://img-blog.csdn.net/20171103103401174?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcG14ZzIwMTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
如图,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的区别。
在编辑器里定义在Project\Config\DefaultEngine.ini里
在编辑器里设置好默认值,默认对所有其他通道忽略,只有特定component的碰撞类型设置为这个"RadiusDamage"即可。
/** 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"即可。
相关文章推荐
- UE4碰撞检测、自动寻路、追踪及小电梯
- ue4 4.18NPC碰撞检测的一些问题
- (转载)ue4碰撞检测及射线查询--LineTraceSingleByChannel 和 LineTraceSingleByObjectType
- UE4物体的碰撞检测
- 【UE4】【C++】炮弹(子弹)使用方法(创建、作用力、范围伤害及接受伤害)
- ue4 碰撞检测测试
- Physx范围伤害检测
- UE4 C++ 碰撞检测(Overlap)
- ue4碰撞检测及射线查询
- 拖拽的基本函数(已有限制范围和修复浏览器默认行为以及磁性吸附、碰撞检测、改变层大小、模拟滚动条)
- UE4蓝图碰撞检测解析
- 运用DIV拖拽实现resize和碰撞检测
- OBB碰撞检测算法
- Unity3D检测(碰撞、射线)
- Unity3d中物体的的碰撞检测
- 任意角度的平行四边形的碰撞检测原理
- AS3 高效像素检测方法(优先,矩形,交集后,再利用通道像素差值混合)
- Java简单游戏开发之碰撞检测
- 【amazing cocos2d-x 3.0之十七】使用新物理引擎实现碰撞检测
- Java简单游戏开发之碰撞检测