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

is cool! First one to make a heightfield voxel landscape which is then turned into a highly efficient instanced mesh wins!

Quick proof of concept shows the plugin doing exactly what I need. I made a small 8x8 grid:

I made a blueprint that loads the image and trolls through the pixel array. Wherever it finds a black pixel, I spawn a tree instance:

Simplicity itself. I now have precise control over the placement of objects in my scenes in a way that I can easily control through visual means. And I’m sure that’s just the start. Now, I will be able to use the same heightfield I use to make a hill or mountain tile mesh for Z’s map gen to control the placement of on that same mesh.

, I love you. :slight_smile:

J^2

It lives! :slight_smile:


Source File:


, I had to plug the Width from the Load Texture node to the Get Pixel node to get it to work(maybe something unique to my setup), but other than that great stuff!

I have only added in land/water data using an image. I could do the same thing for with topology, precipitation, etc. Nice to see that my weather system put deserts and jungles on the earth map where they belong though! :slight_smile:

You’re welcome YarnBallSoftware!

Woohooo! That’s awesome J^2 !!

Thanks for sharing the pic!

Glad you like my new BP node!

For others, its my Load Image And Get Pixels Combo!

Load Image w/ Pixels, and Get Pixel from Index

Wooohoo!

Awesome !

Thanks for sharing the pics!

Your procedural map looks wonderful!

:slight_smile:

Hi !
You already know how we love your plugin, so let’s go with the requests! :wink:
A nice would be the ability to rename the filenames of screenshots (f.i. taken with the console command “HighResShot”) - and change the default destination folder as well, using string parameters for both.
Is it hard / impossibile / sci-fi? ;D

is a great question!

I will look into after I make a node that takes in a pixel array and converts it to various image types! (my next node plan)

But your request is great! Writing it down!

EDIT

I mapped out exactly how I’m gonna do it, will do it on my next work-break!


**'s Newest BP Node ~ Load Image And Get Pixel Data**

** node lets you load  the pixel data from a image file at runtime!**
https://forums.unrealengine.com/showthread.php?3851-(39)--s-Extra-Blueprint-Nodes-for-You-as-a-Plugin-No-C-Required!&p=273611&viewfull=1#post273611

ScreenShots, Move or Rename Most Recent!

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!

, you are beyond awesome! :smiley:
We will never thank you enough for ! =)

Map Range Clamped

(Live as of April 22nd, 2015)

Dear Community,

new node of mine, fixes an with Map Range where the output value is not clamped to the output range.

So if you use the current node, Map Range like so:



Input:  0 to 100
Output: 0 to 1
Value:  200


Then Map Range will give you 2

My node, Map Range Clamped, will give you the maximum of the output range if the value is in excess, and will still correctly return 1, the maximum output value that you supplied.

So basically if you say “I want to get back a value between 0 and 1” then my node guarantees that is exactly what will happen!


**UMG Sliders**

A very important use of  node is with UMG Sliders!

If you supply &gt; 1, a UMG slider thumb will simply disappear!

My  Map Range Clamped node will enable you to more easily and intuitively work with UMG sliders and do range mappings.

Range Mapping?

Every UMG slider goes from a value of 0 to 1, however the value you want to get from the slider might be -50 to 50, or 0 to 100, or -1 to 12.5.

**Using my Map Range Clamped node you can easily map to/from the UMG slider range of 0 to 1 (normalized range).
**


**Download and plug in!**

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

Enjoy!

Hey guys,
if anyone wants it, I created a simple python script which downloads 's plugin and unzips it into your plugin directory, it doesn’t check which version you downloaded as I don’t know how to get the file version from the wiki. If anyone knows how please tell me, I will add it to the script. I just created it because I’m really lazy…:smiley:
Link

Greetings,

** Red Hot News Flash

I turned my 14 Config BP Node Suite into 2 Wild Card Nodes!**

Dear Community,

After delving deep into the engine code, and learning a lot about the special K2 nodes that require special classes and special code, I’ve learned how to use wild cards!

I’ve compacted the 14 nodes of my Config BP Suite into just 2 !

My 2 nodes support 7 different variable types!

Check out video!

The single pin in my 2 nodes can become 7 different variable types!

=xwGMNNJFaz8

The UE4 Engine Pull Request for is here:

/EpicGames/UnrealEngine/pull/1083
(You need to be logged into your UE4 Github account to view link)

If you’d like to see these 2 Wild nodes added to the engine you can post at the link above!

:heart:

Hey , the rename/move screenshot node made me think about : .unrealengine.com/latest/INT/Engine/Basics/Screenshots/index.html#highresolutionscreenshottool
Do you think there’s a way to access that through BP? :wink:
Would be great to get access to buffers, masks and EXR’s within BP! :smiley:

If you do any preliminary research on let me know what you find!

:wink:

**Set Volume of Any Sound Class

Any From Anywhere!**

You can use node to set the volume of any sound class, any, from anywhere!

**My node allows you to offer people an audio slider that is a continuous float value range based only on the slider increments.
**
Enjoy!


![59b3e199554c243882d759c4b789ea97621f9174.jpeg|895x586](upload://cNxT611A11WIYdufbD2vlCwmasQ.jpeg)

And you get get current sound volume of any class very easily too!



**Wiki Download Page**
https://wiki.unrealengine.com/File:VictoryPlugin.zip

Get a Hard-drive accurate listing of Save Game Objects!

Dear Community,

node gives you a hard-drive accurate listing of save game files that you’ve created!

I am referring to UE4’s Save system!

You can now access a full listing in a developer build or in a packaged game, to know the save files that have been saved!

These save files are stored in GameDir/Saved/SaveGames


**UE4 Blueprint Save System?**

If you did not know, you can use UE4's save system like :

1. Create a new blueprint based on SaveGame
2. Add your variables to the blueprint that you want to save the values of
3. in level BP or some other blueprint, create a save game , and set the values of that 
4. Save   to a Save Game Slot, as shown in my pictures
5. You can load a save game  from a Slot name at any!

6.** Now with my new Victory BP Library, you can obtain a full listing of  existing save games as stored on your computer's hard disk! ** let's you know whether a file exists before you try to load it! You can also find out how many save files exist from within BP!

Most Recent Plugin Download From UE4 Wiki

Enjoy!

:slight_smile:

Thanks for posting .

Save Linear Color Array To Disk as PNG Image!

Live as of 4/27/15

Dear Community,

I’ve created a new node that allows you to save a Linear Color array to disk as a PNG image!

So you can draw transparency using the Alpha channel of the Linear Color!

For those who have not used Linear Color much, it has 4 floats (R G B A) and so saving to PNG and supporting transparency is easy!


**Bonus ~ I create target directory for you!**

My node will create the directory you are trying to save to if it does not already exist!

 can be very helpful if you delete your whole generated image folder at once!

Absolute File Paths

node receives absolute file paths, you can use my Path nodes to get various absolute paths that are relative to your project directory!

Victory BP Library Path Nodes (link inside thread)


**Error String**

I provide you with an Error string to help narrow down the reason the node returned false, if it does! 

Even more debugging info for you!

**The most common error will be that your array size does not equal Width x Height** that you inputted into the node.

Solution:

**You can avoid  by using variables for Width and Height** and multiplying them together and using that as the  for the for loop where you initialize the image to black (see picture above)!

If you use my method, make sure the for loop first index is 1 not 0 !

Post Your BP-Generated Images!

Feel free to post images you create using node!


**My C++ Code For You!**

Here's the entire C++ code for my node! 

If you use it please credit me somewhere appropriate!



```


bool UVictoryBPFunctionLibrary::Victory_SavePixels(const FString& FullFilePath,int32 Width, int32 Height, const TArray<FLinearColor>& ImagePixels, FString& ErrorString)
{
	if(FullFilePath.Len() < 1) 
	{
		ErrorString = "No file path";
		return false;
	}
	//~~~~~~~~~~~~~~~~~
	
	//Ensure target directory exists, 
	//		_or can be created!_ <3 
	FString NewAbsoluteFolderPath = FPaths::GetPath(FullFilePath);
	FPaths::NormalizeDirectoryName(NewAbsoluteFolderPath);
	if(!VCreateDirectory(NewAbsoluteFolderPath)) 
	{
		ErrorString = "Folder could not be created, check read/write permissions~ " + NewAbsoluteFolderPath;
		return false;
	}
	
	//Create FColor version
	TArray<FColor> ColorArray;
	for(const FLinearColor& Each : ImagePixels)
	{
		ColorArray.Add(Each);
	}
	 
	if(ColorArray.Num() != Width * Height) 
	{
		ErrorString = "Error ~ height x width is not equal to the total pixel array length!";
		return false;
	}
	  
	//Remove any supplied file extension and/or add accurate one
	FString FinalFilename = FPaths::GetBaseFilename(FullFilePath, false) + ".png";  //false = dont remove path

	//~~~
	
	TArray<uint8> CompressedPNG;
	FImageUtils::CompressImageArray( 
		Width, 
		Height, 
		ColorArray, 
		CompressedPNG
	);
	    
	ErrorString = "Success! or if returning false, the saving of file to disk did not succeed for File IO reasons";
	return FFileHelper::SaveArrayToFile(CompressedPNG, *FinalFilename);
}


```


Most Recent Plugin Download From UE4 Wiki

:slight_smile:

Interesting. I feel like I could do quite a few things with that node, though Minimap is the most applicable thing that comes to mind.

Not sure when I might put it to use, but if I do I will post the results here. :slight_smile:

, you stud. I hope to show what I’m doing with it soon. :smiley: