【学习笔记】Unreal Engine 4 虚幻引擎蓝图中级教程物理碰撞教程

教程链接:Unreal Engine 4 虚幻引擎蓝图中级教程物理碰撞

想共享的小伙伴可以E-mail我:lxbcolorgalaxy@qq.com

目录

第一章 常见的物理现象及分析

1蓝图模板中的物理现象

2创建子弹抛射

3自动追踪

4碰撞事件

5纯物理模拟子弹

第二章 碰撞体

1简易碰撞体

2DOP碰撞体

3凸面碰撞体

4567UBX导入碰撞体

8从其他模型复制碰撞体

9碰撞体积

第三章 物理刚体

1物理刚体

2质量

3质心

4运动衰减

6运动空间锁定

第四章 碰撞通道

1类型、反馈、通道

2UE4中的碰撞设置

3碰撞案例测试

4类型与反馈案例

5添加自定义碰撞

第五章 碰撞事件

1ACTOR交叉触发

2OnComponent触发

3击中

4击伤事件

5伤害类型

6点伤害

7范围伤害规则

8完全伤害

第六章 射线检测

1零粗细(很细)射线检测

2零检测返回结果

4球体非零粗细检测

5调试检测结果

6多重零粗细检测

7盒子、胶囊体检测

8逐多边形检测


 

第一章 常见的物理现象及分析

1蓝图模板中的物理现象

分析了第一人称射击模板中的物理现象,比如子弹飞行、碰撞、产生力的效果与消失。

2创建子弹抛射

1.给子弹击中物体施加一个同方向的冲击力——子弹蓝图

 

2.子弹模型添加Projectile Movement Component组件,引擎自带的子弹模拟,可设置子弹参数

 

3.控制生成的子弹位置、播放角色动画

3自动追踪

1.设置子弹反弹参数

 

2.设置子弹追踪导航功能

蓝图中设置追踪目标

 

4碰撞事件

1.Overlap重叠事件(类似Unity里的触发器,又不同)两者均需要勾选Generate Overlap

5纯物理模拟子弹

1.删除projectile组件,更改Sphere Mesh的碰撞预设,给小球生成时添加Physics Linear Velocity,更改发射方向。

2.选中Actor,修改生命周期

第二章 碰撞体

1简易碰撞体

2DOP碰撞体

10DOP分别沿着X Y Z轴创建更复杂的碰撞体

3凸面碰撞体

 

4567UBX导入碰撞体

3DMAX中制作碰撞体的命名规则:盒型UBX、球形USP、不规则UCX,紧跟其中一个模型的名称。不规则时,每个内角要小于180°,是一个凸边形。

 

8从其他模型复制碰撞体

选中其他已有碰撞体的相同模型,在无碰撞体的模型中选择Copy

9碰撞体积

Blocking Volume通常当作场景的边界碰撞盒,可同BSP模型一样进行编辑修改

第三章 物理刚体

1物理刚体

2质量

3质心

4运动衰减

6运动空间锁定

第四章 碰撞通道

1类型、反馈、通道

Object Type ——> Response ——> Channel

2UE4中的碰撞设置

3碰撞案例测试

1.阴影烘培效果,Movable是实时的,Static需要构建

2.可破坏物体 设置碰撞时可破碎

3.各种Object Response设置

4类型与反馈案例

5添加自定义碰撞

 

第五章 碰撞事件

1ACTOR交叉触发

Event ActorBeginOverlap——碰撞物体触发

Event ActorEndOverlap

2OnComponent触发

Add On Component Begin Overlap——碰撞组件触发

Add On Component End Overlap

3击中

Event Hit

开启Hit事件 碰撞响应要设置为Block

4击伤事件

1.应用伤害Apply Damage

2.接受伤害

Event AnyDamage

Event PointDamage

Event RadialDamage

5伤害类型

1.DamageType的预设类别

2.创建一个继承DamageType的自定义DamageType蓝图

 

3.代替Add Impulse产生冲击力,设置Damage Type中的Damage Impulse为80。但Apply Damage无法触发代码Add Impluse At Location(Apply Point/Radial Damage可以)。

AnyDamage连接下的

6点伤害

1.子弹蓝图里触发Damage

7范围伤害规则

1.球形范围伤害

2.由于Damage Prevention Channel的原因,侧面和后面的方块受到的爆破力被阻碍

8完全伤害

1.C++引擎源码中的ApplyRadialDamge蓝图节点信息

h头文件

/** Hurt locally authoritative actors within the radius. Will only hit components that block the Visibility channel.
	 * @param BaseDamage - The base damage to apply, i.e. the damage at the origin.
	 * @param Origin - Epicenter of the damage area.
	 * @param DamageRadius - Radius of the damage area, from Origin
	 * @param DamageTypeClass - Class that describes the damage that was done.
	 * @param DamageCauser - Actor that actually caused the damage (e.g. the grenade that exploded).  This actor will not be damaged and it will not block damage.
	 * @param InstigatedByController - Controller that was responsible for causing this damage (e.g. player who threw the grenade)
	 * @param bFullDamage - if true, damage not scaled based on distance from Origin
	 * @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
	 * @return true if damage was applied to at least one actor.
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Game|Damage", meta=(WorldContext="WorldContextObject", AutoCreateRefTerm="IgnoreActors"))
	static bool ApplyRadialDamage(const UObject* WorldContextObject, float BaseDamage, const FVector& Origin, float DamageRadius, TSubclassOf<class UDamageType> DamageTypeClass, const TArray<AActor*>& IgnoreActors, AActor* DamageCauser = NULL, AController* InstigatedByController = NULL, bool bDoFullDamage = false, ECollisionChannel DamagePreventionChannel = ECC_Visibility);
	
	/** Hurt locally authoritative actors within the radius. Will only hit components that block the Visibility channel.
	 * @param BaseDamage - The base damage to apply, i.e. the damage at the origin.
	 * @param Origin - Epicenter of the damage area.
	 * @param DamageInnerRadius - Radius of the full damage area, from Origin
	 * @param DamageOuterRadius - Radius of the minimum damage area, from Origin
	 * @param DamageFalloff - Falloff exponent of damage from DamageInnerRadius to DamageOuterRadius
	 * @param DamageTypeClass - Class that describes the damage that was done.
	 * @param DamageCauser - Actor that actually caused the damage (e.g. the grenade that exploded)
	 * @param InstigatedByController - Controller that was responsible for causing this damage (e.g. player who threw the grenade)
	 * @param bFullDamage - if true, damage not scaled based on distance from Origin
	 * @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
	 * @return true if damage was applied to at least one actor.
	 */
	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);

cpp实现

bool UGameplayStatics::ApplyRadialDamage(const UObject* WorldContextObject, float BaseDamage, const FVector& Origin, float DamageRadius, TSubclassOf<UDamageType> DamageTypeClass, const TArray<AActor*>& IgnoreActors, AActor* DamageCauser, AController* InstigatedByController, bool bDoFullDamage, ECollisionChannel DamagePreventionChannel )
{
	float DamageFalloff = bDoFullDamage ? 0.f : 1.f;
	return ApplyRadialDamageWithFalloff(WorldContextObject, BaseDamage, 0.f, Origin, 0.f, DamageRadius, DamageFalloff, DamageTypeClass, IgnoreActors, DamageCauser, InstigatedByController, DamagePreventionChannel);
}

bool UGameplayStatics::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, AController* InstigatedByController, ECollisionChannel DamagePreventionChannel)
{
	FCollisionQueryParams SphereParams(SCENE_QUERY_STAT(ApplyRadialDamage),  false, DamageCauser);

	SphereParams.AddIgnoredActors(IgnoreActors);

	// query scene to see what we hit
	TArray<FOverlapResult> Overlaps;
	if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
	World->OverlapMultiByObjectType(Overlaps, Origin, FQuat::Identity, FCollisionObjectQueryParams(FCollisionObjectQueryParams::InitType::AllDynamicObjects), FCollisionShape::MakeSphere(DamageOuterRadius), SphereParams);
	}

	// collate into per-actor list of hit components
	TMap<AActor*, TArray<FHitResult> > OverlapComponentMap;
	for (int32 Idx=0; Idx<Overlaps.Num(); ++Idx)
	{
		FOverlapResult const& Overlap = Overlaps[Idx];
		AActor* const OverlapActor = Overlap.GetActor();

		if ( OverlapActor && 
			OverlapActor->bCanBeDamaged && 
			OverlapActor != DamageCauser &&
			Overlap.Component.IsValid() )
		{
			FHitResult Hit;
			if (DamagePreventionChannel == ECC_MAX || ComponentIsDamageableFrom(Overlap.Component.Get(), Origin, DamageCauser, IgnoreActors, DamagePreventionChannel, Hit))
			{
				TArray<FHitResult>& HitList = OverlapComponentMap.FindOrAdd(OverlapActor);
				HitList.Add(Hit);
			}
		}
	}

	bool bAppliedDamage = false;

	if (OverlapComponentMap.Num() > 0)
	{
	// make sure we have a good damage type
	TSubclassOf<UDamageType> const ValidDamageTypeClass = DamageTypeClass ? DamageTypeClass : TSubclassOf<UDamageType>(UDamageType::StaticClass());

		FRadialDamageEvent DmgEvent;
		DmgEvent.DamageTypeClass = ValidDamageTypeClass;
		DmgEvent.Origin = Origin;
		DmgEvent.Params = FRadialDamageParams(BaseDamage, MinimumDamage, DamageInnerRadius, DamageOuterRadius, DamageFalloff);

	// call damage function on each affected actors
	for (TMap<AActor*, TArray<FHitResult> >::TIterator It(OverlapComponentMap); It; ++It)
	{
		AActor* const Victim = It.Key();
		TArray<FHitResult> const& ComponentHits = It.Value();
		DmgEvent.ComponentHits = ComponentHits;

		Victim->TakeDamage(BaseDamage, DmgEvent, InstigatedByController, DamageCauser);

		bAppliedDamage = true;
	}
	}

	return bAppliedDamage;
}

2.Apply Radial Damage with Falloff (falloff为0不衰减,越大衰减越快

第六章 射线检测

1零粗细(很细)射线检测

 

射线通道TraceChannel

Visibility——适用于两点之间,存在障碍物时触发

Camera——适用于从相机发出射线

TraceComplex——针对复杂物体,检测复杂碰撞体还是简单的碰撞体,一般不开启

 

Note设置Start End Position

绘制射线的持续时间

2零检测返回结果

法线

测试

 

4球体非零粗细检测

5调试检测结果

蓝图

预测

实际

6多重零粗细检测

1.立方体 碰撞预设设置由BlockAll变为OverlapAll

Blocking Hit 绿色为false,红色为true

7盒子、胶囊体检测

Orientation——方向

 

8逐多边形检测

Trace Complex 不勾选——检测碰撞体

勾选——检测多边形模型

同时,模型选择Use Complex Collision As Simple Collision

 

 

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值