目录
NewObject 和 CreateDefaultSubobject区别
创建一个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
(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);
-
- }
- UMyGameInstance* MyGameInstance;
-
- MyGameInstance = Cast
(GetWorld()->GetFirstPlayerController()->GetGameInstance());
应用游戏实例类
- // 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
(TEXT("MyCustomScene")); - MyMesh = CreateDefaultSubobject
(TEXT("MyCustomScene")); - MyParticle = CreateDefaultSubobject
(TEXT("MyCustomParticleSystem")); - MyBox = CreateDefaultSubobject
(TEXT("MyCustomBox")); - MyAudio = CreateDefaultSubobject
(TEXT("MyCustomAudio")); -
- RootComponent = MyScene;
- MyMesh->SetupAttachment(MyScene);
- MyParticle->SetupAttachment(MyScene);
- MyBox->SetupAttachment(MyScene);
- MyAudio->SetupAttachment(MyBox);
- }
静态加载类,要加 “_C”
- 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
(TEXT("MyRoot")); - MySpringArm = CreateDefaultSubobject
(TEXT("MySpringArm")); - MyCamera = CreateDefaultSubobject
(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
(GetPawn()); - pawn1->Zoom(1,1);
- }
- }
-
- void ASPlayerController::WheelDownFunction()
- {
- if (GetPawn()) {
- AMyPawn* pawn1 = Cast
(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"));
- }
在游戏模式的控制器脚本的开始运行函数中,
根据资源路径加载类,并创建该类的实例作为“提升为变量”的接盘。
- void ASPlayerController::BeginPlay()
- {
- Super::BeginPlay();
- UClass* widgetClass = LoadClass
(NULL, TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/HbtScripts/MyUserWidget233.MyUserWidget233_C'")); - UMyUserWidget* MyWidget = nullptr;
- MyWidget = CreateWidget
(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
创建的对象没有默认的宿主对象关系。