Download

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

This 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:

d54f24b06c6b346968764607e3fece353c559c82.png

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 trees on that same mesh.

Rama, I love you. :slight_smile:

J^2

It lives! :slight_smile:

Source File:

Rama, 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

Rama

Wooohoo!

Awesome Zeustiak!

Thanks for sharing the pics!

Your procedural map looks wonderful!

:slight_smile:

Rama

Hi Rama!
You already know how we love your plugin, so let’s go with the requests! :wink:
A nice feature 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

This is a great question!

I will look into this 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!


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

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

Rama

ScreenShots, Move or Rename Most Recent!

3ad170c1fdb5928f5f54c13a7fa4405b1e2a8d55.jpeg

Dear Community,

New node for you!

This 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 this **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!

This 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 time.

Otherwise, if this 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 max 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!

This 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 this request, so a lot of the functions you see in this 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 Rama**
	if(!VCreateDirectory(NewAbsoluteFolderPath)) return false;
	
	FString ScreenShotsDir = VictoryPaths__ScreenShotsDir();
	
	**//Find all 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;
	}
	
	**//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Rama's Sort Files by Time Stamp Feature
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	//Sort the file names by time stamp
	//  This is my custom c++ struct to do this,
	//  	combined with my operator< and UE4's
	//			TArray::Sort() function!**
	TArray<FFileStampSort> FileSort;
	for(FString& Each : Files)
	{
		FileSort.Add(FFileStampSort(&Each,GetFileTimeStamp(Each)));
		
	}

	//Sort all the file names by their Time 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 feature of my logic and this node is that I used a custom C++ struct in order to sort all of the files by date!

**I do this in a super-efficient way, using UE4's TArray::Sort function which leverages all 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 time in the UE4 Beta program.**

So I had all 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!

Rama

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

Map Range Clamped

628def7da622ddcda32d634482b93876462ee6cf.jpeg

(Live as of April 22nd, 2015)

Dear Community,

This new node of mine, fixes an issue 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 this 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!

Rama

Hey guys,
if anyone wants it, I created a simple python script which downloads Rama’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,
Dakraid

**Rama 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 this video!

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

The UE4 Engine Pull Request for this is here:

https://github.com/EpicGames/UnrealEngine/pull/1083
(You need to be logged into your UE4 Github account to view this link)

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

:heart:

Rama

Hey Rama, the rename/move screenshot node made me think about this: Taking Screenshots | Unreal Engine Documentation
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 this let me know what you find!

:wink:

Rama

2d16db46320c67967ee1942b4e35742031880893.jpeg

**Set Volume of Any Sound Class

Any Time From Anywhere!**

You can use this node to set the volume of any sound class, any time, 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!

Rama

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

29133cff34e19b6d5f6450f26dd03f0fbc0104a7.jpeg

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

Dear Community,

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

I am referring to UE4’s Save Object system!

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

These save files are stored in GameDir/Saved/SaveGames

26bed6e9726e2f5bd0c108371726fef9d0d800a1.jpeg


**UE4 Blueprint Save System?**

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

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 object, and set the values of that object
4. Save this object to a Save Game Slot, as shown in my pictures
5. You can load a save game object from a Slot name at any time!

6.** Now with my new Victory BP Library, you can obtain a full listing of all existing save games as stored on your computer's hard disk! **This 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:

Rama

Thanks for posting this Rama.

Save Linear Color Array To Disk as PNG Image!

eb652c750e94a53fb78dc80487e1e47c03a503ce.jpeg

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!

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

Absolute File Paths

This 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 this 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 this by using variables for Width and Height** and multiplying them together and using that as the max 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 this 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 Rama
	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:

Rama

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:

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