UE4 C++角色与道具技能的互动(上)

Posted Vincent_0000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 C++角色与道具技能的互动(上)相关的知识,希望对你有一定的参考价值。

前言

本文章将会告诉你如何生成道具,并且人物可以拾取道具。
道具能够自转,道具与角色碰撞之后会发出声音然后消失。
(音效、粒子特效、物品找了我好久 😭)


创建C++文件

创建AItem类,继承Actor

.h文件

  • 声明球形组件,用于碰撞检测
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Item | Collision")
	class USphereComponent* SpereComp;
  • 声明碰撞接触和结束做出的反应的函数
UFUNCTION()
	virtual void OnOverlapBegin(UPrimitiveComponent*  OverlappedComponent, AActor* OtherActor, 
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

UFUNCTION()
	virtual void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
		UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

由于这两个函数要和碰撞球体相联系起来,所以他的参数就得遵循一定的规则,这个规则在哪里呢?
先看创建联系的函数怎么实现的:

SpereComp->OnComponentBeginOverlap.AddDynamic(this, &AItem::OnOverlapBegin);
SpereComp->OnComponentEndOverlap.AddDynamic(this, &AItem::OnOverlapEnd);

球形组件中有OnComponentBeginOverlapOnComponentEndOverlap,以OnComponentBeginOverlap为例,我们点进去查看,我们会发现这样的一个声明:

UPROPERTY(BlueprintAssignable, Category="Collision")
FComponentBeginOverlapSignature OnComponentBeginOverlap;

我们找到声明FComponentBeginOverlapSignature的地方,我们就会看到这个:
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);
作为初学者,我们暂时只了解一下我们的函数要写什么函数就行,我们发现前三个东西中,首尾两个就是我们刚刚看到的那个东西,那么就不用管这三个,(应该有某种关系吧,我也是初学者,不知道具体有什么联系,,,)然后把后面的抄到我们的函数声明中。另外一个同理。

  • 声明静态网格体,也就是上图的金币。
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Item | Mesh")
	UStaticMeshComponent* MeshComp;
  • 声明粒子组件,就是上图的一把火的效果。
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Item | Particle")
	class UParticleSystemComponent* ParticleComp;
  • 声明粒子系统,我们表示我们碰撞之后发生的例子效果,就是人物碰撞到炸弹之后,会有烟雾发出来的效果来源。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item | Particle")
	UParticleSystem* ParticleOverlap;
  • 声明碰撞之后发出的声音
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item | Sound")
	class USoundCue* SoundOverlap;
  • 声明储存是否旋转的变量
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item | Property")
	bool Rotate;
  • 我们的静态网格体是可以旋转的,所以我们这里要声明一个旋转速度。
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item | Property")
	float RotationSpeed;

.cpp 文件

  • 构造函数

添加头文件:#include "Components/SphereComponent.h"
为球形组件创建实例,并且设置为根组件。

SpereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SpereComp"));
RootComponent = SpereComp;

创建静态网格体实例,依附于根组件上。

MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp"));
MeshComp->SetupAttachment(RootComponent);

添加头文件:#include "Particles/ParticleSystemComponent.h"
创建粒子组件实例,并且依附于根组件上。

ParticleComp = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("ParticleComp"));
ParticleComp->SetupAttachment(RootComponent);

初始变量:

Rotate = false;
RotationSpeed = 100;
  • BeginPlay()

运行开始的时候,将我们球形组件的碰撞和我们自定义的碰撞之后发生的反应的函数相联系起来。

SpereComp->OnComponentBeginOverlap.AddDynamic(this, &AItem::OnOverlapBegin);
SpereComp->OnComponentEndOverlap.AddDynamic(this, &AItem::OnOverlapEnd);
  • Tick(float DeltaTime)

旋转是有动态变化的,所以我们每一帧都要更新物体的角度。

if (Rotate) {
	FRotator Rotation = MeshComp->GetComponentRotation();
	Rotation.Yaw += DeltaTime * RotationSpeed;
	MeshComp->SetWorldRotation(Rotation);
}

当然,更新之前要判断我们是否需要旋转。

  • 完善我们自定义的重叠函数

添加头文件:

#include "Kismet/GameplayStatics.h"
#include "Sound/SoundCue.h"

这里就是函数的调用,知道有这个函数,按照他的格式来就行。
重叠结束暂时还没写什么东西,因为现在只要一碰物体就消失了。

void AItem::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (ParticleOverlap)  UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ParticleOverlap, GetActorLocation());
	if (SoundOverlap) UGameplayStatics::PlaySound2D(GetWorld(), SoundOverlap);
	Destroy();
}

void AItem::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
}

接下来的定义是为我们后面做铺垫,具体重要作用还没有体现。

创建APickup类,继承AItem

.h文件

添加:

public:
	virtual void OnOverlapBegin(UPrimitiveComponent*  OverlappedComponent, AActor* OtherActor, 
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override;

	virtual void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
		UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) override;

.cpp 文件

void APickup::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	Super::OnOverlapBegin(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
}

void APickup::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	Super::OnOverlapEnd(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex);
}

创建AExplosive类,继承AItem

和上面一样的。

.h文件

添加:

public:
	virtual void OnOverlapBegin(UPrimitiveComponent*  OverlappedComponent, AActor* OtherActor, 
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override;

	virtual void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, 
		UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) override;

.cpp 文件

void AExplosive::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	Super::OnOverlapBegin(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
}

void AExplosive::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	Super::OnOverlapEnd(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex);
}

以C++类为父类创建蓝图

在细节面板的
添加我们的粒子效果即可。

下一章将会介绍:碰到拾取类会增加金币数,爆炸类会扣血,加速键会消耗体力。

以上是关于UE4 C++角色与道具技能的互动(上)的主要内容,如果未能解决你的问题,请参考以下文章

UE4 C++角色拾取替换武器(上)

基于C++代码的UE4学习—— 自定义代理结合Timer实现道具的消失与重生

UE4 C++第三人称人物创建的基本代码(上)

UE4 C++角色拾取替换武器(下)

UE4 C++网络编程基础知识总结

UE4 C++网络编程基础知识总结