UNREAL 笔记

note_01 函数返回引用

函数返回引用与返回指针本质一样都是返回地址, 否则函数将返回数据的拷贝
ps: 不要将局部(函数中)创建的引用作为函数返回值

// 全局变量
int val = 10;

// 定义函数返回引用
int& RetValRef()
{
	return val;
}

// 将函数作为左值使用时(使用引用接收返回值),返回地址
// 本质上发生 int* const v1 = &val;
int& v1 = RetValRef(); 
// 引用 v1 作为左值可修改 val 的值
v1 = 20;

// 将函数作为右值使用时,返回该地址指向的值
// 本质上发生调用解引用 *val 对 v2 进行赋值
int v2 = RetValRef(); 

UFUNCTION 和 委托想返回 UStruct 类型的地址, 只能使用返回引用的方式.简单点说就是结构体在蓝图中要么是值传递要么是引用.
多播委托在返回结构体引用时, 不支持 non-const references
但 UClass 可以这两种情况都可以返回裸指针

// FLevelUpInfo is USTRUCT type
UFUNCTION()
// Inappropriate '*' on variable of type 'FLevelUpInfo'
FLevelUpInfo* GetLevelUpInfoByXP(int32 XP);
// OK
FLevelUpInfo& GetLevelUpInfoByXP(int32 XP);

// UClass可以返回裸指针
UFUNCTION()
AActor* GetEnemyActor();

// 多播委托在返回结构体引用时, 不支持 non-const references
// NewValue 如果不加 const 要报错, 但 MyActor 返回指针 OK
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FSomeDelegate, const FAttributeInfoData&, Data, AActor*, MyActor, const FVector&, NewValue);

note_02 IsValid

IsValid 既判断 nullptr 又判断是否准备被销毁(等待垃圾回收)

// Enemy 有可能会被销毁时使用 IsValid
if(IsValid(Enemy)) {...}
// 如果只是简单的 Proerty 等可使用
if(MaterialInstance) {...}

note_03 BlueprintCallable 函数的引用参数作为输入PIN

对于非 const 引用的参数在蓝图节点中默认将作为输出 Pin

// TargetLocation 将作为输入 pin
UFUNCTION(BlueprintCallable)
void SpawnProjectile(FVector& TargetLocation);

若要将 TargetLocation 作为输入 Pin, 可使用下面方法

// 将 TargetLocation 定义为 const
UFUNCTION(BlueprintCallable)
void SpawnProjectile(const FVector& TargetLocation);

// 或,使用宏
UFUNCTION(BlueprintCallable)
void SpawnProjectile(UPARM(ref) FVector& TargetLocation);

note_04 接口

对于无返回值的接口可以在 Event Graph 中实现 (类似 custom event),对于有返回值的接口需要通过 Override Function 来实现.
在蓝图中调用接口时可像静态函数一样调用 (不需要Cast),如果 Target 未实现该函数则会略过该函数的调用

/**
 * 定义为 BlueprintImplementableEvent 的函数
 * 表明该方法将只能在蓝图中实现,不能在 C++ 中实现
 * 函数不能加 virtual,会导致编译报错
 * 使用 const 将引用参数变更为输入 PIN (否则会作为输出 PIN)
 * 接口中的 BlueprintCallable 表明该函数将作为静态函数可在蓝图中直接调用
 */
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void DoMotionWarp(const FVector& FacingTarget);

/**
 * 定义为 BlueprintNativeEvent 的函数
 * 表明即可在蓝图中实现, 也可在 C++ 中定义默认实现
 * 函数不能加 virtual,会导致编译报错
 * 在 C++ 中实现该函数需要加上 _Implementation
 */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void SetCombatTarget(AActor* InCombatTarget);

在 C++ 中调用 BlueprintNativeEvent 接口,需要调用 Native C++ 实现的版本

// 判断是否实现接口
if (Actor->Implements<UCombatInterface>())
{
	// 调用 Native C++ 的实现
	if (!ICombatInterface::Execute_IsDead(Actor))
	{
		OutActors.AddUnique(Actor);
	}
}

在接口中使用 BlueprintNativeEvent 返回引用时发现报错(返回类型不匹配)

// 报错
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
TArray<FTaggedMontage>& GetAttackMontages();

// 改这样实现
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
void GetAttackTaggedMontages(TArray<FTaggedMontage>& OutTaggedMontages);

note_05 QUICK TIPS

Ctrl + 0~10 创建摄像机 Bookmark
Ctrl + MMB Drag 切换视图 Front / Top …
Ctrl + LMB 操控X轴 / Ctrl + RMB 操控Y轴 / Ctrl + LMB&RMB 操控Z轴
Ctrl + E 编辑选中物体
Ctrl + MMB 临时修改物体轴点
Shift + Click PIN 连接节点
Alt + Click PIN or Wire 移除连接
K 保存模拟状态, 退出模拟或PIE之后不恢复, 只对静态物体起效
Ctrl + P 打开资源窗口 “Open Asset”

note_06 Delegate 小坑

DYNAMIC delegate 参数需要加名称

/* DYNAMIC delegate 参数需要加名称 */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnFloatValueChangedSignature, float, Value);

非 DYNAMIC delegate 参数不能加名称, 否则报错 ‘参数过多’

/* 推荐参考官方定义方式 */
DECLARE_MULTICAST_DELEGATE_OneParam(FOnFloatValueChangedNative, float /* NewValue */);

note_07 智能指针

Shared Pointers, Weak Pointers, and Unique Pointers 不能用于 UObject 的类型
UObject 使用虚幻自己的反射系统管理

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值