UE4 伤害事件,不同部位不同伤害(C++)
可以先看射线检测
效果:
打头和身体有不同的伤害
前面设置部分:
- 先设置项目设置里的物理的Physical Surface,添加好身体的部位
2. 添加了几个就几个变量
设置好它们的表面类型
3. 找到被伤害的那个模型的物理资产
按骨骼树设置好碰撞的物理材质重载
(C++)代码:
发出伤害:
这是一个方法:
发出射线检测到后应用伤害
射线检测的HitResult有一个参数会返回被击中的物理材质,然后再通过物理材质判断其伤害
void AFPSTeachBaseCharacter::RifleLineTrace(FVector CameraLocation, FRotator CameraRotation, bool IsMoveing)
{
FVector EndLocation;
FVector CameraForwardVector=UKismetMathLibrary::GetForwardVector(CameraRotation);
TArray<AActor*> IgnoreArray;
IgnoreArray.Add(this);
FHitResult HitResult;//击中的结果集
if (ServerPrimaryWeapon)
{
if (IsMoveing)
{
}
else
{
EndLocation = CameraLocation + CameraForwardVector * ServerPrimaryWeapon->BulletDistance;
}
bool HitSuccess=UKismetSystemLibrary::LineTraceSingle(GetWorld(),CameraLocation, EndLocation, ETraceTypeQuery::TraceTypeQuery1, false ,
IgnoreArray,EDrawDebugTrace::None, HitResult,true,FLinearColor::Red,
FLinearColor::Green,3.f);
if (HitSuccess)
{
//UKismetSystemLibrary::PrintString(GetWorld(), FString::Printf(TEXT("Hit Actor name : %s"), *HitResult.Actor->GetName()));
AFPSTeachBaseCharacter* FPSCharacter=Cast<AFPSTeachBaseCharacter>(HitResult.Actor);
if (FPSCharacter)
{
//打到玩家
//这里因为HitResult.PhysMaterial是一个智能指针,所以我们要加一个Get()
DamagePlayer(HitResult.PhysMaterial.Get(),HitResult.Actor.Get(),CameraLocation,HitResult);
}
else {
FRotator XRotator=UKismetMathLibrary::MakeRotFromX(HitResult.Normal);
//生成广播单孔
MultiSpawnBulletDecat(HitResult.Location,XRotator);
}
}
}
}
判断被击中的物理材质,计算出该部位被击中所受到的伤害
//我们不用在服务器上自己定义的那个FPSPlayerController 是因为在服务器上拿不到的 FPSPlayerController比GetController 生成要早一点,所以FPSPlayerController拿到的是空
//应用伤害,有一个回调,定义在Beginplay
//UGameplayStatics::ApplyPointDamage(DamagedActor,10,HitFromDirection,HitInfo,GetController(),this,UDamageType::StaticClass());
DamagedActor:是受到伤害的Actor
10:伤害数值
HitFromDirection:发起攻击的位置
HitInfo:发起攻击的位置旋转
GetController():发起攻击的玩家控制器
this:描述所造成的伤害的类。
UDamageType::StaticClass():实际的伤害最终会被施加到行为人身上。一个类的类类型
void AFPSTeachBaseCharacter::DamagePlayer(UPhysicalMaterial* PhysicalMaterial,AActor* DamagedActor, FVector const& HitFromDirection, FHitResult const& HitInfo)
{
//5个位置的应用伤害不同
if (ServerPrimaryWeapon)
{
switch (PhysicalMaterial->SurfaceType)
{
case EPhysicalSurface::SurfaceType1:
{
//head
//ServerPrimaryWeapon->BaseDamage 这是自己定义的一个float伤害数值
UGameplayStatics::ApplyPointDamage(DamagedActor, ServerPrimaryWeapon->BaseDamage*4, HitFromDirection, HitInfo, GetController(), this, UDamageType::StaticClass());
UKismetSystemLibrary::PrintString(this, FString::Printf(TEXT("Head %s Health:%f"), *GetName(), ServerPrimaryWeapon->BaseDamage * 4));
}break;
case EPhysicalSurface::SurfaceType2:
{
//body
UGameplayStatics::ApplyPointDamage(DamagedActor, ServerPrimaryWeapon->BaseDamage * 1, HitFromDirection, HitInfo, GetController(), this, UDamageType::StaticClass());
UKismetSystemLibrary::PrintString(this, FString::Printf(TEXT("Body %s Health:%f"), *GetName(), ServerPrimaryWeapon->BaseDamage * 1));
}break;
case EPhysicalSurface::SurfaceType3:
{
//arm
UGameplayStatics::ApplyPointDamage(DamagedActor, ServerPrimaryWeapon->BaseDamage * 0.8, HitFromDirection, HitInfo, GetController(), this, UDamageType::StaticClass());
}break;
case EPhysicalSurface::SurfaceType4:
{
//leg
UGameplayStatics::ApplyPointDamage(DamagedActor, ServerPrimaryWeapon->BaseDamage * 0.7, HitFromDirection, HitInfo, GetController(), this, UDamageType::StaticClass());
}break;
default:
break;
}
}
//我们不用在服务器上自己定义的那个FPSPlayerController 是因为在服务器上拿不到的 FPSPlayerController比GetController 生成要早一点,所以FPSPlayerController拿到的是空
//应用伤害,有一个回调,定义在Beginplay
//UGameplayStatics::ApplyPointDamage(DamagedActor,10,HitFromDirection,HitInfo,GetController(),this,UDamageType::StaticClass());
}
接受回调伤害
然后伤害就会通知到被攻击的Actor
(C++):
这里面的参数是从它的父类拿到的
***定义一个函数来接收回调的参数***
UFUNCTION()
void OnHit(AActor* DamagedActor, float Damage, class AController* InstigatedBy, FVector HitLocation,
class UPrimitiveComponent* FHitComponent, FName BoneName, FVector ShotFromDirection, const class UDamageType* DamageType, AActor* DamageCauser);
绑定回调:
通过回调回来的伤害进行处理就可以实现了。。
仅供参考