【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++类为父类创建蓝图

在细节面板的在这里插入图片描述
添加我们的粒子效果即可。

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值