主要内容:
本文主要讲解简单插件的编写、将类继承至Subsystem“子系统”框架的好处、鼠标射线检测以及鼠标拖拽功能的实现。
实现步骤:
一、编写插件
1.首先新建一个空的C++项目,然后新建插件,Author是作者名,Description是描述,为什么要编写插件?因为插件方便功能的移植,只需要放在项目的Plugins(没有就自己新建一个)目录下,然后在编辑器内启用就能使用插件的功能
2.创建完插件后会多出一个文件夹,然后就在这个文件夹内新建一个继承自Subsystem框架的类,引擎已经预定义的5个让你可以由此派生的父类,自己判断继承至哪个类,运用Subsystem的好处:自动实例化、托管生命周期、可以在蓝图的各个地方调用该类的属性以及方法,关于Subsystem框架的更详细的介绍可以参考大钊在知乎编写的《InsideUE4》专栏《InsideUE4》
UEngineSubsystem
UEditorSubsystem
UGameInstanceSubsystem
UWorldSubsystem
ULocalPlayerSubsystem
3.编写代码
ImageToTexture.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "ImageToTexture.generated.h"
/**
*
*/
UCLASS()
class LOADIMAGETOTEXTURE2D_API UImageToTexture : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
//通过路径获取单张图片将之转化成Texture2D
UFUNCTION(BlueprintCallable, Category = "Image")
UTexture2D* LoadTexture2D(const FString path);
//获取指定路径下的所有图片的名称,类似于XX.JPG
UFUNCTION(BlueprintCallable, Category = "Image")
TArray<FString> GetFolderFiles(FString path);
//将指定路径下的所有图片转化成Texture2D
UFUNCTION(BlueprintCallable, Category = "Image")
TArray<UTexture2D*> GetAllImageFromFiles(FString Paths);
//判断图片类型
TSharedPtr<class IImageWrapper> GetImageWrapperByExtention(const FString Path);
};
ImageToTexture.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "ImageToTexture.h"
#include "IImageWrapper.h"
#include "IImageWrapperModule.h"
#include "Core\Public\HAL\FileManagerGeneric.h"
UTexture2D* UImageToTexture::LoadTexture2D(const FString path)
{
UTexture2D* Texture = nullptr;
if (!FPlatformFileManager::Get().GetPlatformFile().FileExists(*path))
{
return nullptr;
}
TArray<uint8> RawFileData;
if (!FFileHelper::LoadFileToArray(RawFileData, *path))
{
return nullptr;
}
TSharedPtr<IImageWrapper> ImageWrapper = GetImageWrapperByExtention(path);
if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
{
TArray<uint8> UncompressedRGBA;
if (ImageWrapper->GetRaw(ERGBFormat::RGBA, 8, UncompressedRGBA))
{
Texture = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_R8G8B8A8);
if (Texture != nullptr)
{
void* TextureData = Texture->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
FMemory::Memcpy(TextureData, UncompressedRGBA.GetData(), UncompressedRGBA.Num());
Texture->PlatformData->Mips[0].BulkData.Unlock();
Texture->UpdateResource();
}
}
}
return Texture;
}
TArray<FString> UImageToTexture::GetFolderFiles(FString path)
{
TArray<FString> files;
FPaths::NormalizeDirectoryName(path);
IFileManager& FileManager = IFileManager::Get();
FString FinalPath = path / TEXT("*");
FileManager.FindFiles(files, *FinalPath, true, true);
return files;
}
TArray<UTexture2D*> UImageToTexture::GetAllImageFromFiles(FString Paths)
{
TArray<FString> ImgPaths = GetFolderFiles(Paths);
TArray<UTexture2D*> Texture2DArr;
for (auto path : ImgPaths)
{
UTexture2D* Texture2D = LoadTexture2D(Paths + "/" + path);
Texture2DArr.Add(Texture2D);
}
return Texture2DArr;
}
//只写了png和jpg格式的图片读取,如果有其他格式的需求,请自行添加
TSharedPtr<class IImageWrapper> UImageToTexture::GetImageWrapperByExtention(const FString Path)
{
IImageWrapperModule& module = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
if (Path.EndsWith(".png"))
{
return module.CreateImageWrapper(EImageFormat::PNG);
}
if (Path.EndsWith(".jpg"))
{
return module.CreateImageWrapper(EImageFormat::JPEG);
}
return nullptr;
}
二、制作UI和蓝图
1.新建Actor蓝图WBP_Static用来充当画板的角色,添加一个Plane(Static Mesh Component),创建动态材质实例,新建材质Mat_UE赋给Plane,最后将WBP_Static放在关卡内
Mat_UE
2.创建WBP_Image,用来显示单张图片
3.重写三个函数,都可以从左边Functions点击+号,在Override里找到
重写On Mouse Button Down函数,用来检测按键是否按下
重写On Drag Detected鼠标拖拽函数
重写On Drag Cancelled函数,用来执行鼠标拖拽取消后的逻辑
4.创建WBP_Main,用来展现所有的图片
找到项目文件夹新建一个存放图片的文件夹(Image)用来测试
5.在关卡蓝图里创建WBP—Main
三、最终效果及项目下载地址(4.25)
链接:https://pan.baidu.com/s/1mwDDgOCzTfDdfxFEnN-VkA?pwd=i71w
提取码:i71w