目录
导入csv表格数据
创建、实例化、结构体
GameInstance
Actor
camera
绑定滚轮控制摇臂移动
碰撞绑定
角色碰撞设定
按钮
UI显示
单播代理
多播和动态多播
写一个接口
其他
NewObject 和 CreateDefaultSubobject区别
导入csv表格数据
创建一个object的C++类
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "CharacterMsgObject.generated.h"
USTRUCT(BlueprintType)
struct class CharacterMSG:public FTableRowBase {
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="CharacterMsg")
FString Name;
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="CharacterMsg")
float Health;
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="CharacterMsg")
int32 Level;
}
UCLASS()
class CPDD1_API UCharacterMsgObject : public UObject
{
GENERATED_BODY()
};
编译生成
做一个csv表格,对应结构体的元素
拖拽csv到UE5中
导入时选中上述创建的结构体
创建、实例化、结构体
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/Classes/Engine/DataTable.h"
#include "UObject/NoExportTypes.h"
#include "CharacterMsgObject.generated.h"
USTRUCT(BlueprintType)
struct FCharacterMSG :public FTableRowBase
{
GENERATED_USTRUCT_BODY()
FCharacterMSG();//略
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterMsg")
FString Name;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterMsg")
float Health;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "CharacterMsg")
int32 Level;
};
UCLASS()
class CPDD1_API UCharacterMsgObject : public UObject
{
GENERATED_BODY()
public:
FCharacterMSG CMSG;//供实体类调用
};
//创建实例
UCharacterMsgObject* MyTestMSGObject;
MyTestMSGObject = NewObject<UCharacterMsgObject>(GetWorld(), UCharacterMsgObject::StaticClass());
if (MyTestMSGObject) {
UE_LOG(LogTemp, Warning, TEXT("MyObject is %s"), *MyTestMSGObject->GetName());
UE_LOG(LogTemp, Warning, TEXT("NAME is %s"), *MyTestMSGObject->CMSG.Name);
UE_LOG(LogTemp, Warning, TEXT("HEALTH is %f"), MyTestMSGObject->CMSG.Health);
UE_LOG(LogTemp, Warning, TEXT("LEVEL is %d"), MyTestMSGObject->CMSG.Level);
}
GameInstance
UMyGameInstance* MyGameInstance;
MyGameInstance = Cast<UMyGameInstance>(GetWorld()->GetFirstPlayerController()->GetGameInstance());
应用游戏实例类
Actor
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/SceneComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Components/BoxComponent.h"
#include "Particles/ParticleSystemComponent.h"
#include "Components/AudioComponent.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"
UCLASS()
class CPDD1_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(VisibleAnywhere,BlueprintReadWrite,Category="MySceneComponent")
class USceneComponent* MyScene;
UPROPERTY(VisibleAnywhere,BlueprintReadWrite,Category="MySceneComponent")
class UStaticMeshComponent* MyMesh;
UPROPERTY(VisibleAnywhere,BlueprintReadWrite,Category="MySceneComponent")
class UParticleSystemComponent* MyParticle;
UPROPERTY(VisibleAnywhere,BlueprintReadWrite,Category="MySceneComponent")
class UBoxComponent* MyBox;
UPROPERTY(VisibleAnywhere,BlueprintReadWrite,Category="MySceneComponent")
class UAudioComponent* MyAudio;
};
AMyActor::AMyActor()
{
// 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;
MyScene = CreateDefaultSubobject<USceneComponent>(TEXT("MyCustomScene"));
MyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MyCustomScene"));
MyParticle = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MyCustomParticleSystem"));
MyBox = CreateDefaultSubobject<UBoxComponent>(TEXT("MyCustomBox"));
MyAudio = CreateDefaultSubobject<UAudioComponent>(TEXT("MyCustomAudio"));
RootComponent = MyScene;
MyMesh->SetupAttachment(MyScene);
MyParticle->SetupAttachment(MyScene);
MyBox->SetupAttachment(MyScene);
MyAudio->SetupAttachment(MyBox);
}
静态加载类,要加 “_C”
camera
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category="MySceneComponent")
USceneComponent* MyRoot;
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category="MySceneComponent")
USpringArmComponent* MySpringArm;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "MySceneComponent")
UCameraComponent* MyCamera;
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
MyRoot = CreateDefaultSubobject<USceneComponent>(TEXT("MyRoot"));
MySpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("MySpringArm"));
MyCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCamera"));
RootComponent = MyRoot;
MySpringArm->SetupAttachment(MyRoot);
MyCamera->SetupAttachment(MySpringArm);
MySpringArm->bDoCollisionTest = false;
绑定滚轮控制摇臂移动
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "SPlayerController.generated.h"
/**
*
*/
UCLASS()
class CPDD1_API ASPlayerController : public APlayerController
{
GENERATED_BODY()
public:
virtual void SetupInputComponent();
void WheelUpFunction();
void WheelDownFunction();
};
绑定键在UE5输入中设置
因为这里的Pawn和Controller都设置为当前gamemode的角色,所有getPawn会锁到当前操控者的Pawn。
#include "SPlayerController.h"
#include "MyPawn.h"
void ASPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
InputComponent->BindAction("WheelUp", IE_Pressed, this, &ASPlayerController::WheelUpFunction);
InputComponent->BindAction("WheelDown", IE_Pressed, this, &ASPlayerController::WheelDownFunction);
}
void ASPlayerController::WheelUpFunction()
{
if (GetPawn()) {
AMyPawn* pawn1= Cast<AMyPawn>(GetPawn());
pawn1->Zoom(1,1);
}
}
void ASPlayerController::WheelDownFunction()
{
if (GetPawn()) {
AMyPawn* pawn1 = Cast<AMyPawn>(GetPawn());
pawn1->Zoom(-1, 1);
}
}
void AMyPawn::Zoom(float Direction, float Speed)
{
float temp = MySpringArm->TargetArmLength - Direction * Speed * 10;
if (temp > 2000.f || temp < 500.f)
MySpringArm->TargetArmLength = temp;
}
碰撞绑定
UPROPERTY(VisibleAnywhere,BlueprintReadWrite,Category="MySceneComponent")
class UBoxComponent* MyBox;
MyBox->OnComponentBeginOverlap.AddDynamic(this, &AMyActor::BeginOverlapFunction);
MyBox->OnComponentEndOverlap.AddDynamic(this, &AMyActor::EndOverlapFunction);
MyBox->OnComponentHit.AddDynamic(this, &AMyActor::OnComponentHitFunction);
绑定函数的参数从何而来?
-转到定义
再转到定义
找到同义的参数,看数字,如果是six,就把该函数后6位复制过来,绑定函数的参数括号内,去掉定义类型和变量名之间的逗号即可。
UFUNCTION()
void BeginOverlapFunction(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION()
void EndOverlapFunction(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
UFUNCTION()
void OnComponentHitFunction(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
角色碰撞设定
//碰撞设置
MyBox->SetCollisionEnabled(ECollisionEnabled::NoCollision);
MyBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
MyBox->SetCollisionEnabled(ECollisionEnabled::PhysicsOnly);
MyBox->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
MyBox->SetCollisionEnabled(ECollisionEnabled::ProbeOnly);
MyBox->SetCollisionEnabled(ECollisionEnabled::QueryAndProbe);
//碰撞对象类型
MyBox->SetCollisionObjectType(ECC_WorldDynamic);
MyBox->SetCollisionObjectType(ECC_WorldStatic);
MyBox->SetCollisionObjectType(ECC_Pawn);
MyBox->SetCollisionObjectType(ECC_PhysicsBody);
MyBox->SetCollisionObjectType(ECC_Vehicle);
MyBox->SetCollisionObjectType(ECC_Destructible);
//碰撞响应
MyBox->SetCollisionResponseToAllChannels(ECR_Block);
MyBox->SetCollisionResponseToAllChannels(ECR_Overlap);
MyBox->SetCollisionResponseToAllChannels(ECR_Ignore);
MyBox->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);//pawn允许重叠
MyBox->SetCollisionResponseToChannel(ECC_WorldStatic,ECR_Block);//世界静态阻挡
MyBox->SetCollisionResponseToChannel(ECC_WorldDynamic,ECR_Ignore);//世界动态忽略
MyBox->SetBoxExtent(FVector(64, 64, 64));
按钮
绑定事件绑定函数时不用加括号
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/Button.h"
#include "Blueprint/UserWidget.h"
#include "MyUserWidget.generated.h"
UCLASS()
class CPDD1_API UMyUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(meta=(BindWidget))//UI控件创建的按钮名称和声明名称相同
UButton *ButtonStart;
UPROPERTY(meta=(BindWidget))
UButton* ButtonQuit;
UFUNCTION()
void Start();
UFUNCTION()
void Quit();
virtual bool Initialize()override;//重写组件初始化函数
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="MyHealth")
float CurrentHealth=100.f;
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="MyHealth")
float MaxHealth = 100.f;
UFUNCTION()
void UpdateHealth();
};
#include "MyUserWidget.h"
bool UMyUserWidget::Initialize()
{
if(!Super::Initialize())
return false;
ButtonStart->OnClicked.AddDynamic(this, &UMyUserWidget::Start);
ButtonQuit->OnClicked.AddDynamic(this,&UMyUserWidget::Quit);
return true;
}
void UMyUserWidget::UpdateHealth()
{
if (CurrentHealth <= 0) {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Death"));
}
else {
CurrentHealth -= 30;
}
}
void UMyUserWidget::Start()
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Start"));
UpdateHealth();
}
void UMyUserWidget::Quit()
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Quit"));
}
UI显示
在游戏模式的控制器脚本的开始运行函数中,
根据资源路径加载类,并创建该类的实例作为“提升为变量”的接盘。
void ASPlayerController::BeginPlay()
{
Super::BeginPlay();
UClass* widgetClass = LoadClass<UMyUserWidget>(NULL, TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/HbtScripts/MyUserWidget233.MyUserWidget233_C'"));
UMyUserWidget* MyWidget = nullptr;
MyWidget = CreateWidget<UMyUserWidget>(GetWorld(), widgetClass);
MyWidget->AddToViewport();
}
单播代理
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyDelegateActor.generated.h"
DECLARE_DELEGATE(NoParamDelegate);//1.声明代理类型
DECLARE_DELEGATE_OneParam(OneParamDelegate,FString);
DECLARE_DELEGATE_TwoParams(TwoParamDelegate, FString, int32);
DECLARE_DELEGATE_ThreeParams(ThreeParamDelegate, FString, int32, float);
DECLARE_DELEGATE_RetVal(FString, RetvalDelegate);
UCLASS()
class CPDD1_API AMyDelegateActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AMyDelegateActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
//2.声明代理名称
NoParamDelegate NoParamDelegate;
OneParamDelegate OneParamDelegate;
TwoParamDelegate TwoParamDelegate;
ThreeParamDelegate ThreeParamDelegate;
RetvalDelegate RetvalDelegate;
//声明代理函数
void NoParamFunction();
void OneParamFunction(FString str);
void TwoParamFunction(FString str,int32 value);
void ThreeParamFunction(FString str,int32 value,float balue1);
FString RetvalFunction();
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyDelegateActor.h"
// Sets default values
AMyDelegateActor::AMyDelegateActor()
{
// 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;
//3.绑定代理方法
NoParamDelegate.BindUObject(this, &AMyDelegateActor::NoParamFunction);
OneParamDelegate.BindUObject(this, &AMyDelegateActor::OneParamFunction);
TwoParamDelegate.BindUObject(this, &AMyDelegateActor::TwoParamFunction);
ThreeParamDelegate.BindUObject(this, &AMyDelegateActor::ThreeParamFunction);
RetvalDelegate.BindUObject(this, &AMyDelegateActor::RetvalFunction);
}
// Called when the game starts or when spawned
void AMyDelegateActor::BeginPlay()
{
Super::BeginPlay();
//4.调用代理
NoParamDelegate.ExecuteIfBound();
OneParamDelegate.ExecuteIfBound("OneParamDelegate");
TwoParamDelegate.ExecuteIfBound("TwoParamDelegate",648);
ThreeParamDelegate.ExecuteIfBound("ThreeParamDelegate",648,3.6f);
FString strvalue= RetvalDelegate.Execute();
}
// Called every frame
void AMyDelegateActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AMyDelegateActor::NoParamFunction()
{
GEngine->AddOnScreenDebugMessage(-1,5.0f,FColor::Blue,TEXT("NoParamDelegate"));
}
void AMyDelegateActor::OneParamFunction(FString str)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::Printf(TEXT("%s"),*str));
}
void AMyDelegateActor::TwoParamFunction(FString str, int32 value)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::Printf(TEXT("%s,%d"), *str,value));
}
void AMyDelegateActor::ThreeParamFunction(FString str, int32 value, float value1)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, FString::Printf(TEXT("%s,%d,%f"), *str, value, value1));
}
FString AMyDelegateActor::RetvalFunction()
{
FString str = FString::Printf(TEXT("RetvalFunction"));
return str;
}
多播和动态多播
声明类型
DECLARE_MULTICAST_DELEGATE_OneParam(OneParamMultiDelegate, FString);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDynamicMutilDelegate,FString,param);
声明名称
//多播代理
OneParamMultiDelegate OneParamMultiDelegate;
//动态多播
UPROPERTY(BlueprintAssignable)
FDynamicMutilDelegate FDynamicMutilDelegate;
绑定方法
//多播代理绑定
OneParamMultiDelegate.AddUObject(this, &AMyDelegateActor::MultiDelegateFunction1);
执行(参数根据自己定义的类型)
//执行多播代理
OneParamMultiDelegate.Broadcast("OneParamMultiDelegate");
//执行动态多播代理
FDynamicMutilDelegate.Broadcast("FDynamicMutilDelegate");
多播代理能同时调用多个函数,区别是动态多播能暴露给蓝图。
多播在脚本中写好绑定的多播函数。
动态多播在此基础上,能在蓝图上额外绑定事件,不止函数。
写一个接口
用I开头那个
声明要重写函数时,有{}
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "TestInterface.generated.h"
// This class does not need to be modified.
UINTERFACE(MinimalAPI)
class UTestInterface : public UInterface
{
GENERATED_BODY()
};
/**
*
*/
class CPDD1_API ITestInterface
{
GENERATED_BODY()
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
virtual void Attack() {};
virtual void CaclulateHealth() {};
};
调用,接屁股+头文件
重写
virtual void Attack() override;
virtual void CaclulateHealth() override;
然后再cpp编写即可。
其他
在使用打印语句时报错什么断点问题点,尝试在打印语句上加UFUNCTION
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("Death"));
变量要编辑,组件要可视,然后均为蓝图读写
NewObject
和CreateDefaultSubobject区别
NewObject
和CreateDefaultSubobject
是 Unreal Engine 中用于创建对象的两种不同方式,它们有以下区别:
对象类型:
NewObject
可以用于创建任何类型的对象,包括 UObject、AActor、APawn 等。而CreateDefaultSubobject
仅适用于在一个类的构造函数或初始化过程中创建默认的子对象。对象生命周期:使用
NewObject
创建的对象是动态分配的,并由开发人员负责管理其生命周期。而使用CreateDefaultSubobject
创建的对象是由 Unreal Engine 的对象系统自动管理的,它们的生命周期与宿主对象的生命周期相同。对象属性:
CreateDefaultSubobject
创建的对象会自动继承宿主对象的属性设置,例如编辑器中设置的默认值、蓝图可编辑性等。而使用NewObject
创建的对象需要手动设置属性。宿主对象关系:
CreateDefaultSubobject
创建的子对象与宿主对象之间建立了父子关系,这意味着子对象的生命周期与宿主对象紧密相关,并且在宿主对象销毁时,子对象也会被销毁。而NewObject
创建的对象没有默认的宿主对象关系。