【UE4全反射松耦合框架笔记】第一章 UE4框架基础(上)

PixelStreaming数据通信 PixelStreaming数据通信简介H5到UE4通信H5发送UE4接收UE4到H5通信UE4发送H5接收案例 简介 使用UE4.26像素流送方案,启动像素流送插件 UE4编辑器设置中添加运行参数 复制出引擎目录下的WebServers文件夹 E:\Program Files\Epic Games\UE_4.26\Engine\Source\Programs\PixelStreaming\WebServers 修改WebServers\player.htm内容 运行WebServers\Signal 阅读详情

第一章 UE4框架基础(上)

一、蓝图与C++交互

在蓝图中创建变量时,有四个选项可供选择:
创建变量
变量类型与C++分别对应的是:

AActor*					//对象引用

TSubclassOf<AActor>		//类类型

TSoftObjectPtr<AActor>	//对象软引用

TSoftClassPtr<AActor>	//类类型软引用

FStringAssetReference	//对象路径的引用,不用区分类型

方法与蓝图交互:

BlueprintCallable				蓝图可调用且由C++定义
BlueprintImplementableEvent		C++声明,由蓝图实现
BlueprintNativeEvent			C++实现,蓝图可覆盖,C++实现的方法需要加后缀_Implementation,但实现的方法不需要声明
Exec							控制台可调用
meta							可以限定对象属性

例如:

//限定对象属性
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(MetaClass="Actor", ToolTip="Bool Type"))
FStringAssetReference AssetRef;

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin=10, ClampMax=100), Category="FrameWork")
int32 CInt;

//BlueprintNativeEvent方法声明
UFUNCTION(BlueprintNativeEvent)
void NativeFunc();
//BlueprintNativeEvent方法实现
void AMyActor::NativeFunc_Implementation()
{...}

//控制台命令方法
UFUNCTION(Exec)
void ConsoleFunc(const FString& info);
/*Exec标记的函数,只有在主要的几个类中(GameInstance,GameMode等)才会执行。
我们可以在GameInstance中重写ProcessConsoleExec方法,使其可以被执行到。*/
virtual bool ProcessConsoleExec(const TCHAR* Cmd, FOutputDevice& Ar, UObject* Executor) override;
bool UMyGameInstance::ProcessConsoleExec(const TCHAR* Cmd, FOutputDevice& Ar, UObject* Executor)
{
	bool Res = Super::ProcessConsoleExec(Cmd, Ar, Executor);
	if(!Res)	//命令没有执行成功(没有找到相关命令需要执行)
	{
		for(TActorIterator<AActor> It(GetWorld()); It; ++It)	//遍历Actor类
		{
			Res = It->ProcessConsoleExec(Cmd, Ar, Executor);	//逐个执行
			if(Res)	break;					//如果执行成功,就退出循环并结束
		}
	}
	return Res;
}

对象获取方法:

  • 方法一:迭代器获取
for(TActorIterator<AActor> It(GetWorld()); It; ++It){...}
  • 方法二:静态方法获取
TArray<AActor*> Actors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACharacter::StaticClass(), Actors);

属性修改事件:

//编辑器模式修改变量(属性)时,将会触发此方法
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif

#if WITH_EDITOR
void AMyCharacter::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
	Super::PostEditChangeProperty(PropertyChangedEvent);
	//当对象被修改的属性名等于AMyCharacter类(一般为当前对象的类名)的Param变量(属性名)时,执行此段代码
	if(PropertyChangedEvent.Property&&
		PropertyChangedEvent.Property->GetName() == GET_MEMBER_NAME_CHECKED(AMyCharacter, Param)){...}
}
#endif

开发时,注意的几个点

  1. 声明的函数,如果不是BlueprintImplementationEvent函数,请一定要定义,否则可能会编译失败
  2. 引用头文件时,如果是此类的声明头文件,可以直接使用#include “XXX.h”,不用加路径,而其它自己创建的头文件,要注意加上路径,但路径中不用加Public。这个主要跟模块设置有关。
  3. 因IDE的关系,编译报错的点不一定就是真正的问题所在,但可以从报错的文件中查找错误

二、UMG与C++交互

文件目录:

Game
Common
Gameplay
UI
HUD
Widget

在PlayerController中设置输入模式:

//输入模式
//输入模式有三种类型:FInputModeGameAndUI,FInputModeGameOnly,FInputModeUIOnly
FInputModeGameAndUI InputMode;
InputMode.SetLockMouseToViewBehavior(EMouseLockMode::DoNotLock);
InputMode.SetHideCursorDuringCapture(false)
SetInputMode(InputMode);

//显示鼠标
bShowMouseCursor = true;

创建Widget:

//方法1:
TSubclassOf<UMyWidget> MyWidgetClass;			//可以在蓝图中选择UMyWidget及继承自UMyWidget的子类
UMyWidget* MyWidget = CreateWidget<UMyWidget>(GetWorld(), MyWidgetClass);
MyWidget->AddToViewport();		//添加到界面

//方法2:在Widget内部,通过WidgetTree创建。可用于创建子组件
UImage* DynImage = WidgetTree->ConstructWidget<UImage>(UImage::StaticClass());

从蓝图获取组件:

//方法一:从根节点获取
UCanvasPanel* RootPanel = Cast<UCanvasPanel>(GetRootWidget());
if(RootPanel)
{
	UImage* BGImage = Cast<UImage>(RootPanel->GetChildAt(0));
}

//方法二:GetWidgetFromName
UButton* ButtonTwo = (UButton*)GetWidgetFromName(TEXT("ButtonTwo"));	//通过方法获取到UMG中变量名为ButtonTwo的控件

//方法三:反射绑定
UPROPERTY(meta=(BindWidget))
UButton* ButtonOne;		//变量名应与UMG中控件名一致

给控件绑定函数(事件):

//方法一:__Internal_AddDynamic
Button->OnClick.__Internal_AddDynamic(this, &UMyWidget::ButtonEvent, FName("ButtonEvent"));

//方法二:FScriptDelegate
FScriptDelegate BtnEventDel;
BtnEventDel.BindUFuncion(this, "ButtonEvent");
Button->OnReleased.Add(BtnEventDel);

//方法三:声明BlueprintCallable,蓝图调用
UFUNCTION(BlueprintCallable)
void ButtonEvent();

添加和移除组件:

//添加子组件
UWidget->AddChildXXX(...);
//移除子组件
UWidget->RemoveChild(...);
//从父组件移除
UWidget->RemoveFromParent();

设置布局:

//在Canvas中添加子组件会返回slot插槽对象,通过设置这个对象可以改变布局
//UCanvasPanel* MyCanvasPanel;
//UImage* MyImage;
UCanvasPanelSlot* ImgSlot = MyCanvasPanel->AddChildToCanvas(MyImage);
ImgSlot->SetAnchors(FAnchors(0.f));	//设置锚点
ImgSlot->SetOffsets(FMargin(100.f, 100.f, 50.f, 50.f));	//设置位移

三、生命周期探索

Actor的初始化过程:

  1. Actor的构造函数
  2. 初始化Components
  3. PostInitializeCompoents()
  4. BeginPlay()
  5. Tick(float DeltaSeconds)

UserWidget的初始化过程:

  1. 构造器函数 UUserWidget(const FObjectInitializer& ObjectInitializer);
  2. Initialize()
  3. NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

世界的创建:

  1. GameInstance实例化,执行Init函数
  2. 执行关卡蓝图构造器
  3. 执行场景中Actors的构造器
  4. 执行GameMode构造器
  5. 执行关卡蓝图、场景中Actors及GameMode的PostInitializeComponents函数(子组件构造完成后执行)
  6. 执行Controller、HUD、Character等在GameSettings中设置的Gameplay框架类的构造器及PostInitializeComponents函数
  7. 执行场景中Actor、GameMode、关卡蓝图、Gameplay框架类的BeginPlay函数
  8. 若有Widget在执行HUD类的BeginPlay函数时被创建,将执行Widget的构造器及Initialize函数
  9. 执行所有已经初始化完成类的Tick函数

提前预置Actor和设置中的类(如Gameplay框架类)等会在都执行完成Construct和PostInitializeComponents后才会执行BeginPlay,然后一起执行Tick。另外Gameplay框架类会在GameMode执行完 PostInitializeComponents后,才会开始构造。

初始化过程测试图

上图中,因为UserWidget是在HUD执行BeginPlay时才被创建,所以会在HUD后执行构造器函数和Initialize函数

四、全局类与接口

全局类

方法一:UBlueprintFunctionLibrary
继承自UBlueprintFunctionLibrary的类,主要是给蓝图提供静态函数访问,如果只在C++中使用,不必继承此类。常用的C++类,例如UGameStatics、UGameUserSettings类等,均是继承自UBlueprintFunctionLibrary类。

方法二:GameEngine->GameSingleton
GEngine->GameSingletion是GEngine下的一个UObject指针,可以作为全局变量提供给所有对象调用,这个变量可以在编辑器中指定其类型,UE4建议在这个对象中放置不需要修改的变量。
GameSingleton的设置
GameSingleton类

/*
UCLASS中Blueprintable及BlueprintType解释
Blueprintable/NotBlueprintable
	此说明符表示蓝图可继承此类,默认情况下是NotBlueprintable。但如果此类的父类包含此说明符,在默认情况下将继承父类的说明符,允许蓝图继承此类。因为UObject没有此标识符,所以若要蓝图可以继承和使用此类,需要声明此标识符。
BlueprintType
	表示蓝图可以创建此类类型的变量。但其实,只要声明Blueprintable,就可以作为变量在蓝图中使用了。所以,结构体和枚举可能更需要使用此标识符。此处,还可以再探究。
*/
UCLASS(Blueprintable, BlueprintType)
class XXX_API UMyGameSingleton: public UObject
{
	GENERATED_BODY()
	...
}

获取GameSingleton的变量

UMyGameSingleton* MySingleton = Cast<UMyGameSingletonClass>(GEngine->GameSingleton);

其它引擎全局类
UGameInstance:生命周期一直伴随整个游戏周期,从打开程序直到关闭程序。
UGameplayStatics:可以获取常用的Gamplay对象
UGameUserSettings:可以获取到配置信息

接口

一般,我们创建接口类时,尽量继承UInterface类。继承自UInterface的接口类,可以通过函数反射,提供给蓝图实现和使用。
当创建继承自UInterface的类时,引擎帮我们生成的头文件会有两个类,我们在第二个类中(以I开头)声明函数。
如果接口中的抽象方法需要在蓝图中调用,我们实现的自定义接口类一般有两种情况:1. 函数可以在C++子类和蓝图类中实现和调用 2.函数只能在C++中实现,在蓝图类中调用。

情况一:默认接口类中的函数是必须要允许在蓝图中实现

通过集成UInterface类,引擎自动生成的接口类的宏不带标识符meta=(CannotImplementInterfaceInBlueprint)。所以,我们在接口类中声明的方法的UFUNCTION宏必须使用BlueprintNativeEvent或者BlueprintImplementableEvent标识符。
自定义接口类头文件:

//默认情况下,UINTERFACE标识符只有MinimalAPI
UINTERFACE(MinimalAPI)
class UMyInterface : public UInterface
{
	GENERATED_BODY()
}

class XXX_API IMyInterface
{
	GENERATED_BODY()
public:
	/*默认下的接口类,在声明UFUNCTION宏时,必须使用BlueprintNativeEvent或BlueprintImplementableEvent标识符。
	第一和第三个函数可以在C++文件中实现;这四个函数均可在蓝图中实现;前两个函数可以在蓝图中调用。
	这四个函数没有使用virtual和=0,第一和第三个函数在C++中实现见下面代码*/
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	void FuncOne();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void FuncTwo();

	UFUNCTION(BlueprintNativeEvent)
	void FuncThree();

	UFUNCTION(BlueprintImplementableEvent)
	void FuncFour();
}

继承上述接口类的子类头文件:

class XXX_API AMyActor : public AActor, public UMyInterface
{
	GENERATED_BODY()
public:
	//注意这里的实现,需要加virtual、override关键字,且函数名加_Implementation后缀
	virtual void FuncOne_Implementation() override;

	virtual void FuncThree_Implementation() override;
}

如果接口中的方法只在C++中实现和调用,那就在接口中声明抽象方法并实现,比如:

virtual void GetIndex() {}
情况二:函数不需要在蓝图中实现

如果虚函数不能在蓝图中实现,我们必须在自定义接口类的宏中添加meta=(CannotImplementInterfaceInBlueprint)标识符。
只有加上此标识符,虚函数的UFUNCTION宏才可以不添加BlueprintNativeEvent和BlueprintImplementableEvent标识符,也就不需要在蓝图中实现。

UINTERFACE(MinimalAPI, meta=(CannotImplementInterfaceInBlueprint))
class UMyInterface : public UInterface
{
	GENERATED_BODY()
}

class XXX_API IMyInterface
{
	GENERATED_BODY()
public:
	//此类需要使用virtual关键字,函数后边的=0表示继承的子类需要实现此方法。如果允许蓝图调用,可以加上BlueprintCallable,否则可以不加
	UFUNCTION(BlueprintCallable)
	virtual void FuncOne() = 0;
}

继承UInterface的接口,不能创建UPROPERTY()变量

虚函数的调用

允许在蓝图实现的函数和不允许在蓝图实现的函数的调用方法不同。

//调用第一步是相同的,就是首先我们需要获取一个继承定义接口类的对象
TArray<AActor*> Actors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), AMyInterfaceActor::StaticClass(),  Actors);
if(Actors.Num() > 0)
{
	IMyInterface* MyInterfacePtr = Cast<IMyInterface>(Actors[0]);	//强制转换为父类接口
	/*
	因为使用了BlueprintNativeEvent和BlueprintImplementableEvent标识符的函数的实现与一般C++不同,所以调用方法不同。
	下面代码的调用就是允许在蓝图中实现的函数的调用。
	*/
	MyInterfacePtr->Execute_FuncOne(Actors[0]);		//函数名添加前缀Execute_,第一个参数为子类对象,后续参数为函数实际参数
	//不在蓝图实现的虚函数与一般C++相同,所以按照常规方法调用即可
	//MyInterfacePtr->FuncOne();		//而一般的虚函数可以在转换后直接调用,或者直接调用对象的函数即可。Actors[0]->FuncOne();
}

五、委托与函数传递

委托

UE4委托参见另一篇笔记《【UE4笔记】委托》

函数传递

TFunction

声明TFunction模板变量

public:
	//设置TFunction模板变量的值,这里主要说明如何将函数作为参数传入
	void SetFuncOne(TFunction<void(FString)> Func)
	{		//变量实现应在cpp中,这里为方便说明,所以在声明中实现
		FuncOne = Func;
	}
	
public:
	//TFunction模板声明
	TFunction<void(FString)> FuncOne;  	//void是函数返回类型,FString为函数参数类型

通过Lambda表达式传参,调用SetFuncOne函数

public:
	void MyFunc(FString Str);

//SetFuncOne的调用
XXX->SetFuncOne([this](FString InfoStr){MyFunc(InfoStr);});

使用TFunction定义统一接口

声明函数模板
template<typename RetType, typename... VarTypes>
void PassFunc(TFunction<RetType(VarTypes...)> TarFunc)
{
	bool Result = TarFunc(FString("Hello"), 1024);
}

========================================================
调用函数模板
bool Func(FString, int32);
XXX->PassFunc<bool, FString, int32>([this](FString InfoStr, int32 Count){return Func(Info, Count);});
TMemFunPtrType

使用这种方法传递的函数,函数的返回值和传入参数都已经在函数参数指明,所以传入时,只需要按照函数要求传入即可。

//声明单播委托,这里主要是测试传递函数,所以将接收的函数绑定到这个单播委托上
DECLARE_DELEGATE(FMyDelegate);

//声明模板函数
public:
	template<typename UserClass>
	void BindAndExecDel(UserClass* TarObj, typename TMemFunPtrType<false, UserClass, void(FString, int32)>::Type InMethod);
public:
	FMyDelegate MyDelegate;


//实现模板函数,TMemFuncPtrType模板作为参数类型,用于传递函数参数
template<typename UserClass>
void XXX::BindAndExecDel(UserClass* TarObj, typename TMemFunPtrType<false, UserClass, void(FString, int32)>::Type InMethod)
{
	//因为MyDelegate是一个无参委托,所以调用ExecuteIfBound时是不需要传入参数的。但是绑定的函数却是有参,所以我们可以在BindUObject函数调用,即绑定函数到委托时,固定参数。
	MyDelegate.BindUObject(TarObj, InMethod, FString("Hello World!"), 1024);
	MyDelegate.ExecuteIfBound();
}

//调用模板函数,这里调用的时候,可以传入函数地址
void Func(FString, int32);
XXX->BindAndExecDel(this, &XXX::Func);		//允许传入的函数为返回类型void,参数为FString和int

FMethodPtr

使用TMehtodPtr时,我们需要声明一个委托,然后通过委托的静态成员获取到函数类型。这种方法可以用于函数委托绑定的传参。下面也将介绍如何不用声明委托,即可使用此方法传递函数。
使用这种方法传入的函数,它的返回值和参数类型都是在委托中声明的。

//声明单播委托
DECLARE_DELEGATE_TwoParams(FMyDelegate, FString, int32)

//声明模板函数
public:
	//参数使用了委托,通过委托的静态成员获取函数声明类型
	template<typename UserClass>
	void BindAndExecDel(UserClass* TarObj, typename FMyDelegate::TUObjectMethodDelegate<UserClass>::FMethodPtr InMethod);
public:
	FMyDelegate MyDelegate;

//实现模板函数
template<typename UserClass>
void BindAndExecDel(UserClass* TarObj, typename FMyDelegate::TUObjectMethodDelegate<UserClass>::FMethodPtr InMethod)
{
	//委托的参数是在调用ExecuteIfBound或者Broadcast时传入的。此处注意与上面无参委托的区别。
	MyDelegate.BindUObject(TarObj, InMethod);
	MyDelegate.ExecuteIfBound(FString("Hellow, World!"), 1024);
}

void Func(FString, int32);
XXX->BindAndExecDel(this, &XXX::Func);

不声明委托,使用FMethodPtr传递函数(泛型定义统一接口)
使用这种方法,基本可以传递任意返回值和参数的函数,只需要在调用函数时,按照需要的函数声明委托即可。

函数模板定义:
public:
	//上例中的委托类型被模板参数替代
	template<typename DelegateType, typename UserClass, typename... VarTypes)
	inline void PassFunc(UserClass* TarObj, typename DelegateType::template TUObjectMethodDelegate<UserClass>::FMethodPtr InMethod, VarTypes... Vars)
	{
		//这里的委托声明只是为了测试函数的传递。
		DECLARE_DELEGATE(FTempDelegate);
		FTempDelegate TempDelegate;
		TempDelegate.BindUObject(TarObj, InMethod, Vars...);		//传入多个参数,参数名后有...,不要忘记
		TempDelegate.ExecuteIfBound();
	}
=======================================================================================================
函数模板调用:
void Func(FString, int32);

//函数调用时,函数模板第一个参数传入委托类型
DECALRE_DELEGATE_TwoParams(FTempDelegate, FString, int32);
XXX->PassFunc<FTempDelegate>(this, &XXX::Func, FString("Hello"), 1024);

【信息科学与工程学】【物理/化学和工程科学】第三十九篇 流体力学库01 ​复杂度本质​:预填充是计算密集型,生成是显存带宽密集型。​趋势​:​硬件协同​:NVIDIA H100的FP8指令集进一步加速量化。​算法突破​:Mamba类SSM架构替代Attention,将预填充复杂度降至。​实践建议​:优先采用LMDeploy的在线INT4量化​()与动态分块,兼顾效率与易用性。 阅读详情

相关推荐

【信息科学与工程学】【物理/化学和工程技术】【数学分析】第一百九十九篇 矢量分析和场论及高温合金——低空经济01

br>∗∗散度∗∗:\nabla \cdot \mathbf{F} = \frac{1}{h_1 h_2 h_3} \left[ \frac{\partial}{\partial u_1}(h_2 h_3 F_1) + \frac{\partial}{\partial u_2}(h_3 h_1 F_2) + \frac{\partial}{\partial u_3}(h_1 h_2 F_3) \right]。计算\frac{\partial \rho}{\partial t} = \psi^

weixin_49199313的博客 254

UE4-(蓝图)移除控件蓝图时自动调用节点

在游戏中可能存在游戏按到ESC键后弹出选项菜单,此时游戏暂停,当点击返回游戏后游戏继续,菜单界面消失 在UE4中菜单的消失使用的是Remove from Parent,将UI控件移除。 可以使用 Event Destruct 节点设置一些逻辑, EventDestruct节点是当控件被移除时调用 ...

Stone的博客 3468

掌握UE4中的PostProcessScanEffect后期处理扫描效果

PPE是一种后期处理技术,它可以在游戏运行时,对渲染后的场景图像进行操作,实现各种视觉效果。通过PPE技术,开发者可以轻松地在游戏中的特定区域或者全屏添加扫描线、光晕、颜色偏移等动态效果。在UE4中,PPE是通过蓝图系统和材质编辑器实现的,这使得即使是不具备深厚编程背景的艺术家也能创建出复杂的效果。

weixin_33816734的博客 952

c#往结构体里面读数据_c# 结构体实现数据新增(数据字段较多的情况使用) 一

点击新增按钮{ChkFormIDBox.Text = Coeno.DevChk.DevChk.CleanUpInput(ChkFormIDBox.Text); --清除表单文本框数据输入if (string.IsNullOrEmpty(ChkFormIDBox.Text)){lblMsg.Text = "表单序号不能为空";lblMsg.ForeColor = System.Drawing.Co...

weixin_28811227的博客 495

手把手教你用Microsoft AEC Challenge数据集训练自己的回声消除模型(附完整代码)

本文详细介绍了如何使用Microsoft AEC Challenge数据集训练专业的回声消除模型,包括环境准备、数据清洗、模型架构设计、训练流程和实际部署注意事项。通过完整的代码示例和实战指南,帮助开发者快速掌握AEC技术,提升语音通信系统的回声消除效果。

weixin_27697385的博客 454

科研智能体平台搭建与实战:大模型如何驱动科研自动化

大模型技术的快速发展,正推动AI智能体从单纯对话工具向主动执行任务的科研伙伴演进。智能体的核心原理在于整合模型调用、工具使用、知识库检索与工作流编排,使其能够自主拆解目标、执行操作并迭代优化。在科研场景中,这一技术价值尤为突出:文献初筛、实验数据清洗、代码调试、结果汇总等高频重复劳动均可实现自动化,大幅释放研究者精力。从基础组件配置到多智能体协同,从平台选型到提示词调优,实际落地需要关注模型匹配、工具稳定性、记忆管理与人机校验机制。本文基于真实工程经验,系统梳理科研智能体平台的搭建路径、应用案例与高频问题排

weixin_32597009的博客 282

UE4-桌面宠物/透明窗口

(上面的程序有一些鼠标交互的小问题,只有鼠标在窗口的非透明区域,才能接收到按键消息,否则只能接收到鼠标位移消息,这个可以自己去改改,然后鼠标灵敏度适配相关功能也需要自己去做)不过相较于这样,我更倾向于创建一个dx11设备,然后绑定新窗口表面,避免了将GPU->CPU->GPU的两设备之间的内存拷贝操作,感兴趣的大佬们可以尝试一下的(需要注意,新窗口需要在单独线程上运行,否则会争夺UE窗口的窗口消息,导致UE窗口不再渲染。,换一个颜色就会好很多,例如(255,0,0)。

2301_77795305的博客 2983

机器人学习-matlab四足机器人控制仿真

《机器人学,机器视觉与控制》学习笔记 使用工具箱版本9.10 题目与解决思路: 【1】. 通过减少复位期间的抬腿高度来缩短复位的轨迹 Z轴向下,为了减小复位器件的抬腿高度,应当缩小△Z,故可以将示例程序中zu值调大。 【2】. 增加腿的步幅 腿的步幅可由改变x方向上腿前进和后退运动的极限来达到,令xf = 7; xb = -xf;即可。 ...

weixin_44609769的博客 5538

【UE4全反射松耦合框架笔记】第一章 UE4框架基础(下)

第一章 UE4框架基础(下) 文章目录第一章 UE4框架基础(下)六、反射应用详解七、资源同步、异步加载八、异步加载UClass类型九、LatentAction潜在事件 六、反射应用详解 常用反射宏 UCLASS USTRUCT UENUM UPROPERTY UFUNCTION 通过反射获取实例的函数 StaticLoadClass StaticLoadObject LoadClass L...

胡嘿嘿 2097

YOLOv8改进 | Conv篇:基于FasterBlock与C2f结构的二次创新,参数量下降70万【附保姆级代码】

通过引入FasterBlock二次创新C2f结构,我们成功地对YOLOv8模型进行了优化,显著降低了其参数量,并提升了推理速度,而精度保持不变甚至有所提升。该模型在多个实际应用场景中展现出了优异的性能,尤其是在嵌入式设备、移动端和自动驾驶等领域,具有广泛的应用潜力。未来的研究将进一步优化模型结构,探索更多的应用场景,为目标检测技术的发展做出贡献。

一键难忘的博客 3214

【ArcGIS风暴】Win10操作系统ArcGIS许可License无法启动的解决方法汇总(绝对成功!)

文章目录1. 关闭Windows Defender2. 关闭系统防火墙3. 删除迈克菲(McAfee)杀毒软件4. 在系统服务中启动 在安装ArcGIS软件时,最重要的一步是许可服务的正常启动,通常,由于各种各样的原因,ArcGIS许可管理器License Manager十有八九会无法启动,点N多次都没反应,如果许可服务不能如愿启动的话,即使Desktop安装成功,也是无法打开的。本文汇总了Win10操作系统之上ArcGIS安装过程中可能会导致服务无法启动的原因及解决办法。 ArcGIS安装参考教程:

智慧空间实验室 2万+

【UE4全反射松耦合框架笔记】开篇与目录

UE4全反射松耦合框架笔记 笔记说明 《UE4全反射松耦合框架笔记》系列是根据梁迪老师的《UE4全反射零耦合框架开发坦克游戏》中的知识点所做的总结,并对其中一些知识点进行修正和补充说明。此笔记作为自己学习与总结,如有错误,望指出,谢谢。 目录 第一章 UE4框架基础 UE4框架基础(上) UE4框架基础(下) 第二章 框架结构搭建 框架介绍 仿QT打印功能 模组生命周期 枚举匹配模组结构 注册对象...

胡嘿嘿 1073

量子化学仿真软件:VASP_(9).磁性材料计算

在量子化学仿真软件 VASP 中,磁性材料的计算是一个复杂但重要的过程。通过正确设置磁性状态、分析磁性性质、优化计算参数以及研究磁性相变和磁动力学,可以更准确地描述和预测磁性材料的性能。希望本节的内容能够为研究磁性材料的科研人员提供有用的参考和指导。

kkchenjj的博客 1375

【UE4全反射松耦合框架笔记】第二章 框架结构搭建

第二章 框架结构搭建 文章目录第二章 框架结构搭建一、框架介绍二、仿QT打印功能 一、框架介绍 框架目录: 二、仿QT打印功能

胡嘿嘿 807

[最新]MapReduce综合应用案例 — 气象数据清洗

【代码】[最新]MapReduce综合应用案例 — 气象数据清洗。

M_inherit的博客 1014

如何在 Mac 上下载安装 Xcode——并为 iOS 开发更新它原文

下载 Xcode安装命令行工具打开新版本删除文件注意,我在下面的步骤中列出了一些终端命令。这些命令可以被输入到你现在的工作目录中。这意味着你不需要导航到任何特定的文件夹。如果你真的想这样做,你可以在输入下面的步骤中的命令之前先输入== cd==。这将使你返回到主文件夹。

专注于AI领域前沿知识,业余爱好开发软件 4666

UE4运用C++和框架开发坦克大战教程笔记(一)(第1~4集)

本篇笔记内容包括:笔记前言、框架简述、蓝图与 C++ 交互(方法和变量)、UMG 与 C++ 交互、UE4 对象的生命周期(从构造函数到 Tick())

q446013924的博客 1039

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

UE4 C++联网RPC教程笔记(一)(第1~4集)

本篇笔记内容包括:教程介绍、自定义 Debug 功能、Actor 的复制、判断当前端的联网状态

q446013924的博客 2298

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

UE4全反射零耦合笔记——蓝图与C++交互

创建新的C++类 添加到文件Public/GameFrame中: FWGameMode FWGameInstance FWPlayerController FWCharacter 添加到文件Public/Common中: FWCommon(Object类:公共的类) 在FWCommon中添加Debug函数 FWCommon.h #pragma once #include “CoreMinimal.h” #include “UObject/NoExportTypes.h” #include “En.

笔记的博客 884

UE4全反射零耦合笔记——UMG与C++交互

1,创建Widget //创建Widget方法一:CreateWidget //UXXXWidgetClass是UClass UXXXWidget* XWidget = CreateWidget< UXXXWidget >(GetWorld(),UXXXWidgetClass); //创建Widget方法二 : 通过WidgetThree创建组件,只能在Widget内部创建 UImage* DynImage = WidgetTree->ConstructWidget<UImage&

笔记的博客 909

UE4C++基础(二)

基础回顾 UE4C++基础(一)_WLSTLA-优快云博客 1. C++与UMG交互 ​ 首先我们需要设置玩家的输入模式,可以在PlayerController中的BeginPlay进行设置: void AUIController::BeginPlay() { Super::BeginPlay(); FInputModeGameAndUI InputMode; InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::LockAlways);

WLSTLA 3234

UE4全反射零耦合笔记——获取场景对象的方法

01 使用迭代器获取 for (TActorIterator<AActor> It(GetWorld()); It; ++It) 02 使用静态方法获取 TArray<AActor*> ActArray; UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFWCharacter::StaticClass(), ActArray);

笔记的博客 774

Matlab光纤束拉锥模拟:开启合束与空间复用新视界

Matlab光纤束拉锥模拟多个光纤按照特定排列方式进行拉锥,实现合束或者空间复用功能最近在研究光纤束拉锥的相关内容,发现用Matlab进行模拟是个挺有趣的事儿。光纤束拉锥可以让多个光纤按照特定排列方式进行拉锥,从而实现合束或者空间复用功能。合束能把多束光合成一束,提升功率;空间复用则能在有限空间里传输更多信息,厉害得很。

zAnllYrAbIo的博客 254

【云原生Java冷启动优化黄金法则】:20年实战提炼的7步精准调优路径(含GraalVM+Quarkus实测数据)

解决云原生Java函数计算冷启动慢痛点,提供可落地的冷启动优化步骤。覆盖Serverless场景,融合GraalVM原生镜像与Quarkus轻量框架,实测启动耗时降低85%。含JVM调参、依赖精简等7步精准路径,值得收藏。

VarLens的博客 385
上一篇: 【UE4笔记】各种Delegate委托的区别和应用
下一篇: 【UE4全反射松耦合框架笔记】第一章 UE4框架基础(下)
Im 胡嘿嘿
博客等级 码龄10年 148粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值