首页 > 编程语言 >【UEC++游戏案例】向上的小松饼

【UEC++游戏案例】向上的小松饼

时间:2023-11-04 16:44:58浏览次数:35  
标签:云朵 角色 void C++ Cake UE 松饼 include ACake

一. 效果与资源准备

1.1 游戏演示效果

 

 

1.2 游戏资产素材与源码

 

 

1.3 前期准备

  1. 创建无初学者内容的空项目

  2. 将素材文件拷贝到项目 Content 文件夹下

 

  1. 搭建场景(用 3D 场景模拟 2D 游戏效果)

 

 

二. 创建角色类与全局相机

2.1 创建角色类

  1. 创建C++类(Character),重命名 Cake(Public)

 

  1. 创建继承自 Cake 的蓝图(实例化),重命名 BP_Cake,并存放在 Blueprints 文件夹下

 

  1. 设置 BP_Cake 模型资产,并调整胶囊体覆盖模型

 

  1. 创建 BP_GameModeBase 游戏模式(GameModeBase),并和 BP_Cake 一起挂载到项目设置,那么在场景中放置玩家出生点 Player Start 后,运行时会自动生成 BP_Cake 的玩家出生点位置

 

 

2.2 创建全局相机

  1. 创建C++类(Actor),重命名 Camera(Public)

 

  1. 创建继承自 Camera 的蓝图(实例化),重命名 BP_Camera,并存放在 Blueprints 文件夹下

 

  1. 指定默认相机

 

  1. 调整相机正交模式

 

 

三. 移动逻辑

3.1 角色水平方向跟随鼠标移动

  1. 获取 PlayerController,运行时显示鼠标

 

  1. 角色随鼠标移动

 

  1. 防止角色出画,添加阻挡体积

 

  1. 运行效果:

 

 

3.2 角色垂直方向跳跃

  1. 角色垂直方向跳跃

 

  1. 绑定操作映射

 

  1. 运行效果:

 

 

3.4 设置角色速度

  1. 设置角色在空中/落地 2种状态下的不同速度

 

  1. 设置角色 BP_Cake 蓝图物理细节参数

 

 

3.4 全局相机垂直跟随

  1. 相机左右并不移动,只需调整 Z 轴跟随

 

  1. 设置背景板和阻挡体积为可移动,随摄像机移动

 

  1. 运行效果:

 

 

 

 

四. 创建云朵类

4.1 创建云朵类

  1. 创建C++类(Actor),重命名 Cloud(Public)

 

  1. 创建继承自 Cloud 的蓝图(实例化),重命名 BP_Cloud,并存放在 Blueprints 文件夹下

 

  1. 添加盒体检测组件和云朵组件

 

4.2 随机云朵贴图生成

  1. 通过修改材质中的,随机生成云朵显示

 

  1. 设置云朵的显示,并添加材质数组

 

  1. 运行效果(拖放多个 BP_Cloud 到场景中运行测试):

 

  1. 调整修改云朵的大小

 

 

 

 

4.3 角色触碰云朵则触发弹跳

  1. 重写碰撞函数,检测到角色则调用弹跳函数

 

  1. 运行效果(小球触碰到云朵就起飞):

 

 

4.4 云朵随机下雨

  1. 添加云朵雨组件并绑定,随机显示云朵雨

 

  1. 设置云朵雨的位置,并添加材质

 

  1. 运行效果(随机生成云朵雨):

 

 

五. 云朵生成器

5.1 创建云朵生成器

  1. 创建C++类(Actor),重命名 SpawnCloud(Public)

 

  1. 创建继承自 SpawnCloud 的蓝图(实例化),重命名 BP_SpawnCloud,存放在 Blueprints 文件夹下

 

  1. 云朵生成器的原理:在高处设置一块云朵生成区 SpawnArea,低处设置一块碰撞检测区 TriggerArea,当角色跳跃碰撞到检测区 TriggerArea,则整体上移,并在生成区 SpawnArea 随机位置生成云朵

 

 

5.2 随机位置生成云朵

  1. 添加云朵生成区域组件和检测生成区域组件

 

  1. 随机位置生成云朵

 

 

5.3 碰撞检测与初始化上升

  1. 检测是否与角色产生碰撞

 

  1. 云朵生成器的初始化与上升

 

  1. 在 BP_SpawnCloud 中调整参数

 

 

六. 计分系统与云朵销毁

6.1 计分系统

  1. 在角色中添加分数和计分方法

 

  1. 在云朵中添加分数文本,并显示分数

 

  1. 调整分数文本的字体位置大小

 

 

6.2 TimeLine 云朵销毁

  1. 结合蓝图中 Timeline 实现云朵淡入淡出效果

 

  1. 销毁相机视角外的多余云朵

 

  1. 在场景中调整销毁碰撞检测区域的位置

 

  1. 运行效果(销毁时显示计数并变化淡出,落下区域无云朵):

 

 

七. 游戏结束与重开

7.1 游戏结束的判定

  1. 结合蓝图中 Timeline (计数 2s )判断角色是否持续下落,如果持续下落则直接降落到地面

 

  1. 游戏结束的判定

 

 

7.2 游戏重开按钮

  1. 创建 UMG 蓝图,直接设计游戏重开按钮 UI(不建议在C++里面用代码创建UI按钮,是一件非常费力不讨好的事情)

 

  1. 设置 UI 动画

 

  1. 结合蓝图,在游戏结束后显示游戏重开按钮

 

 

7.3 点击事件游戏重开

  1. 添加按钮点击事件

 

  1. 重开则重新生成云朵

 

  1. 点击重开后,移除UI,调用 C++ 中 GameReset 函数

 

 

 

 

 

八. 游戏音乐

8.1 背景音乐

  1. 将音乐文件拖入场景,设置循环播放

 

 

8.2 角色接触云朵音乐

  1. 按云朵按位置播放音乐

 

  1. 设置音乐

 

 

8.3 云朵雨音乐

  1. 添加云朵雨的声音组件,并播放

 

  1. 创建雨声音频的 Cue 文件并打开,设置雨声衰减

 

  1. 在蓝图中设置云朵雨的音效

 

 

附录:C++文件提要

1. Cake.h

 1 // Fill out your copyright notice in the Description page of Project Settings.
 2 
 3 #pragma once
 4 
 5 #include "CoreMinimal.h"
 6 #include "GameFramework/Character.h"
 7 #include "Cake.generated.h"
 8 
 9 UCLASS()
10 class PROJECT_UPUPCAKE_API ACake : public ACharacter
11 {
12     GENERATED_BODY()
13 
14 public:
15     // Sets default values for this character's properties
16     ACake();
17 
18 protected:
19     // Called when the game starts or when spawned
20     virtual void BeginPlay() override;
21     
22     //声明一个玩家控制器
23     APlayerController* PlayerController;
24     
25     //角色在空中的速度
26     UPROPERTY(EditAnywhere,Category="Speed")
27     float AirSpeed;
28 
29     //角色落地的速度
30     UPROPERTY(EditAnywhere,Category="Speed")
31     float GroundSpeed;
32     
33     //计分
34     int Score;
35 
36     //判断是否死亡
37     bool bDeath;
38 
39     //判断游戏是否开始
40     bool bGamestart;
41 
42 public:    
43     // Called every frame
44     virtual void Tick(float DeltaTime) override;
45 
46     // Called to bind functionality to input
47     virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
48 
49     //声明角色跟随鼠标移动的函数
50     void FollowMouseCursorMoving();
51     
52     //声明跳跃,游戏启动时跳跃
53     void BeginJump();
54 
55     //声明跳跃,碰到云彩时跳跃
56     void Jump();
57 
58     //判断角色所在的场景,设置速度
59     void SetSpeed();
60 
61     //加分
62     void IncreaseScore();
63 
64     //获取分数
65     int GetScore() const;
66 
67     //判断角色是否持续下落
68     void IsFalling();
69 
70     //刷新时间轴
71     UFUNCTION(BlueprintImplementableEvent)
72     void UpdateTimer();
73 
74     //重置时间轴
75     UFUNCTION(BlueprintImplementableEvent)
76     void ResetTimer();
77 
78     //游戏结束
79     UFUNCTION(BlueprintCallable)
80     void GameOver();
81 
82     //游戏重开
83     UFUNCTION(BlueprintCallable)
84     void GameReset();
85     
86     //显示重开按钮
87     UFUNCTION(BlueprintImplementableEvent)
88     void ResetUI();
89 };

 

2. Cake.cpp

  1 // Fill out your copyright notice in the Description page of Project Settings.
  2 
  3 #include "Cake.h"
  4 #include "GameFramework/CharacterMovementComponent.h" //判断角色是否运动
  5 
  6 // Sets default values
  7 ACake::ACake()
  8 {
  9      // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 10     PrimaryActorTick.bCanEverTick = true;
 11 
 12     //速度初始化
 13     AirSpeed = 3500.0f;
 14     GroundSpeed = 300.0f;
 15 
 16     //分数初始化
 17     Score = 0;
 18 
 19     //判断是否死亡(初始化)
 20     bDeath = false;
 21     //判断游戏是否开始(初始化)
 22     bGamestart = false;
 23 }
 24 
 25 // Called when the game starts or when spawned
 26 void ACake::BeginPlay()
 27 {
 28     Super::BeginPlay();
 29 
 30     //获取 PlayerController(因为继承自 Character,可以直接 GetController()获取)
 31     PlayerController = Cast<APlayerController>(GetController());
 32 
 33     //获取鼠标显示
 34     PlayerController->bShowMouseCursor = true;
 35 
 36     //调用游戏重开
 37     GameReset();
 38 }
 39 
 40 // Called every frame
 41 void ACake::Tick(float DeltaTime)
 42 {
 43     Super::Tick(DeltaTime);
 44 
 45     if(!bDeath)
 46     {
 47         FollowMouseCursorMoving();  //每帧判断角色朝鼠标方向移动
 48     
 49         SetSpeed();  //每帧判断角色所在的场景,设置速度
 50     
 51         IsFalling();  //每帧判断角色是否持续下落
 52     }
 53 }
 54 
 55 // Called to bind functionality to input
 56 void ACake::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
 57 {
 58     Super::SetupPlayerInputComponent(PlayerInputComponent);
 59 
 60     //跳跃绑定
 61     PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACake::BeginJump);
 62 }
 63 
 64 void ACake::FollowMouseCursorMoving()
 65 {
 66     //获取鼠标在世界坐标下的位置(方向暂用不到)
 67     FVector MouseCursorLocation;
 68     FVector MouseCursorDirection;
 69     PlayerController->DeprojectMousePositionToWorld(MouseCursorLocation, MouseCursorDirection);
 70 
 71     //角色朝鼠标方向移动
 72     //获取 Y方向(左右方向)的偏移:鼠标位置-小球位置,用 Clamp()函数限定范围为 -1到 1
 73     float YDirection = FMath::Clamp(MouseCursorLocation.Y - GetActorLocation().Y, -1.0f ,1.0f);
 74     FVector Direction = FVector(0,YDirection,0);  //转换为向量
 75     AddMovementInput(Direction);
 76     
 77 }
 78 
 79 void ACake::BeginJump()
 80 {
 81     if(!bGamestart && GetActorLocation().Z != 0)
 82     {
 83         bGamestart = true;  //游戏开始
 84         Jump();
 85     }
 86 }
 87 
 88 void ACake::Jump()
 89 {
 90     //LaunchCharacter(发射方向,false:XY方向,true:Z方向),弹跳函数只对角色有效
 91     //false/true:是否替换原发射速度(true一直保持 1500)
 92     LaunchCharacter(FVector(0,0,1500),false, true);    
 93 }
 94 
 95 void ACake::SetSpeed()
 96 {
 97     //判断角色是否下落
 98     if(GetCharacterMovement()->IsFalling())
 99     {
100         GetCharacterMovement()->MaxWalkSpeed = AirSpeed;  //在空中
101     }
102     else
103     {
104         if(bGamestart)
105         {
106             GameOver();
107         }
108         GetCharacterMovement()->MaxWalkSpeed = GroundSpeed;  //在地面
109     }
110 }
111 
112 void ACake::IncreaseScore()
113 {
114     Score++;
115 }
116 
117 int ACake::GetScore() const
118 {
119     return Score;
120 }
121 
122 void ACake::IsFalling()
123 {
124     //如果 Z方向小于0,则表示准备开始下落了
125     if(GetCharacterMovement()->Velocity.Z < 0)
126     {
127         //持续性下落,刷新时间轴
128         UpdateTimer();
129     }
130     else
131     {
132         //短暂性下落,重置时间轴
133         ResetTimer();
134 
135     }
136 }
137 
138 void ACake::GameOver()
139 {
140     bDeath = true;
141     SetActorRotation(FRotator::ZeroRotator);  //旋转归零
142     EnableInput(PlayerController);  //启用输入
143 
144     //显示重开按钮
145     UE_LOG(LogTemp,Warning, TEXT("GameOver"));
146     
147     ResetUI();
148 
149 }
150 
151 void ACake::GameReset()
152 {
153     Score = 0;
154     bDeath = false;
155     bGamestart = false;
156 }

 

3.Camera.h

 1 // Fill out your copyright notice in the Description page of Project Settings.
 2 
 3 #pragma once
 4 
 5 #include "CoreMinimal.h"
 6 #include "Camera/CameraComponent.h"
 7 #include "GameFramework/Actor.h"
 8 #include "Cake.h"  //角色
 9 #include "Components/BoxComponent.h"  //盒体检测
10 #include "Camera.generated.h"
11 
12 UCLASS()
13 class PROJECT_UPUPCAKE_API ACamera : public AActor
14 {
15     GENERATED_BODY()
16     
17 public:    
18     // Sets default values for this actor's properties
19     ACamera();
20 
21 protected:
22     // Called when the game starts or when spawned
23     virtual void BeginPlay() override;
24 
25     //声明一个相机组件
26     UPROPERTY(VisibleAnywhere)
27     UCameraComponent* CameraComponent;
28 
29     //声明一个玩家控制器
30     APlayerController* PlayerController;
31 
32     //声明角色
33     ACake* Cake;
34 
35     //销毁相机视角外的多余云朵
36     UPROPERTY(VisibleAnywhere, Category = "Component")
37     UBoxComponent* DestroyArea;
38 
39 public:    
40     // Called every frame
41     virtual void Tick(float DeltaTime) override;
42 
43     //全局相机垂直跟随
44     void CameraMoving();
45 
46     //检测销毁区是否与多余云朵产生碰撞
47     virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;  //重写碰撞函数
48 };

 

4. Camera.cpp

 1 // Fill out your copyright notice in the Description page of Project Settings.
 2 
 3 #include "Camera.h"
 4 #include "Camera/CameraComponent.h"  //相机组件
 5 #include "Kismet/GameplayStatics.h"  //玩家控制器
 6 #include "Cloud.h"  //销毁相机视角外的多余云朵
 7 
 8 // Sets default values
 9 ACamera::ACamera()
10 {
11      // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
12     PrimaryActorTick.bCanEverTick = true;
13 
14     //定义一个相机组件
15     CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
16     //将相机组件设置为默认根组件
17     CameraComponent->SetupAttachment(RootComponent);
18 
19     //销毁相机视角外的多余云朵
20     DestroyArea = CreateDefaultSubobject<UBoxComponent>(TEXT("DestroyArea"));
21     //绑定到根组件
22     DestroyArea->SetupAttachment(RootComponent);
23 
24 }
25 
26 // Called when the game starts or when spawned
27 void ACamera::BeginPlay()
28 {
29     Super::BeginPlay();
30 
31     //获取玩家控制器
32     PlayerController = UGameplayStatics::GetPlayerController(this, 0);
33     //切换视角(立刻对齐)
34     PlayerController->SetViewTargetWithBlend(this, 0);
35 
36     //获取角色
37     Cake = Cast<ACake>(UGameplayStatics::GetPlayerPawn(this,0));
38     
39 }
40 
41 // Called every frame
42 void ACamera::Tick(float DeltaTime)
43 {
44     Super::Tick(DeltaTime);
45 
46     CameraMoving();  //每帧调用全局相机垂直跟随
47 }
48 
49 void ACamera::CameraMoving()
50 {
51     //(相机的 X,相机的 Y,角色的 Z)组成跟随坐标
52     FVector TargetLoaction = FVector(GetActorLocation().X, GetActorLocation().Y, Cake->GetActorLocation().Z);
53     //设置相机当前位置
54     SetActorLocation(TargetLoaction);
55 }
56 
57 void ACamera::NotifyActorBeginOverlap(AActor* OtherActor)
58 {
59     Super::NotifyActorBeginOverlap(OtherActor);
60 
61     //类型转换
62     ACloud* Cloud = Cast<ACloud>(OtherActor);
63     if(Cloud)
64     {
65         //检测到多余云朵则调用销毁
66         Cloud->Destroy();
67     }
68 }

 

5. Cloud.h

 1 // Fill out your copyright notice in the Description page of Project Settings.
 2 
 3 #pragma once
 4 
 5 #include "CoreMinimal.h"
 6 #include "Components/BoxComponent.h"
 7 #include "GameFramework/Actor.h"
 8 #include "Cake.h"  //角色
 9 #include "Components/TextRenderComponent.h"  //文本
10 #include "Sound/SoundWave.h"  //播放音乐
11 #include "Cloud.generated.h"
12 
13 UCLASS()
14 class PROJECT_UPUPCAKE_API ACloud : public AActor
15 {
16     GENERATED_BODY()
17     
18 public:    
19     // Sets default values for this actor's properties
20     ACloud();
21 
22 protected:
23     // Called when the game starts or when spawned
24     virtual void BeginPlay() override;
25 
26     //声明盒体检测组件
27     UPROPERTY(VisibleAnywhere, Category = "Collision")
28     UBoxComponent* BoxComponent;
29 
30     //声明云朵组件
31     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Show")
32     UStaticMeshComponent* CloudPlane;
33 
34     //声明云朵雨组件
35     UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Show")
36     UStaticMeshComponent* RainPlane;
37 
38     //云朵库
39     UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Show")
40     TArray<UTexture*> CloudTextures;
41 
42     //动态材质实例
43     UPROPERTY(BlueprintReadOnly, Category = "Show")
44     UMaterialInstanceDynamic* MaterialInstanceDynamic;
45     
46     UMaterialInterface* MaterialInterface;
47 
48     //分数文本
49     UPROPERTY(EditAnywhere, Category = "Show")
50     UTextRenderComponent* ScoreText;
51 
52     //检测是否与角色产生碰撞
53     ACake* Cake;
54 
55     //角色接触云朵音乐
56     UPROPERTY(EditAnywhere, Category = "Sound")
57     USoundWave* CloudSound;
58 
59     //云朵雨音乐
60     UPROPERTY(VisibleAnywhere, Category = "Sound")
61     UAudioComponent* RainSound;
62     
63 public:    
64     // Called every frame
65     virtual void Tick(float DeltaTime) override;
66     
67     //随机云朵生成
68     void SetRandomCloudTextures();
69 
70     //显示分数
71     void DisplayScore();
72 
73     //检测是否与角色产生碰撞
74     virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;  //重写碰撞函数
75     
76     //云朵淡出(蓝图实现)
77     UFUNCTION(BlueprintImplementableEvent)
78     void FadeOut();
79 };

 

6. Cloud.cpp

  1 // Fill out your copyright notice in the Description page of Project Settings.
  2 
  3 #include "Cloud.h"
  4 #include "Kismet/GameplayStatics.h"  //播放音乐
  5 #include "Components/AudioComponent.h"  //云朵雨音乐组件
  6 
  7 // Sets default values
  8 ACloud::ACloud()
  9 {
 10      // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 11     PrimaryActorTick.bCanEverTick = true;
 12 
 13     //定义盒体检测
 14     BoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxCollision"));
 15     //设置为默认根组件
 16     RootComponent = BoxComponent;
 17 
 18     //定义云朵
 19     CloudPlane = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CloudMesh"));
 20     //绑定到根组件(盒体检测)
 21     CloudPlane->SetupAttachment(RootComponent);
 22 
 23     //定义云朵雨
 24     RainPlane = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("RainMesh"));
 25     //绑定到云朵组件
 26     RainPlane->SetupAttachment(CloudPlane);
 27 
 28     //分数文本
 29     ScoreText = CreateDefaultSubobject<UTextRenderComponent>(TEXT("ScoreText"));
 30     //绑定到根组件
 31     ScoreText->SetupAttachment(RootComponent);
 32 
 33     //云朵雨音乐
 34     RainSound = CreateDefaultSubobject<UAudioComponent>(TEXT("RainSound"));
 35     //绑定到云朵组件
 36     RainSound->SetupAttachment(CloudPlane);
 37 }
 38 
 39 // Called when the game starts or when spawned
 40 void ACloud::BeginPlay()
 41 {
 42     Super::BeginPlay();
 43     
 44     SetRandomCloudTextures();  //调用随机云朵生成
 45 
 46     //随机显示云朵雨
 47     if(FMath::RandRange(0,2))
 48     {
 49         RainPlane->SetVisibility(true);
 50 
 51         //播放云朵雨音乐
 52         RainSound->Activate(true);
 53     }
 54 }
 55 
 56 // Called every frame
 57 void ACloud::Tick(float DeltaTime)
 58 {
 59     Super::Tick(DeltaTime);
 60 
 61 }
 62 
 63 void ACloud::SetRandomCloudTextures()
 64 {
 65     //获取 CloudPlane上的材质
 66     MaterialInterface = CloudPlane->GetMaterial(0);
 67     
 68     //通过创建动态材质实例来获取指定材质参数的随机材质
 69     MaterialInstanceDynamic = CloudPlane->CreateDynamicMaterialInstance(0,MaterialInterface);
 70     
 71     //随机数
 72     int index = FMath::RandRange(0,2);
 73     
 74     if(CloudTextures[index])
 75     {
 76         //设置材质参数值(参数节点名Texture,随机云彩库)
 77         MaterialInstanceDynamic->SetTextureParameterValue(FName(TEXT("Texture")), CloudTextures[index]);
 78         //将材质实例赋给模型
 79         CloudPlane->SetMaterial(0, MaterialInstanceDynamic);
 80     }
 81 }
 82 
 83 void ACloud::NotifyActorBeginOverlap(AActor* OtherActor)
 84 {
 85     Super::NotifyActorBeginOverlap(OtherActor);
 86 
 87     //类型转换
 88     Cake = Cast<ACake>(OtherActor);
 89     if(Cake)
 90     {
 91         //按位置播放音乐
 92         UGameplayStatics::PlaySoundAtLocation(this, CloudSound, GetActorLocation());
 93         //检测到角色则调用弹跳
 94         Cake->Jump();
 95         //显示分数
 96         DisplayScore();
 97 
 98         //云朵淡出(蓝图实现)
 99         FadeOut();
100     }
101 }
102 
103 void ACloud::DisplayScore()
104 {
105     Cake->IncreaseScore();
106     
107     //设置文本(类型转换 int - FString - FText)
108     ScoreText->SetText(FText::FromString(FString::FromInt(Cake->GetScore())));
109 }

 

7. SpawnCloud.h

 1 // Fill out your copyright notice in the Description page of Project Settings.
 2 
 3 #pragma once
 4 
 5 #include "CoreMinimal.h"
 6 #include "Cloud.h"
 7 #include "GameFramework/Actor.h"
 8 #include "Components/BoxComponent.h"  //盒体检测
 9 #include "SpawnCloud.generated.h"
10 
11 UCLASS()
12 class PROJECT_UPUPCAKE_API ASpawnCloud : public AActor
13 {
14     GENERATED_BODY()
15     
16 public:    
17     // Sets default values for this actor's properties
18     ASpawnCloud();
19 
20 protected:
21     // Called when the game starts or when spawned
22     virtual void BeginPlay() override;
23 
24     //云朵生成区域
25     UPROPERTY(VisibleAnywhere, Category = "Component")
26     UBoxComponent* SpawnArea;
27 
28     //根据角色位置,检测云朵是否可以继续生成
29     UPROPERTY(VisibleAnywhere, Category = "Component")
30     UBoxComponent* TriggerArea;
31 
32     //场景根组件
33     USceneComponent* DefaultRootComponent;
34 
35     //TSubclassOf:限定为 ACloud或其子类
36     UPROPERTY(EditAnywhere, Category = "Cloud")
37     TSubclassOf<ACloud> Cloud;
38 
39     //检测是否与角色产生碰撞
40     ACake* Cake;
41     
42     //云朵初始化
43     UPROPERTY(EditAnywhere, Category = "Cloud")
44     int32 InitialCloud;
45 
46     //云朵生成器每次上升距离
47     UPROPERTY(EditAnywhere, Category = "Cloud")
48     float SpawnSpacing;
49 
50 public:    
51     // Called every frame
52     virtual void Tick(float DeltaTime) override;
53 
54     //随机生成云朵
55     void SpawnCloud();
56 
57     //检测是否与角色产生碰撞
58     virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;  //重写碰撞函数
59     
60     //重开则重新生成云朵
61     UFUNCTION(BlueprintCallable)
62     void ResetCloud();
63 
64 };

 

8. SpawnCloud.cpp

  1 // Fill out your copyright notice in the Description page of Project Settings.
  2 
  3 #include "SpawnCloud.h"
  4 #include "Kismet/KismetMathLibrary.h"  //随机生成点
  5 #include "Cloud.h"  //生成云朵
  6 #include "Kismet/GameplayStatics.h"  //重开销毁之前的所有云朵
  7 
  8 // Sets default values
  9 ASpawnCloud::ASpawnCloud()
 10 {
 11      // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 12     PrimaryActorTick.bCanEverTick = true;
 13 
 14     //场景根组件
 15     DefaultRootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("DefaultRootComponent"));
 16     RootComponent = DefaultRootComponent;
 17     
 18     //云朵生成区域
 19     SpawnArea = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawnArea"));
 20     //绑定到场景根组件
 21     SpawnArea->SetupAttachment(RootComponent);
 22 
 23     //根据角色位置,检测云朵是否可以继续生成
 24     TriggerArea = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerArea"));
 25     //绑定到场景根组件
 26     TriggerArea->SetupAttachment(RootComponent);
 27 
 28     //云朵初始化
 29     InitialCloud = 6;
 30     //云朵生成器每次上升距离
 31     SpawnSpacing = 300.0f;
 32 }
 33 
 34 // Called when the game starts or when spawned
 35 void ASpawnCloud::BeginPlay()
 36 {
 37     Super::BeginPlay();
 38 
 39     ResetCloud();
 40 }
 41 
 42 // Called every frame
 43 void ASpawnCloud::Tick(float DeltaTime)
 44 {
 45     Super::Tick(DeltaTime);
 46 
 47 }
 48 
 49 void ASpawnCloud::SpawnCloud()
 50 {
 51     FVector SpawnOrigin = SpawnArea->Bounds.Origin;  //生成中心点
 52     FVector SpawnExtent = SpawnArea->Bounds.BoxExtent;  //生成范围
 53 
 54     //生成的位置
 55     //提供圆心和范围,Y轴随机生成点
 56     float YLocation = UKismetMathLibrary::RandomPointInBoundingBox(SpawnOrigin, SpawnExtent).Y;
 57     FVector SpawnLocation = FVector(SpawnArea->GetComponentLocation().X, YLocation, SpawnArea->GetComponentLocation().Z);
 58 
 59     //生成(生成云朵,生成位置,生成旋转)
 60     GetWorld()->SpawnActor<ACloud>(Cloud, SpawnLocation, FRotator::ZeroRotator);
 61 
 62     //云朵生成器上升(0,0,300)
 63     AddActorWorldOffset(FVector(0,0,SpawnSpacing));
 64 }
 65 
 66 void ASpawnCloud::NotifyActorBeginOverlap(AActor* OtherActor)
 67 {
 68     Super::NotifyActorBeginOverlap(OtherActor);
 69 
 70     //类型转换
 71     Cake = Cast<ACake>(OtherActor);
 72     if(Cake)
 73     {
 74         //检测到角色则调用随机生成云朵
 75         SpawnCloud();
 76     }
 77 }
 78 
 79 void ASpawnCloud::ResetCloud()
 80 {
 81     //云朵初始化
 82     InitialCloud = 6;
 83 
 84     //刷新位置为(0,0,0)
 85     SetActorLocation(FVector::ZeroVector);
 86 
 87     //重开销毁之前的所有云朵
 88     TArray<AActor*>ResetClouds;
 89     UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACloud::StaticClass(), ResetClouds);
 90     for(AActor* TActor : ResetClouds)
 91     {
 92         ACloud* FoundClouds = Cast<ACloud>(TActor);  //类型转换
 93         if(FoundClouds!= nullptr)
 94         {
 95             FoundClouds->Destroy();
 96         }
 97     }
 98     
 99     //云朵初始化随机生成
100     while(InitialCloud > 0)
101     {
102         SpawnCloud();
103         InitialCloud--;
104     }
105 }

 

 


参考资料:

【SiKi学院Unreal视频教程】UE4/5 虚幻4/5初级课程-向上的小松饼_哔哩哔哩_bilibili

 

 

标签:云朵,角色,void,C++,Cake,UE,松饼,include,ACake
From: https://www.cnblogs.com/ZWJ-zwj/p/17809517.html

相关文章

  • C/C++连接mysql(api接口方法详解)
      前言本篇记录C/C++连接mysql利用mysql的api接口的方法:这个方法的代码基本上很久都没有变过了,这里做个笔记来简单学习一下,还有一种方法等有时间了解后再来更新使用API的方式连接,需要先做环境配置,加载mysql的头文件和lib文件。可以看我之前的一篇文章VS中C/C++访问MySQL数据......
  • 图解C/C++灵魂:指针变量
    1、指针变量的基本操作基本操作inta,*iptr,*jptr,*kptr;iptr=&a;jptr=iptr;*jptr=100;kptr=NULL;图解:1.1己址和己空间指针变量也是一个变量,对应一块内存空间,对应一个内存地址,指针名就是己址。这空内存空间多大?一个机器字长(machineword),32位的......
  • 与c++比较学习rust3-1:变量和可变性
    rust文章:变量和可变性let,const这两个在c++中,没有与let相同的用法,letlet有点像constauto1.1.相同点:不需要指定类型。使用了constauto之后,不能改变值也不能改变类型。1.2.不同点:rust合法,c++中不合法(即c++中,不能重复定义一个变量)leta=2;leta=4;le......
  • 【每日例题】蓝桥杯 c++ 串的处理
    串的处理题目题目描述在实际的开发工作中,对字符串的处理是最常见的编程任务。本题目即是要求程序对用户输入的串进行处理。具体规则如下: 1.把每个单词的首字母变为大写。 2.把数字与字母之间用下划线字符(_)分开,使得更清晰3.把单词中间有多个空格的调整为1个空格。输入描......
  • WS-Introducing Colleagues
    2023.11.04周六中关村中心教室:11Inthislessonyouwilllearnsetphrasestodescribepeople'sprofessionalstrengthsandresponsibilities.Bytheendofthislesson,youwillbeabletointroduceacolleaguefromyourworkplace.A.KeyVocabularyMatchthep......
  • UE4中的GamePlay模块
    链接该文档主要通过学习自己构建文件,形成GamePlay模块。下图是利用引擎创建的一个空模板C++代码结构简要流程UBT虚幻编译工具(UBT:UnrealBuildTool)是一个自定义工具,负责管理通过各种编译配置来编译虚幻引擎4(UE4)源代码的过程。该工具处理所有复杂的项目编译工作,编译UE4的......
  • 【每日例题】蓝桥杯 c++ 最大降雨量
    最大降雨量题目本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。由于沙之国长年干旱,法师小明准备施展自己的一个神秘法术来求雨。这个法术需要用到他手中的49张法术符,上面分别写着1至49这49个数字。法术—共持续7周,每天小明都要使用—张法术符,法术符不能......
  • 【每日例题】蓝桥杯 c++ 最小的或运算
    最小的或运算题目问题描述给定整数a,b,求最小的整数工,满足a|a=ba,其中|表示或运算。输入格式第—行包含2个正整数a,b.输出格式输出共1行,包含1个整数,表示最终答案。样例输入样例输出评测数据规模对于所有测评数据,0<a,b<264.最小的或运算思路分析1.要求最小的x满足a|x=b|x,......
  • ASP.NET Core+Vue3 实现SignalR通讯
    从ASP.NETCore3.0版本开始,SignalR的Hub已经集成到了ASP.NETCore框架中。因此,在更高版本的ASP.NETCore中,不再需要单独引用Microsoft.AspNetCore.SignalR包来使用Hub。在项目创建一个类继承Hub,首先是写一个CreateConnection方法ConnectionId是SignalR中标识的客户端连接的唯......
  • 【每日例题】蓝桥杯 c++ 奖学金
    奖学金题目蓝桥杯奖学金题目分析由题目可知,该题涉及到五个属性:学号,语文分数,数学分数,英语分数,总分;由于我们需要通过输入语文、数学、英语分数,经过操作后,输出学号与总分,所以我们可以通过结构体进行存储。       下面是有关结构体的信息:结构体信息   2.......