(39) 's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

Dear Community,

New node for you!

** node will move / rename the most recently taken screenshot!**

So the intended work flow is

  1. Exec Console Command -> “HighResShot 2” or “shot showui”

  2. Possibly put in a short Delay node

  3. Use my new node! ScreenShots Move Rename Most Recent!


**More Power for You in BP**

Now you can specify an absolute path directory and also file name for the most recent screen shot, and it will be relocated for you!

So please note you can only do  **after** you create the image using UE4's console commands.

Bonus For You

You can specify a destination folder that does not exist yet and my node will create it for you!

is great for if you delete your custom screen shots folder and expect my node to work anyway!

My node will!

:slight_smile:


**High Res vs Regular Screen Shots**

You can filter for High Resolution and regular screen shots independently using my node!

So if you have High Res selected, ONLY High Resolution screenshots are considered when sorting by file.

Otherwise, if  is unchecked, I will ONLY look for regular screenshots taken with  "shot showui"

:)

Keep in Same Directory?

To keep the file in the same directory, use my new Paths node that retrieves your project’s ScreenShot directory!


**Pro Tip**

If you have a bunch of shots, you can:

1. use my node in a for loop with a break and a  count of 1000,  (or while loop if you are feeling confident)

2. Ensure that you are moving the files OUT of their current directory (otherwise for loop will run to its limit) 

3. The break condition is when my new node returns false, so just plug the false end of the branch right back into the break condition!

 will work because my node is only checking the dates of the files that are within the screenshots directory, so as you keep moving the files out, my node will keep finding the new most recent picture!

My C++ Code For You

I had to write a lot of custom File Operations code to fulfill request, so a lot of the functions you see in node are not stock UE4 code. :slight_smile:



bool UVictoryBPFunctionLibrary::ScreenShots_Rename_Move_Most_Recent(
	FString& OriginalFileName,
	FString NewName, 
	FString NewAbsoluteFolderPath, 
	bool HighResolution
){ 
	OriginalFileName = "None";

	**//File Name given?**
	if(NewName.Len() <= 0) return false;
	
	**//Normalize**
	FPaths::NormalizeDirectoryName(NewAbsoluteFolderPath);
	
	**//Ensure target directory exists, 
	//		_or can be created!_ <3 **
	if(!VCreateDirectory(NewAbsoluteFolderPath)) return false;
	
	FString ScreenShotsDir = VictoryPaths__ScreenShotsDir();
	
	**//Find  screenshots**
	TArray<FString> Files;	  //false = not recursive, not expecting subdirectories
	bool Success = GetFiles(ScreenShotsDir, Files, false);
	
	if(!Success)
	{
		return false;
	}
	
	**//Filter**
	TArray<FString> ToRemove; //16 bytes each, more stable than ptrs though since RemoveSwap is involved
	for(FString& Each : Files)
	{
		if(HighResolution)
		{
			//remove those that dont have it
			if(Each.Left(4) != "High")
			{
				ToRemove.Add(Each);
			}
		}
		else
		{ 
			//Remove those that have it!
			if(Each.Left(4) == "High")
			{
				ToRemove.Add(Each);
			}
		}
	}
	
	**//Remove!**
	for(FString& Each : ToRemove)
	{
		Files.RemoveSwap(Each); //Fast remove! Does not preserve order
	}
	
	**//No files?**
	if(Files.Num() < 1)
	{ 
		return false;
	}
	
	**//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// 's Sort Files by Stamp 
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//Sort the file names by stamp
	//   is my custom c++ struct to do ,
	//  	combined with my operator< and UE4's
	//			TArray::Sort() function!**
	TArray<FFileStampSort> FileSort;
	for(FString& Each : Files)
	{
		FileSort.Add(FFileStampSort(&Each,GetFileTimeStamp(Each)));
		
	}

	//Sort  the file names by their Stamp!
	FileSort.Sort();
	
	//Biggest value = last entry
	OriginalFileName = *FileSort.Last().FileName;
	**//~~~~~~~~~~~~~~~~~~~~~~~~~~~~**

	    
	**//Generate new Full File Path!**
	FString NewFullFilePath = NewAbsoluteFolderPath + "/" + NewName + ".bmp";
	
	**//Move File!**
	return RenameFile(NewFullFilePath, ScreenShotsDir + "/" + OriginalFileName);
}



**How It Works**

The core  of my logic and  node is that I used a custom C++ struct in order to sort  of the files by date!

**I do  in a super-efficient way, using UE4's TArray::Sort function which leverages  of Epic's hard work to create a fast sorting function!**

I defined the C++ **operator&lt;** for my custom struct so that UE4 could do the sorting for me!

**In addition I have developed my own File I/O library since my in the UE4 Beta program.**

So I had  the supporting functions I needed!

C++ Code Speed

Please note that in my internal file sorting system I do not duplicate the FString data! I refer to it via pointer, and use the FDateTime as the only data I access.

So essentially my custom C++ struct is a FDateTime wrapper for a FString ptr so that UE4 can sort the files for me like Lightning!


**Download and plug in!**

**Latest plugin download is here:**
https://wiki.unrealengine.com/File:VictoryPlugin.zip

Enjoy!

Is there a way i can use those functions in C++ as well? i’m trying to include the header file it says it doesn’t found.

Right now we have Current Floor Hit Result which gets updated every tick while walking but there is no easy way to store it for comparisons.

What about a node that stores the previous ticks floor hit result, call it “Last Floor Hit Result” or “Old Floor Hit Result”? I know in 4.8 OnWalkOffLedge does but only when you walk off a ledge and not the whole hit result. If we change movement modes it would store the last ground contact, possibly even a timestamp until we switch back to walking

How to Include Plugin Functions and Classes in Project-Level Code

I did actually expose my Victory Core BP Library yes, so you can include it in your build cs!



UCLASS()
class VICTORYBPLIBRARY_API UVictoryBPFunctionLibrary : public UBlueprintFunctionLibrary
{


The fact that I include VICTORYBPLIBRARY_API means that the symbols get exported so that you include my plugin functions and classes and compile code at the project level.

You need to include my plugin module in your build cs as a dependency in order to use include “VictoryBPLibrary.h”



PublicDependencyModuleNames.AddRange(new string] { 
	"Core", "CoreUObject", "Engine", "InputCore",
			
	"VictoryPlugin"
});


Once you do , you can then call my Victory BP Library functions wherever you include “VictoryBPLibrary.h”


**Fancy Extra **

Another neat  is that you can even have classes in your project code that extend C++ classes that I've included in the plugin such as JoyISM (instanced static mesh)!

Enjoy!

My plugin only operates in a static context, as Blueprint Libraries do, so I can’t store variables for you, you can create variables at the project-level and save off the result yourself though :slight_smile:

Great to hear from you!

:slight_smile:

Get Current Operating System

annnnd

Get Milliseconds/Seconds/Minutes/Hours Passed Since Previous Recorded!

These two nodes can be used to

  1. obtain the current local Operating System for your computer.

  2. obtain the amount of milliseconds/seconds/minutes/hours that have passed since the you recorded for the first node! You can stores as many times as you want! They are simply stored as a string!

You can use these two nodes to record down to the sub-millisecond the amount of passing between game events!

**The milliseconds portion is a float, so you can record far smaller than 1 millisecond!
**

In the attached picture I record the amount of real-world between two play sessions! :slight_smile:


**Download and plug in! (Files Size: Less Than 1 MB)**

**Latest plugin download is here:**
https://wiki.unrealengine.com/File:VictoryPlugin.zip

Enjoy!

Thanks, but when i add “VictoryPlugin” into my OldSchoolNightmare.Build.cs file, and it looks like that:


PublicDependencyModuleNames.AddRange(new string] { "Core", "CoreUObject", "Engine", "InputCore", "VictoryPlugin" });

I’m getting these erros:


Error	1	error : Exception thrown while processing dependent modules of OldSchoolNightmare	C:\OldSchoolNightmare\Intermediate\ProjectFiles\EXEC	OldSchoolNightmare
Error	2	error : Couldn't find module rules file for module 'VictoryPlugin'.	C:\OldSchoolNightmare\Intermediate\ProjectFiles\EXEC	OldSchoolNightmare
Error	3	error MSB3073: The command ""D:\Program Files\Epic Games\4.7\Engine\Build\BatchFiles\Build.bat" OldSchoolNightmareEditor Win64 Development "C:\OldSchoolNightmare\OldSchoolNightmare.uproject" -rocket" exited with code -1.	C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets	38	5	OldSchoolNightmare


Ooops, please use



VictoryBPLibrary


instead of



VictoryPlugin


Let me know how it goes!

:slight_smile:

**Get Screen Resolutions
**
Now works in packaged games!

You can use with your UMG menus!

It gathers data specific to the end user’s display adapter, including available refresh rates :slight_smile:

old but has nice in-game pic

actual!


**Download and plug in! (Files Size: Less Than 1 MB)**

**Latest plugin download is here:**
https://wiki.unrealengine.com/File:VictoryPlugin.zip

Enjoy!

Dear , I feel as if some of the plugin nodes have names that seem a bit odd, for example: “Options Menu Get Display Adapter Screen Resolutions”. I think that a more fitting name could be: “Get Supported Screen Resolutions”, or “Get Display Adapter Screen Resolutions”, I just feel as if it is a bit harder to understand when the title has unnecessary words, and also harder to search. Just thought I’d post in case you change the way you name them.

Thanks, now it compiles with the added module, but when i add the header to my cpp file (include “VictoryBPLibrary.h”), it gives me error:


Error	1	error C1083: Cannot open include file: 'VictoryBPLibrary.h': No such file or directory	C:\OldSchoolNightmare\Source\OldSchoolNightmare\BYM_Building_Base.cpp	8	1	OldSchoolNightmare


Also tried : include “VictoryBPFunctionLibrary.h” and it gave me :


Error	1	error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl FSlateFontInfo::~FSlateFontInfo(void)" (__imp_??1FSlateFontInfo@@QEAA@XZ) referenced in function "void __cdecl DestructItems<class FSlateDrawElement>(class FSlateDrawElement *,int)" (??$DestructItems@VFSlateDrawElement@@@@YAXPEAVFSlateDrawElement@@H@Z)	C:\OldSchoolNightmare\Intermediate\ProjectFiles\BYM_Building_Base.cpp.obj	OldSchoolNightmare


I agree the Options Menu part is unnecessary, but if I change the name now, it will invalidate a lot of people’s BP code who are using my plugin.

I will investigate non-destructive ways to rename, perhaps using a meta friendly name.

But you see the now, renaming is a process that requires everyone else to adjust to my decision to rename a node.

Slate Build CS Dependencies Required

Dear ,

The latter is correct:



#include "VictoryBPFunctionLibrary.h"


The problem is that your build cs needs to include the same Slate/UMG modules that I am including in the Victory BP Library plugin.

Refer to the Victory BP Library build cs to see which modules you should add:



 PublicDependencyModuleNames.AddRange(
			new string] { 
				"Core", 
				"CoreUObject", 
				"Engine", 
				"InputCore",
				
				"RHI",
				"RenderCore",
				 
				"HTTP",
				"UMG", "Slate", "SlateCore",
				
				"ImageWrapper",
				
				"PhysX", "APEX" 
			}
		);  


Try adding these to your own public dependencies (project build cs)



"UMG", "Slate", "SlateCore",


That should do it!

:slight_smile:

Thanks, now it compiles :slight_smile:

**Load Texture 2D From File!

JPG, PNG, BMP, ICO, EXR, and ICNS are Supported File Formats !**

With node you can load a Texture 2D from a file during runtime!

I output for you the width and height of the loaded image!

Now you can easily create Texture 2D’s from image files in Blueprints, during runtime!

Special Note!

Sweeney liked node!

Enjoy!

PS: Make sure to include the file extension when you use node!


**C++ Code For You**

Here is the core C++ function involved, entire source is in the download! I wrote my own Enum for the file formats.



```


UTexture2D* UVictoryBPFunctionLibrary::Victory_LoadTexture2D_FromFile(const FString& FullFilePath,EJoyImageFormats ImageFormat, bool& IsValid,int32& Width, int32& Height)
{
	IsValid = false;
	UTexture2D* LoadedT2D = NULL;
	
	IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked<IImageWrapperModule>(FName("ImageWrapper"));
	
	IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(GetJoyImageFormat(ImageFormat));
 
	//Load From File
	TArray<uint8> RawFileData;
	if (!FFileHelper::LoadFileToArray(RawFileData, * FullFilePath)) 
	{
		return NULL;
	}
	
	  
	//Create T2D!
	if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawFileData.GetData(), RawFileData.Num()))
	{ 
		const TArray<uint8>* UncompressedBGRA = NULL;
		if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA))
		{
			LoadedT2D = UTexture2D::CreateTransient(ImageWrapper->GetWidth(), ImageWrapper->GetHeight(), PF_B8G8R8A8);
			
			//Valid?
			if (!LoadedT2D) 
			{
				return NULL;
			}
			
			//Out!
			Width = ImageWrapper->GetWidth();
			Height = ImageWrapper->GetHeight();
			 
			//Copy!
			void* TextureData = LoadedT2D->PlatformData->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
			FMemory::Memcpy(TextureData, UncompressedBGRA->GetData(), UncompressedBGRA->Num());
			LoadedT2D->PlatformData->Mips[0].BulkData.Unlock();

			//Update!
			LoadedT2D->UpdateResource();
		}
	}
	 
	// Success!
	IsValid = true;
	return LoadedT2D;
}


```



Download Link (6.5mb)

UE4 Wiki, Plugin Download Page

:slight_smile:

Hi , are TMaps replicated?

Awesome . Would it be possible to add access to the pixel array via node as in your other one? Or perhaps a more generalized Texture Reference to pixel array function?

Cheers,

J^2

Fails on Android

I just converted my project to a C++ project. I can build and run the project in Visual Studio. I can build and compile the project in the editor without any issues. I can package to Win64, no problem. But as soon as I try to package to and/or launch to Android, it fails.

When it was a BP only project, I was able to build to without any issues. The only difference between project and BP only project, is that I added the Victory BP plugin. Now if I remove the plugin, I can build again.

Here’s part of the log that specifies my error. It seems that it’s missing something

Thus it cannot create an so file.

ERROR: UBT ERROR: Failed to produce item: C:\Users\Marc-Andre\Google Drive\Hangar 74\UE4\Bengal\Binaries\Android\Bengal-armv7-es2.so

Here’s the last portion of my log file.

Any reason why?

thanks

No they are not replicated automatically, replication like that would have to be orchestated by you just like for most other gameplay features. My recommendation would be to only run the logic requiring TMaps on the server-side and just pass the output/results/ to clients via custom replicated events.

:slight_smile:

Texture2D -> Pixel array is a great idea, I will have to look into it when I get the !

:slight_smile:


**Build Issues**

I have many reports of people compiling my plugin for successfully, so I am not sure why you in particular are having an.

If anyone who is routinely building for can provide any additional insight in the matter that would be great!

Do you have any other log info that seems relevant besides what I've copied above? 

 error does not give me a whole lot to work with.

Here's the first key line:



```


creating C:/Users/Marc-Andre/Google Drive/Hangar 74/UE4/Bengal/Plugins/VictoryPlugin/Binaries/Android/VictoryBPLibrary-Static-armv7-es2.a 

_


```



and then :



```


C:\Users\Marc-Andre\Google Drive\Hangar 74\UE4\Bengal\Intermediate\Build\Android\Bengal\Development/UELinkerFixups.cpp:615: error: undefined reference to 'EmptyLinkFunctionForStaticInitializationSettings()'

_ 


```



C++ Development

Please review the documentation on developing for using C++.

There’s probably a build.cs or target.cs adjustment that you need to make to the plugin to support specifically. I can’t add to the general plugin since not everyone is building for android.

Epic Docs on Building for Android
.unrealengine.com/latest/INT/Platforms/Android/Reference/index.html


**NDK Required for Plugin Builds**

In particular please note that in order to compile C++ for you need these two additinal things, beyond building for BP only.

**NDK
Enviro variable -> NDKROOT**
 

Might want to wait for 4.8

Again once 4.8 rolls around it is likely that there will be an easier workflow for plugins in packaged games and not requiring as much C++ awareness or fancy components.

These issues have probably already been resolved because no one can purchase a C++ plugin and ship it to unless Epic has already resolved issues.


**Solution From Another User**

Here's a solution mentioned by another user:



```


i had to rebuild the solution, and compile to the targets (android, ios, etc.) in shipping mode.
Now it works.
Thanks.


```



:)

Additional Input Requested

I know there are people who have gotten my plugin to work great on Android, I’d love to hear their input on matter as I’ve not been developing for in my own projects.

:slight_smile: