UE4 C++代码实现碰撞小游戏

 新建项目选择空项目

复制Materials和Meshes到Content目录

重新构建关卡

添加SM_Backdrop,SM_Wall,并作如下修改:

添加C++类,并取名为Paddle

在Paddle.h中添加属性:

在类上声明:

FloatingPawnMovement是一个运动组件,为任何Pawn类提供简单的运动。

在Paddle.h中继续添加移动处理的函数

Paddle.cpp中添加头文件

构造函数中添加UStaticMeshComponent与UFloatingPawnMovement组件

实现MoveHorizontal函数:

在Paddle_BP蓝图设置SM_Padle的mesh

把Paddle_BP放入场景中

在场景中新建GameMode并改名为ArkanoidGameMode_BP

对GameMode进行设置

添加Camera

新建PlayerController的基类,并取名为Paddle_Player_Controller

Paddle_Player_Controller.h添加函数声明

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "Paddle_Player_Controller.generated.h"

//class ABall
/**
 * 
 */
UCLASS()
class PLAYBALL_API APaddle_Player_Controller : public APlayerController
{
	GENERATED_BODY()

		APaddle_Player_Controller();

	UFUNCTION()
		virtual void SetupInputComponent() override;

protected:
	virtual void BeginPlay() override;

	void MoveHorizontal(float AxisValue);

	//ball reerences
};

Paddle_Player_Controller.cpp中设置相机为主视角

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


#include "Paddle_Player_Controller.h"

#include "Kismet/GameplayStatics.h"
#include "Camera/CameraActor.h"

#include "Paddle.h"
//#include "Ball.h"

APaddle_Player_Controller::APaddle_Player_Controller()
{

}

void APaddle_Player_Controller::SetupInputComponent()
{
}

void APaddle_Player_Controller::BeginPlay()
{
	TArray<AActor*> CameraActors;
	UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACameraActor::StaticClass(), CameraActors);

	FViewTargetTransitionParams params;
	SetViewTarget(CameraActors[0], params);
}

void APaddle_Player_Controller::MoveHorizontal(float AxisValue)
{
}

新建蓝图类,基类为Paddle_Player_Controller

然后设置游戏控制类为刚刚新建的蓝图类:

设置完之后运行游戏,可以看到:

添加输入

在Paddle_Player_Controller.h中绑定SetupInputComponent:

void APaddle_Player_Controller::SetupInputComponent()
{
	Super::SetupInputComponent();

	EnableInput(this);

	InputComponent->BindAxis("MoveHorizontal", this, &APaddle_Player_Controller::MoveHorizontal);

}

实现MoveHorizontal

void APaddle_Player_Controller::MoveHorizontal(float AxisValue)
{
	auto MyPawn = Cast<APaddle>(GetPawn());

	if (MyPawn) {
		MyPawn->MoveHorizontal(AxisValue);
	}
}

这里需要注意的是,在关卡中只需要放PlayerStart即可,不需要放Paddle_BP,否则会不能移动。

添加球体

在ball.h添加属性:

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Ball.generated.h"

class UProjectileMovementComponent;

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

	virtual void Launch();

	bool BallLaunched;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
		UStaticMeshComponent* SM_Ball;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
		UProjectileMovementComponent* ProjectileMovement;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

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

	UFUNCTION()
		UStaticMeshComponent* GetBall();

};

在Ball.cpp的构造函数中添加:

	SM_Ball = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Ball"));
	RootComponent = SM_Ball;

	SM_Ball->SetSimulatePhysics(true);
	SM_Ball->SetEnableGravity(false);
	SM_Ball->SetConstraintMode(EDOFMode::XZPlane);
	SM_Ball->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
	SM_Ball->SetCollisionProfileName(TEXT("PhysicsActor"));

设置PhysicsActor的原因是Paddle_BP中StaticMesh的碰撞预设设置的是PhysicsActor

在构造函数中继续添加

	ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Projectile Movement"));
	ProjectileMovement->bShouldBounce = true;
	ProjectileMovement->Bounciness = 1.1f;
	ProjectileMovement->Friction = 0.0f;
	ProjectileMovement->Velocity.X = 0.0f;

实现Launch函数

void ABall::Launch()
{
	if (!BallLaunched) {
		SM_Ball->AddImpulse(FVector(140.0f, 0.0f, 130.0f), FName(), true);

		BallLaunched = true;
	}
}

添加函数绑定

在蓝图中实现:

修改Paddle_Player_Controller.h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"

#include "Ball.h"

#include "Paddle_Player_Controller.generated.h"


/**
 * 
 */
UCLASS()
class PLAYBALL_API APaddle_Player_Controller : public APlayerController
{
	GENERATED_BODY()

		APaddle_Player_Controller();

	UFUNCTION()
		virtual void SetupInputComponent() override;

protected:
	virtual void BeginPlay() override;

	void MoveHorizontal(float AxisValue);

	void Launch();

	UPROPERTY(EditAnywhere)
		TSubclassOf<ABall> BallObj;

	ABall* MyBall=nullptr;

	FVector SpawnLocation = FVector(10.0f, 0.0f, 40.0f);
	FRotator SpawnRotation = FRotator(0.0f, 0.0f, 0.0f);
	FActorSpawnParameters SpawnInfo;

public:
	void SpawnNewBall();

	//ball reerences
};

在Paddle_Player_Controller.h实现SpawnNewBall()函数

void APaddle_Player_Controller::SpawnNewBall()
{
	if (!MyBall) {
		MyBall = nullptr;
	}

	if (BallObj) {
		MyBall = GetWorld()->SpawnActor<ABall>(BallObj, SpawnLocation, SpawnRotation, SpawnInfo);
	}
}

开始游戏的时候调用SpawnNewBall

设置Ball Obj

新建Material

双击做如下设置

完成以上步骤后做如下步骤:

创建砖块,并命名为Brick.h:

在Brick.h中创建属性与函数:

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Brick.generated.h"

class UBoxComponent;

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

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UPROPERTY(VisibleAnywhere,BlueprintReadOnly)
		UStaticMeshComponent* SM_Brick;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
		UBoxComponent* Box_Collision;

	float SpeedModifierOnBounce = 1.0f;

	UFUNCTION()
		void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor,
			class UPrimitiveComponent* OtherComp, int32 OtherBodyIndexType, bool bFromSweep,
			const FHitResult& SweepResult);

	void DestroyBrick();

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

};

初始化,以及绑定碰撞函数

新建Brick的蓝图类并做如下设置:

把Brick蓝图类拖入level中

添加Tag

实现碰撞函数

void ABrick::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndexType, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Warning, TEXT("OnOverlapBegin"));
	if (OtherActor->ActorHasTag("Ball"))
	{
		UE_LOG(LogTemp, Warning, TEXT("OnOverlapBegin  OtherActor"));
		ABall* MyBall = Cast<ABall>(OtherActor);

		FVector BallVelocity = MyBall->GetVelocity();
		BallVelocity *= (SpeedModifierOnBounce + 1.0001f);

		MyBall->GetBall()->SetPhysicsLinearVelocity(BallVelocity, true);

		FTimerHandle UnusedHandle;
        //先弹走,然后0.1s后再destroy造成视觉差
		GetWorldTimerManager().SetTimer(UnusedHandle, this, &ABrick::DestroyBrick, 0.1f, false);
	}
}

void ABrick::DestroyBrick()
{
	this->Destroy();
}

到这里,游戏基本功能已经实现,但是如果小球弹到下面了该怎么处理呢?

添加基类为Actor的ABallBoound C++类

BallBoound.h

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "BallBoound.generated.h"

class UBoxComponent;
class APaddle_Player_Controller;

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

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
		UBoxComponent* Box_Collision;

	APaddle_Player_Controller* PlayerController_REF;

	UFUNCTION()
		void OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor,
			class UPrimitiveComponent* OtherComp, int32 OtherBodyIndexType, bool bFromSweep,
			const FHitResult& SweepResult);

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

};

BallBound.cpp

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


#include "BallBoound.h"
#include "Components/BoxComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Paddle_Player_Controller.h"

// Sets default values
ABallBoound::ABallBoound()
{
 	// 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;

	Box_Collision = CreateDefaultSubobject<UBoxComponent>(TEXT("Box Collision"));
	RootComponent = Box_Collision;

}

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

	Box_Collision->OnComponentBeginOverlap.AddDynamic(this, &ABallBoound::OnOverlapBegin);

	PlayerController_REF = Cast<APaddle_Player_Controller>(
		UGameplayStatics::GetPlayerController(GetWorld(), 0)
		);
	
}

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

}

void ABallBoound::OnOverlapBegin(class UPrimitiveComponent* OverlappedComp, class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndexType, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OtherActor->ActorHasTag("Ball"))
	{
		OtherActor->Destroy();

		PlayerController_REF->SpawnNewBall();
	}
}


新建该类的蓝图类,并调整好大小,放入蓝图中

运行截图:

 代码链接:CodingInn/UE4 Basic Tutorial

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要在UE4C++代码实现ClampFloat,你可以使用FMath::Clamp函数。这个函数可以将一个浮点数限制在指定的范围内。 下面是一个示例代码,演示了如何在UE4C++代码中使用ClampFloat来限制一个浮点数的值: ```cpp float ValueToClamp = 10.0f; float MinValue = 0.0f; float MaxValue = 5.0f; float ClampedValue = FMath::Clamp(ValueToClamp, MinValue, MaxValue); ``` 在这个示例中,ValueToClamp的值被限制在0.0到5.0之间。如果ValueToClamp的值小于0.0,ClampedValue将会是0.0;如果ValueToClamp的值大于5.0,ClampedValue将会是5.0;如果ValueToClamp的值在0.0到5.0之间,ClampedValue将会是ValueToClamp的值本身。 你可以根据自己的需求修改示例代码中的ValueToClamp、MinValue和MaxValue的值来实现你想要的效果。\[1\] #### 引用[.reference_title] - *1* [使用Unreal5 创建C++类(FloatingActor)](https://blog.csdn.net/qq_42915442/article/details/125890112)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [UE4 C++代码实现碰撞小游戏](https://blog.csdn.net/Learning_xzj/article/details/124705378)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潮浪之巅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值