【UE-C++开发】②关于宏

目录

一、UPROPERTY宏

1. Category:分组(定义属性的分类)

2. Blueprint

2.1BlueprintReadOnly&BlueprintReadWrite

 2.2BlueprintAssignable&BlueprintCallable

 3. Edit

4. Visible

二、UCLASS宏

三、UFUNCTION()函数声明宏

四、USTRUCT()结构体声明宏

五、UENUM()枚举声明宏

总结


一、UPROPERTY宏

UPROPERTY:用于将对象属性暴露到蓝图中操作

语法:UPROPERTY(标记,标记,...,meta(key=value,key=value,...)

1. Category:分组(定义属性的分类)

UPROPERTY(Category=CategoryName)
Type VariableName;

UPROPERTY(Category="CategoryName|SubCategoryName")
Type VariableName;

2. Blueprint

2.1BlueprintReadOnly&BlueprintReadWrite

BlueprintReadOnly:只读
BlueprintReadWrite:可读可写

//① BlueprintReadOnly:只读
UPROPERTY(BlueprintReadOnly, Category=MyVars)
int ReadOnly;

//② BlueprintReadWrite:可读可写
UPROPERTY(BlueprintReadWrite, Category=MyVars)
int ReadWrite;

 2.2BlueprintAssignable&BlueprintCallable

BlueprintAssignable:应显示该属性,以供在蓝图中分配,蓝图中可绑定委托

BlueprintCallable:应显示该属性,以在蓝图代码中调用,蓝图中可绑定委托

//----------以下2个仅能用于Multicast代理:
//蓝图中可绑定委托
//③ BlueprintAssignable:应显示该属性,以供在蓝图中分配,
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FNotifyPawnChange, float, PawnHpPercent, float, PawnPhysicalShieldPercent, float, PawnMageShieldPercent);

	UPROPERTY(BlueprintAssignable)
	FNotifyPawnChange NotifyPawnChange;

//④ BlueprintCallable:应显示该属性,以在蓝图代码中调用
UPROPERTY(BlueprintCallable)

 3. Edit

//① EditAnywhere:可从编辑器内的属性窗口编辑,在原型和实例中
//(可以在编辑器窗口中进行编辑,也可在场景细节面板中编辑)
UPROPERTY(EditAnywhere)

//② EditDefaultsOnly:可通过属性窗口来编辑,仅能对原型编辑
//(可以在蓝图编辑器中编辑原型数据,但无法在场景细节面板中编辑场景中的具体对象)
UPROPERTY(EditDefaultsOnly)

//③ EditInstanceOnly:可通过属性窗口来编辑,仅能对实例而非原型进行编辑
//(属性的修改权限在实例,不能在蓝图编辑器原型中修改)
UPROPERTY(EditInstanceOnly)


//④ EditFixedSize:限定动态数组长度,禁止用户在蓝图属性面板中修改(单一添加无法显式,需要配合使用上面两个标记)
//只限制修改数组大小,不限制普通变量
UPROPERTY(BlueprintReadWrite, EditAnyWhere, EditFixedSize)

//⑤ EditInline:使得用户可编辑UnrealEd的属性查看器中的变量所引用的对象属性
//(仅对对象引用可用,包括对象引用数组)
UPROPERTY(EditInline)

 例:

 类的默认面板

 类的实例化细节面板

4. Visible

//① VisibleAnywhere:在属性窗口可见但无法编辑(原型实例中均可看到)
//如果标记组件指针,则表示组件内容在场景和编辑器的细节面板中显示所有编辑项
//如果标记的是普通属性(指针、基本数据类型、复合数据类型),则在场景和编辑器中只显示,无法编辑
UPROPERTY(VisibleAnywhere)

//② VisibleDefaultsOnly:仅在原型蓝图编辑器属性窗口中可见,无法编辑
//如果标记组件指针,则表示组件内容在场景和编辑器的细节面板中显示所有编辑项
//如果标记的是普通属性(指针、基本数据类型、复合数据类型),则只在编辑器中会显示(不在场景细节面板中显示),无法编辑
UPROPERTY(VisibleDefaultsOnly)

//⑩ VisibleInstanceOnly:仅在实例属性窗口中可见,无法编辑
//如果标记组件指针,则表示组件内容在场景和编辑器的细节面板中显示所有编辑项
///如果标记的是普通属性(指针、基本数据类型、复合数据类型),则只在场景细节面板中会显示(不在编辑器中显示),无法编辑
 UPROPERTY(VisibleInstanceOnly)

 例:

	//仅在类的默认设置可见
	UPROPERTY(VisibleDefaultsonly)
		int32 VisibleDefaultsnlyInt=10;
	//仅在实例化细节面板中可见
	UPROPERTY(VisibleInstanceOnly)
		FString VisibleInstanceOnlyString=TEXT("VisibleInstanceOnly");
	//在类的默认设置和实例化细节面板中都可见
	UPROPERTY(VisibleAnywhere)
	FVector VisibleAnywhereVector = {5,5,5};

运行结果:

类的默认设置

实例化细节面板

 5. Meta说明符

	//meta元数据说明符,
		//DisplayName别名
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(DisplayName="myValueDisplayName"), Category = "meta")
	int value3;
		//EditCondition条件控制编辑
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta= (DisplayName = "controller"), Category = "meta")
	bool isControl;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (EditCondition = "isControl"), Category = "meta")
	float value4;

二、UFUNCTION()函数声明宏

1. BlueprintCallable

反射系统可以识别的C++函数,表明此函数可在蓝图中被调用(当类被蓝图继承后才有效果),

// 函数在蓝图中调用
	UFUNCTION(BlueprintCallable, Category = "MyFunction")
	void MyFunction1();

//如果函数参数是引用类型,则在蓝图中调用被当做输出针脚
//如果传入参数是const修饰的引用类型,则在蓝图中被当做输入针脚
UFUNCTION(BlueprintCallable)
void Func(int32& A, const int32& B);  //void Func(输出针脚, 输入针脚)

 2. BlueprintPure

特殊标记,构建一个蓝图中的纯函数,用来获取对象数据 


//此标记的函数必须有有效返回值(无返回值编译报错),且在蓝图中无法加入到执行队列,只能以输出值的操作方式被使用,定义实现均放在cpp中
// 纯函数在蓝图中调用 BlueprintPure
	UFUNCTION(BlueprintCallable, BlueprintPure, Category = "MyFunction")
	bool MyFunction2();

 运行结果: 

3. Category

Category:标明此函数在蓝图中的分类

Category=”UE4Test|MyActor”  // |符号用来划分分类级别
UFUNCTION(BlueprintCallable,Category=”UE4Test|MyActor”);

4. BlueprintImplementableEvent

 BlueprintImplementableEvent:用此标记可以在C++中构建函数声明,但是定义由蓝图完成,从而达到C++向蓝图进行调用的目的,在CPP无需定义

	//BlueprintImplementableEvent在C++中声明,但不能定义;蓝图中可重载,可定义
	UFUNCTION(BlueprintImplementableEvent)
	void Test01();
	UFUNCTION(BlueprintImplementableEvent)
	int	Test02();
	UFUNCTION(BlueprintImplementableEvent)
	void Test03(const FString &MyString);
	UFUNCTION(BlueprintImplementableEvent)
	int Test04(const FString& MyString);

//必须放在公有或受保护的访问域中,不能在C++中定义函数(本质上相当于纯虚函数virtual)
//注意:
//① 无参无返,则在蓝图中当作事件Event使用;
//② 无参有返,则在蓝图中当作函数使用(需要在函数的overlap中寻找)
//③ 有参无返(基本数据类型),当作普通事件输入参数使用
//④ 有参无返(自定义数据类型,如FString),编译不过
//⑤ 有参无返(基本数据类型/自定义数据类型引用),当作函数看待,在函数表中寻找

 

 5. BlueprintNativeEvent

标记的函数只能在c++中调用,在蓝图中无法调用,此标记可以标注函数可在蓝图中被重写,并且具备在C++中有另一个标记函数

//.h
UFUNCTION(BlueprintNativeEvent)
void Func01(int32 Num);  //在蓝图中调用
//如果蓝图重写此函数,则函数实现在蓝图,如果蓝图没有重写此函数,则函数实现在(函数名_ Implementation)上
//蓝图中实现后,可以右键函数节点,选择add call to parent function可以调用父类的函数逻辑(类似类中的虚函数,在继承关系中子类可以调用父类的虚函数)
//注意:
//① 无参无返,则在蓝图中当作事件Event使用;
//② 无参有返,则在蓝图中当作函数使用(需要在函数的overlap中寻找)

//.cpp
//需要在名称后加上_Implementation
void Func01_Implementation(int32 Num)
{
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("TestA_Implementation")));
};  

蓝图中重载:

运行结果

三、USTRUCT()结构体声明宏

反射系统可以识别的C++结构体

//结构体
//声明类
USTRUCT(BlueprintType)
struct FMyStruct
{
	GENERATED_BODY()
	UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="mystruct")
	int Data1;
	UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="mystruct")
	float Data2;
	
};


//声明对象
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="myStruct")
	FMyStruct MyStruct;

四、UENUM()枚举声明宏

反射系统可以识别的C++枚举值


UENUM(BlueprintType)
namespace MyEnumType 
{
	enum MyCustomEnum
	{
		Type1,
		Type2,
		Type3,
	};

}

UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="MyEnum")
TEnumAsByte<MyEnumType::MyCustomEnum> MyCustomEnum;


<think>好的,用户说他是UE5 C++开发者,我需要针对他的背景来回答之前的警告问题。之前他提到的是关于变量未使用的警告,现在需要结合UE5 C++的具体情况来分析。 首先,UE5的C++项目通常会有自己的编码规范和,比如可能使用UE_LOG进行日志输出,或者GEngine->AddOnScreenDebugMessage来显示信息。用户可能在代码中声明了变量但没有使用它们,导致编译器警告。 接下来,要考虑UE5特有的情况,比如可能在蓝图中使用的UPROPERTY变量,如果没有正确标记,或者没有在蓝图中使用,也会出现未使用的警告。另外,UE5的代码生成工具可能对变量使用有特殊要求,比如必须初始化或显式标记为未使用。 然后,需要回顾之前的解决方案,将其适配到UE5的上下文中。例如,检查变量是否在UE的日志系统或调试信息中使用,或者是否正确暴露给蓝图。同时,可能需要提到UE5的如ensureMsgf或check来使用变量,或者使用UNUSED来显式标记未使用的变量以避免警告。 还要注意UE5的编码规范,比如变量命名通常带有前缀,如b表示布尔,或者使用驼峰命名法,这可能影响变量声明的正确性。另外,如果变量是在头文件中声明但未在源文件中使用,也可能导致警告,需要检查头文件中的声明是否必要。 最后,可能需要提醒用户关于UE5的热重载功能,如果在编辑器中修改代码后没有正确编译或重新加载,可能会导致变量看似未使用的情况,需要确保编译过程完成。同时,建议用户查看输出日志,确定警告的具体位置和上下文,以便更精准地解决问题。</think>$\textbf{针对UE5 C++开发者的变量未使用警告解决方案}$ $\boxed{\text{核心问题}}$:在UE5 C++项目中,变量被赋值但未被后续代码引用。以下是$\textbf{专为UE引擎优化的解决策略}$: --- $\textbf{步骤1:验证UE特定使用场景}$ 1. $\textbf{蓝图交互检查}$:若变量涉及`UPROPERTY` ```cpp // 错误案例:暴露给蓝图但未实际使用 UPROPERTY(VisibleAnywhere) float MinSqDist; // 仅声明未使用 // 正确做法:在C++代码或蓝图中必须有读取操作 void YourActor::Tick(float DeltaTime) { if (MinSqDist > Threshold) {...} // 添加实际使用 } ``` 2. $\textbf{调试输出规范}$:使用UE专用日志系统 ```cpp // 必须包含头文件 #include "Kismet/KismetSystemLibrary.h" // 在赋值后添加调试输出 UKismetSystemLibrary::PrintString( GetWorld(), FString::Printf(TEXT("最小距离:%f,索引:%d"), MinSqDist, MinSqDistIdx), true, // 显示到屏幕 false, // 不写入日志文件 FColor::Green, 2.0f // 显示时长 ); ``` --- $\textbf{步骤2:处理引擎编译特性}$ 3. $\textbf{抑制警告的UE标准方法}$(慎用): ```cpp // 使用UE_UNUSED显式标记 UE_UNUSED(MinSqDist); UE_UNUSED(MinSqDistIdx); // 或使用C++17特性(需启用对应编译标准) [[maybe_unused]] float MinSqDist = JuLi[idx]; ``` 4. $\textbf{热重载陷阱}$:在编辑器运行中修改代码后,必须: - 完全编译(非热重载) - 关闭"Live Coding"功能测试 - 清除Intermediate/Binaries目录 --- $\textbf{步骤3:优化代码结构}$ 5. $\textbf{基于UE的算法优化}$: ```cpp // 用TArray内置方法替代手动查找 TArray<float> JuLiArray; int32 MinIndex = INDEX_NONE; // UE专用无效索引标识 const float MinVal = JuLiArray.FindMinIndex(MinIndex); // 自动获取最小值和索引 // 或使用Algo模板库 auto MinIt = Algo::MinElement(JuLiArray); if (MinIt != JuLiArray.end()) { const int32 FoundIndex = MinIt - JuLiArray.begin(); } ``` 6. $\textbf{异步任务处理}$:若涉及多线程 ```cpp // 错误案例:在AsyncTask中赋值但未同步 AsyncTask(ENamedThreads::GameThread, [this, idx](){ MinSqDist = JuLi[idx]; // 可能未被主线程及时使用 }); // 正确做法:使用原子变量或任务委托 std::atomic<float> MinSqDist_Atomic{0.0f}; AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [&](){ MinSqDist_Atomic.store(JuLi[idx]); }); // 主线程中读取 if (MinSqDist_Atomic.load() > Threshold) {...} ``` --- $\textbf{UE专有注意事项}$: - $\textbf{垃圾回收}$:若变量持有`UObject`指针,需确保: ```cpp UPROPERTY() // 必须标记以防止意外回收 AActor* CachedActor; ``` - $\textbf{序列化}$:检查变量是否需要`SaveGame`标记 ```cpp UPROPERTY(SaveGame) float PersistentValue; // 会被存档系统使用 ``` 通过结合UE5引擎特性处理变量生命周期和多线程场景,可从根本上消除警告并提升代码健壮性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值