【虚幻引擎】UE4/UE5插件

这篇具有很好参考价值的文章主要介绍了【虚幻引擎】UE4/UE5插件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、插件分类

插件分为七大类

  • Blank:空白插件,可以从头开始自己定义想要的插件风格和内容,用此模板创建的插件不会有注册或者菜单输入。
  • BlueprintLibrary:创建一个含有蓝图函数库的插件,此模板函数都是静态全局函数,可以在蓝图中直接调用。
  • ContentOnly:创建一个只包含内容的空白文件
  • Editor Toolbar Button:创建关卡编辑器的工具栏中的按钮插件,首先在创建的点击事件中实现一些内容
  • Editor Standalone Window:创建关卡编辑器的工具栏中的按钮插件,点击按钮可调出一个空白选项独立卡窗口
  • Editor Mode:创建一个含有编辑器模式的插件
  • Third Party Library:创建一个已包含第三方库的插件

【虚幻引擎】UE4/UE5插件

二、插件模块 

插件可含有任意数量的模块源目录。多数插件仅有一个模块(但可创建多个模块,例如插件包含纯编辑器功能时),及游戏期间要运行的其他代码。

插件源文件的大部分布局与引擎中其他C++模块相同。

在模块的 Source 目录(或其子目录)内,插件可在标头文件中声明新反映的类型(UCLASSUSTRUCT 等)。引擎的构建系统将检测此类文件,并按需要生成代码支持新类型。需遵守C++模块中使用 Uobjects 时的一般规则,例如在模块的源文件中包含生成的标头文件和模块 generated.inl 文件。

UE4支持共生模块和插件。通过在自身.uproject文件中启用插件,项目模块可依赖插件。类似地,通过在自身.uplugin文件中启用其他插件,插件可表明依赖性。但其中有一项重要限制:插件和模块将拆分为若干层级,仅能依赖同一级或更高级的其他插件或模块。例如,项目模块可依赖引擎模块,但引擎模块无法依赖项目模块。这是因为引擎(及其所有插件和模块)的级别高于项目,须能在无项目的情况下编译。

三、引擎插件和项目插件

虚幻引擎4的 Engine 目录下包含部分内置插件。引擎插件和项目插件类似,但可用于所有项目。此类插件通常由引擎和工具程序员创建,目的在于提供可在多个项目中使用并能在单一位置维护的基线功能。利用此功能,用户可直接添加或覆盖引擎功能,而无需修改引擎代码。

【虚幻引擎】UE4/UE5插件

项目插件位于项目目录的 Plugins 子文件夹下,将在引擎或编辑器启动时被探测和加载。如插件包含具有 Source 文件夹(和 .Build.cs 文件)的模块,插件代码将被自动添加到生成的C++项目文件,以便在开发项目时开发插件。编译项目时,有可用源的插件都被作为游戏依赖项进行编译。项目生成器将忽略无 Source 文件夹的插件,其不会出现在C++项目文件中,但若存在二进制文件,启动时仍将加载此类插件。

【虚幻引擎】UE4/UE5插件

插件的描述,描述的文件是Json格式,以官方案例为准

{
    "FileVersion" :3,
    "Version" :1,
    "VersionName" :"1.0",
    "FriendlyName" :"UObject Example Plugin",
    "Description" :"An example of a plugin which declares its own UObject type.This can be used as a starting point when creating your own plugin.",
    "Category" :"Examples",
    "CreatedBy" :"Epic Games, Inc.",
    "CreatedByURL" :"http://epicgames.com",
    "DocsURL" :"",
    "MarketplaceURL" :"",
    "SupportURL" :"",
    "EnabledByDefault" : true,
    "CanContainContent" : false,
    "IsBetaVersion" : false,
    "Installed" : false,
    "Modules" :
    [
        {
            "Name" :"UObjectPlugin",
            "Type" :"Developer",
            "LoadingPhase" :"Default"
        }
    ]
}

 四、案例分析Editor Standalone Window

  创建一个Editor Standalone Window插件,命名为:MyEditorStandaloneWindow

【虚幻引擎】UE4/UE5插件

创建成功之后VS会出现Plugins

【虚幻引擎】UE4/UE5插件 出现三个cpp文件

MyEditorStandaloneWindow:主函数所有的主要逻辑都是写在这里,包含了注册命令,布局分布,按钮点击事件等。

【虚幻引擎】UE4/UE5插件

MyEditorStandaloneWindowCommand:声明一些命令变量,注册函数等。

【虚幻引擎】UE4/UE5插件

MyEditorStandaloneWindowStyle:插件的样式风格。

【虚幻引擎】UE4/UE5插件

创建好之后我们会在编辑器工具栏中看到我们的插件

【虚幻引擎】UE4/UE5插件

 点击这个按钮触发的事件通过MapAction创建代理函数绑定,执行

【虚幻引擎】UE4/UE5插件

 创建独立窗口

void FMyEditorStandaloneWindowModule::PluginButtonClicked()
{
	FGlobalTabmanager::Get()->TryInvokeTab(MyEditorStandaloneWindowTabName);
}

 内容的注册通过FGlobalTabmanager::Get()->RegisterNomadTabSpawner

FGlobalTabmanager::Get()->RegisterNomadTabSpawner(MyEditorStandaloneWindowTabName, FOnSpawnTab::CreateRaw(this, &FMyEditorStandaloneWindowModule::OnSpawnPluginTab))
		.SetDisplayName(LOCTEXT("FMyEditorStandaloneWindowTabTitle", "MyEditorStandaloneWindow"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);

【虚幻引擎】UE4/UE5插件

他本质上就是一个SDockTab,返回的是一个TSharedRef<SDockTab>的引用,

TSharedRef<SDockTab> FMyEditorStandaloneWindowModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{
	FText WidgetText = FText::Format(
		LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"),
		FText::FromString(TEXT("FMyEditorStandaloneWindowModule::OnSpawnPluginTab")),
		FText::FromString(TEXT("MyEditorStandaloneWindow.cpp"))
		);

	return SNew(SDockTab)
		.TabRole(ETabRole::NomadTab)
		[
			// Put your tab content here!
			SNew(SBox)
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Center)
			[
				SNew(STextBlock)
				.Text(WidgetText)
			]
		];
}

五、自定义插件内容 

首先打开UI扩展点

【虚幻引擎】UE4/UE5插件

【虚幻引擎】UE4/UE5插件

这些绿色的扩展点主要是用于菜单按钮和工具按钮的排序的,添加一个绿色的扩展点统管N个菜单按钮,如果你可以自定义自己的UI扩展点,并将自己的扩展点下的菜单按钮安插在某个扩展点之后。也就是UI扩展点是用于布局菜单栏和工具栏的顺序的。

第一步:首先加载模块

//首先加载模块FExtend最后都在FLevelEditorModule中管理
	FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");

第二步:创建对象

{
		TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());
		MenuExtender->AddMenuExtension("WindowLayout", EExtensionHook::After, PluginCommands, FMenuExtensionDelegate::CreateRaw(this, &FMyEditorStandaloneWindowModule::AddMenuExtension));

		LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
	}
	{
		TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
		ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FMyEditorStandaloneWindowModule::AddToolbarExtension));

		LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);

	}

 第三步:注册绑定对象事件

FGlobalTabmanager::Get()->RegisterNomadTabSpawner(MyEditorStandaloneWindowTabName, FOnSpawnTab::CreateRaw(this, &FMyEditorStandaloneWindowModule::OnSpawnPluginTab))
		.SetDisplayName(LOCTEXT("FMyEditorStandaloneWindowTabTitle", "MyTestWindow"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);
	FGlobalTabmanager::Get()->RegisterNomadTabSpawner("MyWindow1", FOnSpawnTab::CreateRaw(this, &FMyEditorStandaloneWindowModule::SpawnCustomTab))
		.SetDisplayName(LOCTEXT("FMyEditorStandaloneWindowTabTitle", "MyWindow1"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);
	FGlobalTabmanager::Get()->RegisterNomadTabSpawner("MyWindow2", FOnSpawnTab::CreateRaw(this, &FMyEditorStandaloneWindowModule::SpawnCustomTab))
		.SetDisplayName(LOCTEXT("FMyEditorStandaloneWindowTabTitle", "MyWindow2"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);

第四步:FTabManager重新布局

const TSharedRef<SDockTab> NomadTab = SNew(SDockTab)
		.TabRole(ETabRole::NomadTab);
	if (!MyWindowTabManager.IsValid())
	{
		MyWindowTabManager = FGlobalTabmanager::Get()->NewTabManager(NomadTab);
	}
	if (!MyWindowLayout.IsValid())
	{
		MyWindowLayout = FTabManager::NewLayout("TestLayoutWindow")
			->AddArea
			(
				FTabManager::NewPrimaryArea()
				->SetOrientation(Orient_Vertical)
				->Split
				(
					FTabManager::NewStack()
					->SetSizeCoefficient(.5f)
					->AddTab("MyWindow1", ETabState::OpenedTab)
				)
				->Split
				(
					FTabManager::NewStack()
					->SetSizeCoefficient(.5f)
					->AddTab("MyWindow2", ETabState::OpenedTab)
				)
			);
		
	}
	
	TSharedRef<SWidget> TabContents = MyWindowTabManager->RestoreFrom(MyWindowLayout.ToSharedRef(), TSharedPtr<SWindow>()).ToSharedRef();
	NomadTab->SetContent(TabContents);

 效果如下:

【虚幻引擎】UE4/UE5插件

 完整代码附上:

MyEditorStandaloneWindow.h文件

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

class FToolBarBuilder;
class FMenuBuilder;

class FMyEditorStandaloneWindowModule : public IModuleInterface
{
public:

	/** IModuleInterface implementation */
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
	
	/** This function will be bound to Command (by default it will bring up plugin window) */
	void PluginButtonClicked();
	
private:

	void RegisterMenus();

	TSharedRef<class SDockTab> OnSpawnPluginTab(const class FSpawnTabArgs& SpawnTabArgs);

private:
	TSharedPtr<class FUICommandList> PluginCommands;


	void AddMenuExtension(FMenuBuilder& Builder);
	void AddToolbarExtension(FToolBarBuilder& Builder);
	TSharedRef<SDockTab> SpawnCustomTab(const FSpawnTabArgs& Arg);
	TSharedPtr<FTabManager> MyWindowTabManager;
	TSharedPtr<FTabManager::FLayout> MyWindowLayout;

};

MyEditorStandaloneWindow.cpp文件文章来源地址https://www.toymoban.com/news/detail-449427.html

// Copyright Epic Games, Inc. All Rights Reserved.

#include "MyEditorStandaloneWindow.h"
#include "MyEditorStandaloneWindowStyle.h"
#include "MyEditorStandaloneWindowCommands.h"
#include "LevelEditor.h"
#include "Widgets/Docking/SDockTab.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Text/STextBlock.h"
#include "ToolMenus.h"

static const FName MyEditorStandaloneWindowTabName("MyEditorStandaloneWindow");

#define LOCTEXT_NAMESPACE "FMyEditorStandaloneWindowModule"

void FMyEditorStandaloneWindowModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
	
	FMyEditorStandaloneWindowStyle::Initialize();
	FMyEditorStandaloneWindowStyle::ReloadTextures();

	FMyEditorStandaloneWindowCommands::Register();
	
	PluginCommands = MakeShareable(new FUICommandList);

	PluginCommands->MapAction(
		FMyEditorStandaloneWindowCommands::Get().OpenPluginWindow,
		FExecuteAction::CreateRaw(this, &FMyEditorStandaloneWindowModule::PluginButtonClicked),
		FCanExecuteAction());

	//UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FMyEditorStandaloneWindowModule::RegisterMenus));
	
	//首先加载模块FExtend最后都在FLevelEditorModule中管理
	FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
	{
		TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());
		MenuExtender->AddMenuExtension("WindowLayout", EExtensionHook::After, PluginCommands, FMenuExtensionDelegate::CreateRaw(this, &FMyEditorStandaloneWindowModule::AddMenuExtension));

		LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
	}
	{
		TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
		ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FMyEditorStandaloneWindowModule::AddToolbarExtension));

		LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);

	}
	FGlobalTabmanager::Get()->RegisterNomadTabSpawner(MyEditorStandaloneWindowTabName, FOnSpawnTab::CreateRaw(this, &FMyEditorStandaloneWindowModule::OnSpawnPluginTab))
		.SetDisplayName(LOCTEXT("FMyEditorStandaloneWindowTabTitle", "MyTestWindow"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);
	FGlobalTabmanager::Get()->RegisterNomadTabSpawner("MyWindow1", FOnSpawnTab::CreateRaw(this, &FMyEditorStandaloneWindowModule::SpawnCustomTab))
		.SetDisplayName(LOCTEXT("FMyEditorStandaloneWindowTabTitle", "MyWindow1"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);
	FGlobalTabmanager::Get()->RegisterNomadTabSpawner("MyWindow2", FOnSpawnTab::CreateRaw(this, &FMyEditorStandaloneWindowModule::SpawnCustomTab))
		.SetDisplayName(LOCTEXT("FMyEditorStandaloneWindowTabTitle", "MyWindow2"))
		.SetMenuType(ETabSpawnerMenuType::Hidden);
	
}

void FMyEditorStandaloneWindowModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.

	UToolMenus::UnRegisterStartupCallback(this);

	UToolMenus::UnregisterOwner(this);

	FMyEditorStandaloneWindowStyle::Shutdown();

	FMyEditorStandaloneWindowCommands::Unregister();

	FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(MyEditorStandaloneWindowTabName);
}

TSharedRef<SDockTab> FMyEditorStandaloneWindowModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{
	/*FText WidgetText = FText::Format(
		LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"),
		FText::FromString(TEXT("FMyEditorStandaloneWindowModule::OnSpawnPluginTab")),
		FText::FromString(TEXT("MyEditorStandaloneWindow.cpp"))
		);*/

	//return SNew(SDockTab)
	//	.TabRole(ETabRole::NomadTab)
	//	[
	//		// Put your tab content here!
	//		SNew(SBox)
	//		.HAlign(HAlign_Center)
	//		.VAlign(VAlign_Center)
	//		[
	//			SNew(STextBlock)
	//			.Text(WidgetText)
	//		]
	//	];
	const TSharedRef<SDockTab> NomadTab = SNew(SDockTab)
		.TabRole(ETabRole::NomadTab);
	if (!MyWindowTabManager.IsValid())
	{
		MyWindowTabManager = FGlobalTabmanager::Get()->NewTabManager(NomadTab);
	}
	if (!MyWindowLayout.IsValid())
	{
		MyWindowLayout = FTabManager::NewLayout("TestLayoutWindow")
			->AddArea
			(
				FTabManager::NewPrimaryArea()
				->SetOrientation(Orient_Vertical)
				->Split
				(
					FTabManager::NewStack()
					->SetSizeCoefficient(.5f)
					->AddTab("MyWindow1", ETabState::OpenedTab)
				)
				->Split
				(
					FTabManager::NewStack()
					->SetSizeCoefficient(.5f)
					->AddTab("MyWindow2", ETabState::OpenedTab)
				)
			);
		
	}
	
	TSharedRef<SWidget> TabContents = MyWindowTabManager->RestoreFrom(MyWindowLayout.ToSharedRef(), TSharedPtr<SWindow>()).ToSharedRef();
	NomadTab->SetContent(TabContents);
	return NomadTab;
}

void FMyEditorStandaloneWindowModule::AddMenuExtension(FMenuBuilder& Builder)
{
	Builder.AddMenuEntry(FMyEditorStandaloneWindowCommands::Get().OpenPluginWindow);
}

void FMyEditorStandaloneWindowModule::AddToolbarExtension(FToolBarBuilder& Builder)
{
	Builder.AddToolBarButton(FMyEditorStandaloneWindowCommands::Get().OpenPluginWindow);
}

TSharedRef<SDockTab> FMyEditorStandaloneWindowModule::SpawnCustomTab(const FSpawnTabArgs& Arg)
{

	return SNew(SDockTab);
}

void FMyEditorStandaloneWindowModule::PluginButtonClicked()
{
	FGlobalTabmanager::Get()->TryInvokeTab(MyEditorStandaloneWindowTabName);
}

void FMyEditorStandaloneWindowModule::RegisterMenus()
{
	// Owner will be used for cleanup in call to UToolMenus::UnregisterOwner
	FToolMenuOwnerScoped OwnerScoped(this);

	{
		UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window");
		{
			FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");
			Section.AddMenuEntryWithCommandList(FMyEditorStandaloneWindowCommands::Get().OpenPluginWindow, PluginCommands);
		}
	}

	{
		UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar");
		{
			FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("Settings");
			{
				FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FMyEditorStandaloneWindowCommands::Get().OpenPluginWindow));
				Entry.SetCommandList(PluginCommands);
			}
		}
	}
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FMyEditorStandaloneWindowModule, MyEditorStandaloneWindow)

到了这里,关于【虚幻引擎】UE4/UE5插件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【虚幻引擎】UE4/UE5 pak挂载

     找到:D:UEUE_4.27EngineBinariesWin64,  WindowS+R打开CMD命令 运行UnrealPak,运行结果如下      注意如果想要加载Pak内资源,那么这些资源必须是经过Cook的。如果打包的是未Cook的资源,那么即使Pak挂载成功,也不可能会成功加载Pak内资源。  Cook好之后,存储的路径在你的I:DBJ

    2024年02月10日
    浏览(75)
  • 【虚幻引擎UE】UE4/UE5 新人科普向

    Unreal Engine是当前最为流行的游戏引擎之一,具有丰富的游戏开发功能和强大的游戏引擎渲染能力。 UE5官方文档:UE5官方文档非常详细,介绍了UE5的各个功能和应用,适合入门学习和深入探究。链接:https://docs.unrealengine.com/5.1/zh-CN/ UE5中文社区:该社区聚集了大量的UE5开发者,

    2024年02月09日
    浏览(79)
  • 【虚幻引擎】UE4/UE5科大讯飞文字合成语音

    B站视频链接:https://space.bilibili.com/449549424?spm_id_from=333.1007.0.0   第一步:首先进入讯飞开放平台注册一个账号,然后创建一个 创建一个应用,命名按照你自己的想法来,会产生一个APPID,具体参考UE4如何接入科大讯飞的语音识别_ue4 科大讯飞的语音识别_飞起的猪的博客-CSDN博

    2024年02月13日
    浏览(71)
  • 【虚幻引擎】UE4/UE5鼠标点击事件实现物体移动

     在UE4/UE5中,引擎有它自己的一套框架体系,虚幻就是基于这一个框架体系来实现的。其中就有PlayerController(玩家控制器),玩家控制器中就有对鼠标的一系列设置,包括显示鼠标,允许点击事件等。  1.创建PlayerController,命名为MyPlayerController 2.打开MyPlayerController,勾选参数

    2024年02月10日
    浏览(114)
  • 【虚幻引擎】UE4/UE5数字孪生与前端Web页面匹配

            数字孪生是一种多维动态的数字映射,可大幅提高效能。数字孪生是充分利用物理模型、传感器更新、运行历史等数据,集成多学科、多物理量、多尺度、多概率的仿真过程,在虚拟空间中完成对现实体的复制和映射,从而反映物理实体的全生命周期过程。数字孪生

    2024年02月03日
    浏览(79)
  • UE4,UE5虚幻引擎,Command Console控制台命令,参数集

    1、Command Console控制台命令,虚幻官方文档 https://docs.unrealengine.com/5.0/zh-CN/unreal-editor-interface/ 2、在cmd控制台 help 并按 Enter 3、自动跳转到网页,在网页中,可以查找所有的命令行参数。

    2024年02月15日
    浏览(86)
  • 解决UE4 UE5 虚幻引擎 关卡内或sequence 播放多个视频卡顿问题

    在项目设置中搜索缓存,修改其中的参数即可解决问题,默认为1G,详细见图 经测试,单个关卡内使用蓝图或在sequence内创建媒体,播放30个mp4视频或者序列帧分辨率为1080p,可流畅播放,实时帧数40fps,使用设备(2080ti,内存64G)

    2024年02月11日
    浏览(73)
  • UE4/UE5 虚幻引擎,Pawn的碰撞,怎么防止Pawn移动的时候穿透物体。

    前言:在UE项目开发中,有些我们需要自己新建一个Pawn来控制视角,但是如果我们没有设置Pawn的碰撞,那么Pawn在移动的过程中,很容易穿到Actor里面。而有的时候我们并不需要Pawn穿过物体,就必须要给Pawn增加碰撞。 1、新建一个Pawn类。 2、 添加FloatingPawnMovement(必须添加这

    2023年04月12日
    浏览(74)
  • 【虚幻引擎UE】UE4/UE5 基于2D屏幕坐标获取场景3D坐标 射线检测(蓝图/C++)

    射线检测(Ray Casting) 是一种计算机图形和计算机图形学中的基本技术,用于检测光线或射线是否与三维场景中的物体相交,以确定相交点的位置和其他相关信息。射线检测通常用于实现各种交互功能、渲染效果和物理模拟,包括但不限于鼠标拾取、光线追踪、碰撞检测和物

    2024年02月07日
    浏览(120)
  • UE4,UE5虚幻引擎,怎么在蓝图中获取FPS帧速率,显示在UMG(UI)上

    前言:在UE中可以使用命令行比如stat fps显示帧率,但只是显示在界面,假设我们要在蓝图中获取FPS帧率,并且显示在我们创建的UMG控件蓝图。这种stat fps命令行的形式就不行了,因为它只会固定显示在右上角的位置。 1、在Tick中获取DeltaSeconds,用1除InDeltaTime,得到帧速率。

    2024年02月11日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包