UE/C++简单功能实现笔记

天空闲话  金牌会员 | 2023-6-17 11:36:22 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 907|帖子 907|积分 2721

本篇笔记主要用于记录如何利用C++在虚幻引擎5中实现一些基本的功能需求。

目录

实现功能与代码

以下代码均来自我的跳棋小游戏,所以默认Pawn的类名为ATiaoQi
构造函数中添加物体

.h
  1. UCLASS()
  2. class UNREALTIAOQI_API ATiaoQi : public APawn
  3. {
  4.     GENERATED_BODY()
  5. public:
  6.     UStaticMeshComponent* selectCircle;
  7.     ATiaoQi();
  8. }
复制代码
.cpp
  1. ATiaoQi::ATiaoQi() {
  2.     RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
  3.     selectCircle = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("selectCircle"));
  4.     static ConstructorHelpers::FObjectFinder<UStaticMesh> PlaneAsset(TEXT("/Script/Engine.StaticMesh'/Engine/BasicShapes/Plane.Plane'"));
  5.     static ConstructorHelpers::FObjectFinder<UMaterial> PlaneMaterial(TEXT("/Script/Engine.Material'/Game/Material/selectBall.selectBall'"));  //右键材质,复制引用即可获得该字符串
  6.     selectCircle->SetStaticMesh(PlaneAsset.Object);
  7.     selectCircle->SetMaterial(0, PlaneMaterial.Object);
  8.     const double selectCircleSize = 0.5;
  9.     selectCircle->SetWorldScale3D(FVector(selectCircleSize, selectCircleSize, selectCircleSize));
  10.     selectCircle->SetVisibility(false); //隐藏物体
  11. }
复制代码
运行时添加C++ Actor

.h
  1. class ACBall;
  2. UCLASS()
  3. class UNREALTIAOQI_API ATiaoQi : public APawn
  4. {
  5.     GENERATED_BODY()
  6. public:
  7.     ACBall* middleBall;
  8. }
复制代码
.cpp
  1. #include "CBall.h"
  2. const FTransform SpawnLocAndRotation(...) //省略具体值;
  3. middleBall = mainWorld->SpawnActorDeferred<ACBall>(ACBall::StaticClass(), SpawnLocAndRotation); //添加了ACBall类C++ Actor
复制代码
运行时设置动态材质及参数

.h
  1. class UNREALTIAOQI_API ATiaoQi : public APawn
  2. {
  3.     GENERATED_BODY()
  4. public:
  5.     UStaticMeshComponent* playerTriangle;
  6.     UMaterialInterface* triangleStaticMaterial;
  7.     UMaterialInstanceDynamic* DynMaterial;
  8. }
复制代码
.cpp
  1. ATiaoQi::ATiaoQi() {
  2.     static ConstructorHelpers::FObjectFinder<UMaterial> TrianMaterial(TEXT("/Script/Engine.Material'/Game/Material/nowPlayerMaterial.nowPlayerMaterial'"));
  3.     triangleStaticMaterial = TrianMaterial.Object;
  4. }
  5. void ATiaoQi::initColor(const FLinearColor& TargetColor) {
  6.     DynMaterial = UMaterialInstanceDynamic::Create(triangleStaticMaterial, this);
  7.     //也可以在这声明一个局部变量作为DynMaterial
  8.     DynMaterial->SetVectorParameterValue(FName(TEXT("Color")), TargetColor); //修改动态材质参数
  9.     playerTriangle->SetMaterial(0, DynMaterial);
  10. }
复制代码
蓝图调用C++函数

在头文件中给需要调用的函数声明前添加UFUNCTION(BlueprintCallable)即可。
编译后,在蓝图中,获得需要的对象,然后Cast to对应类,再调用函数即可。
蓝图访问C++成员

在头文件中给需要访问的变量声明前添加UPROPERTY(BlueprintReadWrite)即可。
编译后,在蓝图中,获得需要的对象,然后Cast to对应类,即可读取和修改其成员。
C++调用用户控件蓝图函数

思路是这样的,用户控件蓝图继承某个C++控件类,并用蓝图重写其部分C++函数。在控件蓝图中调用指定C++类的函数,使其获得蓝图对象的指针。随后在该C++类中即可直接使用该指针调用C++控件类的函数,即调用了用户控件蓝图的函数。
为什么不直接把用户控件定为C++类而要蓝图呢?因为C++类不提供UI界面的设计器,要直接敲代码,简直没法用。
TiaoQiWidget.h:C++ UserWidget类,控件蓝图继承该类。
  1. UCLASS()
  2. class UNREALTIAOQI_API UTiaoQiWidget : public UUserWidget
  3. {
  4.     GENERATED_BODY()
  5. public:
  6.     UFUNCTION(BlueprintNativeEvent)
  7.     void humanFinish();  //这是需要调用的函数,在蓝图中重写它。
  8.     virtual void humanFinish_Implementation() {}; //必须按照这种形式声明,即在原来的函数后面添加_Implementation,不可声明其=0,但可以为空。
  9. };
复制代码
TiaoQi.h:
  1. class UTiaoQiWidget;
  2. UCLASS()
  3. class UNREALTIAOQI_API ATiaoQi : public APawn
  4. {
  5.     GENERATED_BODY()
  6. public:
  7.     UTiaoQiWidget* widget;
  8.     UFUNCTION(BlueprintCallable)
  9.     void setWidget(UTiaoQiWidget* w=nullptr);
  10. }
复制代码
TiaoQi.cpp:
  1. #include "TiaoQiWidget.h"
  2. void ATiaoQi::setWidget(UTiaoQiWidget* w) { //在控件蓝图中调用,参数为self即可。
  3.     widget = w; //之后即可调用widget->humanFinish();
  4. }
复制代码
播放wav格式音效

.h
  1. UCLASS()
  2. class UNREALTIAOQI_API ATiaoQi : public APawn
  3. {
  4.     GENERATED_BODY()
  5. public:
  6.     USoundWave* jumpSoundWave[6];
  7.     ATiaoQi();
  8.     void playSound();
  9. }
复制代码
.cpp
  1. #include "Sound/SoundWave.h"
  2. const FString jumpSound[5] = {
  3. TEXT("/Script/Engine.SoundWave'/Game/soundFX/Jump/s1.s1'"),
  4. TEXT("/Script/Engine.SoundWave'/Game/soundFX/Jump/s2.s2'"),
  5. TEXT("/Script/Engine.SoundWave'/Game/soundFX/Jump/s3.s3'"),                                                 
  6. TEXT("/Script/Engine.SoundWave'/Game/soundFX/Jump/s4.s4'"),
  7. TEXT("/Script/Engine.SoundWave'/Game/soundFX/Jump/s5.s5'") };
  8. const FString nextStepSound[5] = {
  9. TEXT("/Script/Engine.SoundWave'/Game/soundFX/humanNextStep/button01_mp3.button01_mp3'"),
  10. TEXT("/Script/Engine.SoundWave'/Game/soundFX/humanNextStep/button03_mp3.button03_mp3'"),
  11. TEXT("/Script/Engine.SoundWave'/Game/soundFX/humanNextStep/button04_mp3.button04_mp3'"),
  12. TEXT("/Script/Engine.SoundWave'/Game/soundFX/humanNextStep/button05_mp3.button05_mp3'"),
  13. TEXT("/Script/Engine.SoundWave'/Game/soundFX/humanNextStep/button06_mp3.button06_mp3'") };
  14. ATiaoQi::ATiaoQi() {
  15.     for (int i = 0; i < 5; ++i) {
  16.         ConstructorHelpers::FObjectFinder<USoundWave> jumpSoundObject(*jumpSound[i]);
  17.         jumpSoundWave[i] = jumpSoundObject.Object;
  18.     }
  19. }
  20. void ATiaoQi::playSound(){
  21.     const FVector3d T = ...; // 发声地点,省略具体值。
  22.     UGameplayStatics::PlaySoundAtLocation(this, jumpSoundWave[FMath::RandRange(0, 4)], T);
  23.     //下面这种动态载入方式也可以
  24.     USoundWave* HitSound = LoadObject<USoundWave>(this, *nextStepSound[FMath::RandRange(0,4)]);
  25.     //下面这种是直接发声,无关具体位置。
  26.     if (HitSound) {UGameplayStatics::PlaySound2D(GetWorld(), HitSound);}
  27. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表