UE4--中级练习TPS[骨骼插槽;蓝图添加至插槽;c++、蓝图产生特效;点伤害、范围伤害]

2021/5/22 20:29:47

本文主要是介绍UE4--中级练习TPS[骨骼插槽;蓝图添加至插槽;c++、蓝图产生特效;点伤害、范围伤害],对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

C++继承关系图

参考学习视频

1、蓝图实现武器放入骨骼中的槽口

步骤1、在人物上给右手添加插槽

步骤2、武器的骨骼实现

步骤3、蓝图的实现

进阶版

效果图

【备注】

你也可以通过在插槽右键添加预览资源,旋转插槽进行一个持枪的具体调整

2、C++实现发射激光+特效生成

【Sweapon.cpp】

// Fill out your copyright notice in the Description page of Project Settings.

#include "SWeapon.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/ActorComponent.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
#include "Kismet/GameplayStatics.h"
#include "Particles/ParticleSystemComponent.h"
#include "PhysicalMaterials/PhysicalMaterial.h"
#include "CoopGame.h"



// Sets default values
ASWeapon::ASWeapon()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	MeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("MeshComponent"));
	RootComponent = MeshComponent;
	MuzzleSocketName = "MuzzleSocket";
	TrancerTargetgetName = "Target";
	BaseDamage = 20;
	HeadDamage = 100;

}

// Called when the game starts or when spawned
void ASWeapon::BeginPlay()
{
	Super::BeginPlay();
	
}

static int32 DebugWeapnDrawing = 0;
FAutoConsoleVariableRef CVARDebugWeaponDrawing(
	TEXT("COOP.WeaponsLine"),
	DebugWeapnDrawing,
	TEXT("Draw Debug Lines for Weapons"),
	ECVF_Cheat
);

void ASWeapon::Fire()
{
	//获得当前玩家
	AActor* MyOwner = GetOwner();
	
	
	if (MyOwner) {

		APawn* MyPawn = Cast<APawn>(GetOwner());
		//镜头震动
		if (MyPawn) {
			APlayerController *PC = Cast<APlayerController>(MyPawn->GetController());
			if (PC) {
				PC->ClientPlayCameraShake(FireCamShake);
			}
		}
		

		FVector EyeLocation;
		FRotator EyeRotator;
		//获取眼睛位置信息
		MyOwner->GetActorEyesViewPoint(EyeLocation, EyeRotator);

		FVector MuzzleLocation = MeshComponent->GetSocketLocation(MuzzleSocketName);
		//FVector DirectRotation = MeshComponent->GetSocketRotation(MuzzleSocketName).Vector();
		//弹道终点 = 起点+方向 * 10000
		FVector TraceEnd = EyeLocation + EyeRotator.Vector() * 10000;
		//撞击句柄,获取弹道信息
		FHitResult Hit;
		//碰撞查询参数
		FCollisionQueryParams QueryParams;
		//FCollisionQueryParams QueryParams;
		
		//忽略玩家和这把枪
		QueryParams.AddIgnoredActor(MyOwner);
		QueryParams.AddIgnoredActor(this);
		//复合追踪,让射击更精准,可以追踪目标网格每一个三角形
		QueryParams.bTraceComplex = true;
		QueryParams.bReturnPhysicalMaterial = true;
		FVector TraceEndPoint = TraceEnd;
		//GetWorld()->LineTraceSingleByChannel(Hit, 起点, 终点, 可见性弹道,碰撞查询参数) 如果击中则为真
		if (GetWorld()->LineTraceSingleByChannel(Hit, EyeLocation, TraceEnd, COLLISION_WEAPON, QueryParams))
		{
			AActor* HitActor = Hit.GetActor();
			

			TraceEndPoint = Hit.ImpactPoint;

			//设置材质
			EPhysicalSurface SurfaceType = UPhysicalMaterial::DetermineSurfaceType(Hit.PhysMaterial.Get());
			UParticleSystem *SelectedEffect = nullptr;
			float realDamage = BaseDamage;
			if (SurfaceType == SURFACE_FLESHEAD) realDamage = HeadDamage;
			switch (SurfaceType) {
			case SURFACE_FLESHBODY:
			case SURFACE_FLESHEAD:
				SelectedEffect = FleshImpactEffect;
				break;
			default:
				SelectedEffect = DefaultImpactEffect;
				break;
			}
			//伤害对象,基础伤害,射击方向,命中信息,eventInstigator, 伤害者,伤害类
			UGameplayStatics::ApplyPointDamage(HitActor, realDamage, EyeRotator.Vector(), Hit, MyOwner->GetInstigatorController(), this, DamageType);

			if (SelectedEffect)
			{
				//被击中处的特效
				//GetWorld  特效,位置是撞击位置,旋转 命中效果
				UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), SelectedEffect, Hit.ImpactPoint, Hit.ImpactNormal.Rotation());
			}

		}
		
		//DrawDebugLine(GetWorld(), 起点, 终点, 颜色, 不需要一直存在, 持续1s, 0, 粗细);
		if(DebugWeapnDrawing > 0)
		    DrawDebugLine(GetWorld(), MuzzleLocation, TraceEnd, FColor::Red, false, 1, 0, 1);

		if (MuzzleEffect)
		{
			保证特效出生在枪口的槽位上SpawnEmitterAttached ,枪口特效,如何定位到槽位上的呢?只有一个槽位就这么些,如果有多个呢
			//UGameplayStatics::SpawnEmitterAttached(MuzzleEffect, MeshComponent, MuzzleSocketName);
			
			UParticleSystemComponent *it = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), MuzzleEffect, MuzzleLocation);
		}
		
		//弹道特效
		if (TracerEffect)
		{
			UParticleSystemComponent *it = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), TracerEffect, MuzzleLocation);
			if (it)
			{
				//参数名字,参数向量
				it->SetVectorParameter(TrancerTargetgetName, TraceEndPoint);
			}
		}
		
	}
	
}


// Called every frame
void ASWeapon::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

关键代码:

//撞击句柄,获取弹道信息
FHitResult Hit;
//碰撞查询参数
FCollisionQueryParams QueryParams;
//FCollisionQueryParams QueryParams;
//忽略玩家和这把枪
QueryParams.AddIgnoredActor(MyOwner);
QueryParams.AddIgnoredActor(this);
//复合追踪,让射击更精准,可以追踪目标网格每一个三角形
QueryParams.bTraceComplex = true;
QueryParams.bReturnPhysicalMaterial = true;
FVector TraceEndPoint = TraceEnd;
//GetWorld()->LineTraceSingleByChannel(Hit, 起点, 终点, 可见性弹道,碰撞查询参数) 如果击中则为真
if (GetWorld()->LineTraceSingleByChannel(Hit, EyeLocation, TraceEnd, COLLISION_WEAPON, QueryParams))
{
    //伤害对象,基础伤害,射击方向,命中信息,eventInstigator, 伤害者,伤害类
			UGameplayStatics::ApplyPointDamage(HitActor, realDamage, EyeRotator.Vector(), Hit, MyOwner->GetInstigatorController(), this, DamageType);

			if (SelectedEffect)
			{
				//被击中处的特效
				//GetWorld  特效,位置是撞击位置,旋转 命中效果
				UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), SelectedEffect, Hit.ImpactPoint, Hit.ImpactNormal.Rotation());
			}

		}
		
		//DrawDebugLine(GetWorld(), 起点, 终点, 颜色, 不需要一直存在, 持续1s, 0, 粗细);
		if(DebugWeapnDrawing > 0)
		    DrawDebugLine(GetWorld(), MuzzleLocation, TraceEnd, FColor::Red, false, 1, 0, 1);

		if (MuzzleEffect)
		{
			保证特效出生在枪口的槽位上SpawnEmitterAttached ,枪口特效,如何定位到槽位上的呢?只有一个槽位就这么些,如果有多个呢
			//UGameplayStatics::SpawnEmitterAttached(MuzzleEffect, MeshComponent, MuzzleSocketName);
			
			UParticleSystemComponent *it = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), MuzzleEffect, MuzzleLocation);
		}
		
		//弹道特效
		if (TracerEffect)
		{
			UParticleSystemComponent *it = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), TracerEffect, MuzzleLocation);
			if (it)
			{
				//参数名字,参数向量
				it->SetVectorParameter(TrancerTargetgetName, TraceEndPoint);
			}
		}    
}

【Swapon.h】

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SWeapon.generated.h"
class UDamageType;


UCLASS()
class COOPGAME_API ASWeapon : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ASWeapon();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Component")
	class USkeletalMeshComponent *MeshComponent;

	UFUNCTION(BlueprintCallable, Category = "Weapon")
	virtual void Fire();
	//EditDefaultsOnly:只可通过类默认值修改内容
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	TSubclassOf<UDamageType> DamageType;	

	UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	FName MuzzleSocketName;

	UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	FName TrancerTargetgetName;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	class UParticleSystem* MuzzleEffect;
	
	//默认击中特效
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	class UParticleSystem* DefaultImpactEffect;
	//击中身体时的特效
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	class UParticleSystem* FleshImpactEffect;

	//枪口特效
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	class UParticleSystem* TracerEffect;
	//窗口抖动
	UPROPERTY(EditDefaultsOnly, Category = "Weapon")
	TSubclassOf<class UCameraShake> FireCamShake;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	float BaseDamage;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
	float HeadDamage;



public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

3、C++实现应用点伤产生伤害 (原理:ue4自带函数,学习射击句柄)

//伤害对象,基础伤害,射击方向,命中信息,eventInstigator, 伤害者,伤害类
UGameplayStatics::ApplyPointDamage(HitActor, realDamage, EyeRotator.Vector(), Hit, MyOwner->GetInstigatorController(), this, DamageType);

//撞击句柄
FHitResult Hit;
GetWorld()->LineTraceSingleByChannel(Hit, EyeLocation, TraceEnd, COLLISION_WEAPON, QueryParams)

4、C++实现枪口特效 (原理:ue4自带函数)

if (MuzzleEffect)
		{
			保证特效出生在枪口的槽位上SpawnEmitterAttached ,枪口特效,如何定位到槽位上的呢?只有一个槽位就这么些,如果有多个呢
			//UGameplayStatics::SpawnEmitterAttached(MuzzleEffect, MeshComponent, MuzzleSocketName);
			
			UParticleSystemComponent *it = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), MuzzleEffect, MuzzleLocation);
		}

5、蓝图实现榴弹、手榴弹 

新建SProjectileWeapon,并继承Sweapon.h,并重写Fire函数如下

SProjectileWeapon.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "SProjectileWeapon.h"
#include "Engine/World.h"
#include "Components/SkeletalMeshComponent.h"

void ASProjectileWeapon::Fire()
{
	//获得当前玩家
	AActor* MyOwner = GetOwner();
	
	if (MyOwner) {
		FVector EyeLocation;
		FRotator EyeRotator;
		//获取眼睛位置信息
		MyOwner->GetActorEyesViewPoint(EyeLocation, EyeRotator);
		FVector MuzzleLocation = MeshComponent->GetSocketLocation(MuzzleSocketName);
		FActorSpawnParameters SpawnParams;
		//SpawnCollisionHandlingOverride??  AlwaysSpawn??
		SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
		if (ProjectileClass)
		{
			//类,位置,方向 
			GetWorld()->SpawnActor<AActor>(ProjectileClass, MuzzleLocation, EyeRotator, SpawnParams);
		}
		
	}
}

SProjectileWeapon.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "SWeapon.h"
#include "SProjectileWeapon.generated.h"

/**
 * 
 */
UCLASS()
class COOPGAME_API ASProjectileWeapon : public ASWeapon
{
	GENERATED_BODY()
protected:
	virtual void Fire() override;

	UPROPERTY(EditDefaultsOnly, Category = "ProjectTileWeapon")
	TSubclassOf<AActor> ProjectileClass;
};

子弹蓝图:【我这里有问题,apply radial damage 返回值是false,还没找到具体问题】

子弹爆炸时的特效蓝图

 

 

 



这篇关于UE4--中级练习TPS[骨骼插槽;蓝图添加至插槽;c++、蓝图产生特效;点伤害、范围伤害]的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程