IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> ue4 制作导出Content目录下某个文件夹内所有模型的六视图并将模型资源文件复制到指定文件夹的插件 -> 正文阅读

[游戏开发]ue4 制作导出Content目录下某个文件夹内所有模型的六视图并将模型资源文件复制到指定文件夹的插件

一、新建空白插件

在Bulid.cs内加入两个模块,"EditorSubsystem","UnrealEd",

PublicDependencyModuleNames.AddRange(
			new string[]
			{
				"Core",
                "EditorSubsystem",
                "UnrealEd",
				// ... add other public dependencies that you statically link with here ...
			}
			);

创建继承于EditorSubsystenm的子类

?

点创建后会报错,没关系回C++重新编译一下就好

二、C++代码

ExportSixViewsSub.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "EditorSubsystem.h"
#include "ExportSixViewsSub.generated.h"
class USpringArmComponent;

/**
 *
 */

UCLASS()
class EXPORTSIXVIEWS_API UExportSixViewsSub : public UEditorSubsystem
{
	GENERATED_BODY()

public:
	//获取World
	UFUNCTION(BlueprintPure, Category = "FunTool")
		UWorld* GetContextWorld();

	//遍历指定路径下所有的StaticMesh
	UFUNCTION(BlueprintCallable, Category = "FunTool")
		TArray<UStaticMesh*> FindOrLoadAssetsByPath(const FString& FilePath);

	//将Actor的Privot设置为Center
	UFUNCTION(BlueprintCallable, Category = "FunTool")
		bool SetActorPrivotOnCenter(AActor* InActor, bool bWorldSpace /*= false*/, FVector& CenterLocation);

	//拍摄模型六视图并保存到指定文件夹
	UFUNCTION(BlueprintCallable, Category = "FunTool")
		bool SaveRenderTargetToFile(UTextureRenderTarget2D* rt, const FString& Filepath);

	//复制指定文件到指定目录
	UFUNCTION(BlueprintCallable, Category = "FunTool")
		void CopyFile(UStaticMesh* SM, const FString& Filepath);

	//导出完成时的消息提示框
	UFUNCTION(BlueprintCallable, Category = "FunTool")
		void Tips();

	//打开文件管理器并返回选择的文件的目录
	UFUNCTION(BlueprintCallable, Category = "FunTool")
		void OpenFiles(FString& DirectoryName);
};
ExportSixViewsSub.cpp
// Fill out your copyright notice in the Description page of Project Settings.


#include "ExportSixViewsSub.h"
#include "EngineUtils.h"
#include "UnrealEdGlobals.h"
#include "Editor/UnrealEdEngine.h"
#include "Engine/TextureRenderTarget2D.h"
#include "Misc/FileHelper.h"
#include "ImageUtils.h"
#include "GameFramework/SpringArmComponent.h"
#include "Kismet/KismetSystemLibrary.h"

#include "Developer/DesktopPlatform/Public/IDesktopPlatform.h"
#include "Developer/DesktopPlatform/Public/DesktopPlatformModule.h"


UWorld* UExportSixViewsSub::GetContextWorld()
{
	UWorld* World = GEditor->GetEditorWorldContext().World();
	return World;
}

TArray<UStaticMesh*> UExportSixViewsSub::FindOrLoadAssetsByPath(const FString& FilePath)
{
	TArray<UObject*> OutAssets;
	TArray<UStaticMesh*> OutStaticMeshs;
	FString GamePath = FilePath;
	GamePath.ReplaceInline(*FPaths::ProjectContentDir(), TEXT("/Game/"));
	if (!GamePath.IsEmpty())
	{
		EngineUtils::FindOrLoadAssetsByPath(GamePath, OutAssets, EngineUtils::ATL_Regular);
		for (auto SM : OutAssets)
		{
			UStaticMesh* TempSM = Cast<UStaticMesh>(SM);
			if (TempSM)
			{
				OutStaticMeshs.Add(TempSM);
			}
		}
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory Exists"));
		return OutStaticMeshs;
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory Does not exist"));
		return OutStaticMeshs;
	}
}

bool UExportSixViewsSub::SetActorPrivotOnCenter(AActor* InActor, bool bWorldSpace /*= false*/, FVector& CenterLocation)
{
	if (InActor)
	{
		FVector PivotOffset = InActor->GetComponentsBoundingBox().GetCenter();
		if (bWorldSpace)
		{
			FVector Delta(PivotOffset - InActor->GetActorLocation());
			PivotOffset = InActor->GetTransform().InverseTransformVector(Delta);
		}

		if (InActor->GetPivotOffset() == PivotOffset)
		{
			CenterLocation = InActor->GetActorLocation();
			return false;
		}
		else
		{
			InActor->Modify();
			InActor->SetPivotOffset(PivotOffset);
			GUnrealEd->SetPivotMovedIndependently(false);
			InActor->PostEditMove(/*bFinished=*/ true);
			CenterLocation = InActor->GetActorLocation() + PivotOffset;
			return true;
		}
	}

	return false;
}

bool UExportSixViewsSub::SaveRenderTargetToFile(UTextureRenderTarget2D* rt, const FString& fileDestination)
{

	FTextureRenderTargetResource* rtResource = rt->GameThread_GetRenderTargetResource();
	FReadSurfaceDataFlags readPixelFlags(RCM_UNorm);
	TArray<FColor> outBMP;

	for (FColor& color : outBMP)
	{
		color.A = 255;
	}
	outBMP.AddUninitialized(rt->GetSurfaceWidth() * rt->GetSurfaceHeight());
	rtResource->ReadPixels(outBMP, readPixelFlags);

	FIntPoint destSize(rt->GetSurfaceWidth(), rt->GetSurfaceHeight());
	TArray<uint8> CompressedBitmap;
	FImageUtils::CompressImageArray(destSize.X, destSize.Y, outBMP, CompressedBitmap);
	bool imageSavedOk = FFileHelper::SaveArrayToFile(CompressedBitmap, *fileDestination);

	return imageSavedOk;
}

void UExportSixViewsSub::CopyFile(UStaticMesh* SM, const FString& FilePath)
{
	FString SM_AbsolutePath = UKismetSystemLibrary::GetSystemPath(SM);

	FString FileDestination = FilePath;
	FileDestination.Append("/" + SM->GetFName().ToString() + ".uasset");

	IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
	if (FileManager.CreateDirectory(*FilePath))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory was created"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: Directory was not created"));
	}

	if (FileManager.CopyFile(*FileDestination, *SM_AbsolutePath))
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: File Copied!"));
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("FilePaths: File not Copied!"));
	}
}

void UExportSixViewsSub::Tips()
{
	FText const Title = FText::FromString("Message");
	FText const DialogText = FText::FromString("Export complete!");
	EAppReturnType::Type const ReturnType = FMessageDialog::Open(EAppMsgType::Ok, DialogText, &Title);
}

void UExportSixViewsSub::OpenFiles(FString& DirectoryName)
{
	IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
	DesktopPlatform->OpenDirectoryDialog(nullptr, TEXT("ProjectDir"), FPaths::ConvertRelativePathToFull(FPaths::ProjectDir()), DirectoryName);
}

?三、蓝图代码

?

1.新建Actor蓝图,就只添加一个StaticMeshComponent用于测试用

?2.新建相机蓝图,添加一个相机臂和SceneCaptureComponent2D,相机臂取消碰撞,设置CaptureSource默认值

?3.新建结构体和创建表格

?4.新建编辑器UI

设计界面:

?逻辑界面:

自定义事件:拷贝模型资源文件到指定文件夹

自定义事件:将图片保存到指定文件夹

销毁Actor的函数

?Button Pressed事件 选择文件夹

?Button Pressed事件 导出图片

?四、测试

?

?五、插件下载(4.27)

链接:https://pan.baidu.com/s/1q7uYrQ41xaY1mIR0ZuQGmA?pwd=rx5y?
提取码:rx5y

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-05-15 11:43:54  更:2022-05-15 11:44:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:50:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码