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

,

Are you keeping the github updated because it appears that its not…??? Not sure if I am missing something. I built a custom base build with your source (so I don’t have to add to each project) but I had to download from the zip file. Just be easier to grab off of git. Thanks for your work!

teak

Hi… I use a custom build and it works great with’s code… I’m just building a base build with his added code and it works peachy.

teak

Load Level Instance, Load Multiple Transformed Instances of Same Level, not in Levels List! :heart:

Dear Community,

New: Please note I’ve now made a pull request for Node to the Engine! If you’d like to see in-engine make sure to comment!

The code in node was first presented by Epic staff, Marc Audy, as code used in Fortnite.

I’ve fully implemented the code as well as making it user-friendly.

In particular I’ve presented a solution for ensuring you can spawn multiple instances of the same UE4 level, by giving you an “Instance Number” that you should increment each you spawn an instance of a level.

allows me to enable you to easily create as many uniquely translated and rotated instances of a level as you want!

is ideal for Dynamic Level Generation!


**Can Include Landscapes and Other Fancy Level Features!**

In my demo I included a landscape in my level "tile."

Level Scripting / Level Blueprint

You can also include level scripting that will run uniquely per level isntance!


**C++ Code For You**

Here's my implemenation of the code Marc Audy originally presented to the Community, exactly as it is in my Victory BP Library:



```


bool UVictoryBPFunctionLibrary::VictoryLoadLevelInstance(
	UObject* WorldContextObject, 
	FString MapFolderOffOfContent, 
	FString LevelName, 
	int32 InstanceNumber,
	FVector Location, FRotator Rotation)
{
    if(!WorldContextObject) return false;
	 
	UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject);
	if(!World) return false;
	//~~~~~~~~~~~
 
	//Full Name
	FString FullName = "/Game/" + MapFolderOffOfContent + "/" + LevelName;
	  
	FName LevelFName = FName(*FullName);
    FString PackageFileName = FullName;   
	
    ULevelStreamingKismet* StreamingLevel = NewObject<ULevelStreamingKismet>((UObject*)GetTransientPackage(), ULevelStreamingKismet::StaticClass());
 
	if(!StreamingLevel)
	{
		return false;
	}
	
	//Long Package Name
	FString LongLevelPackageName = FPackageName::FilenameToLongPackageName(PackageFileName);
	
	**//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Here is where a unique name is chosen for the new level asset
	//    Ensure unique names to gain ability to have multiple instances of same level!
	//	   <3**
	
	//Create Unique Name based on BP-supplied instance value
	FString UniqueLevelPackageName = LongLevelPackageName;
	UniqueLevelPackageName += "_VictoryInstance_" + FString::FromInt(InstanceNumber);
     
    //Set!
    StreamingLevel->SetWorldAssetByPackageName(FName(*UniqueLevelPackageName));
	**//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~**
	 
    if (World->IsPlayInEditor())
    {
        FWorldContext WorldContext = GEngine->GetWorldContextFromWorldChecked(World);
        StreamingLevel->RenameForPIE(WorldContext.PIEInstance);
    }
 
    StreamingLevel->LevelColor = FColor::MakeRandomColor();
    StreamingLevel->bShouldBeLoaded = true;
    StreamingLevel->bShouldBeVisible = true;
    StreamingLevel->bShouldBlockOnLoad = false;
    StreamingLevel->bInitiallyLoaded = true;
    StreamingLevel->bInitiallyVisible = true;
 
	//Transform
    StreamingLevel->LevelTransform = FTransform(Rotation,Location);
 
    StreamingLevel->PackageNameToLoad = LevelFName;
          
    if (!FPackageName::DoesPackageExist(StreamingLevel->PackageNameToLoad.ToString(), NULL, &PackageFileName))
    {        
        return false;
    }
  
	//~~~
	
	//Actual map package to load
	StreamingLevel->PackageNameToLoad = FName(*LongLevelPackageName);
	
	//~~~
	
    // Add the new level to world.
    World->StreamingLevels.Add(StreamingLevel);
     
    return true;
 }	


```

oh man, is cool, thanks, is much appreciated !!

Any update on VictoryEdEngine for UE 4.11? I’ve read about the issues, and we need it pretty badly for its vertex snap :slight_smile:

Anyway, , you’ve an amazing work so far!

Hi , SavePixelArray node is saving colors wrong. I was easily able to reproduce by using your node in the BeginPlay event of a level. Here are some color conversions that the node writes:

Given color in [0-1] range -> Saved color in 8bit PNG file

0.0 -> 0
0.25 -> 137
0.5 -> 188
0.75 -> 255
1.0 -> 255

Engine version is 4.11 and I used latest version that you shared via mediafire.

Victory Ed Engine on 4.11

Welcome to the forums Jacopo!


Dear Community,

I've gotten multiple requests to update the VictoryEdEngine plugin, so here it is!

I"ve now updated my Vertex Snap Editor to 4.11!

The delay was because the Instance Static Mesh (ISM) portion of the editor was unable to operate after changes made to Instanced Static Mesh Component in 4.11.

I've decided to simply disable the ISM  for now.

**You can now use the vertex snapping functionality of my Victory Ed Engine plugin in 4.11!**

https://wiki.unrealengine.com/File:VictoryEdEngine.zip

Enjoy!

♥

I am mostly just using UE4 API functions for , so I am not sure what the cause of the is.

Here is the relevant portion of the source code for node:



bool UVictoryBPFunctionLibrary::Victory_SavePixels(const FString& FullFilePath,int32 Width, int32 Height, const TArray<FLinearColor>& ImagePixels, FString& ErrorString)
{
	//Create FColor version
	TArray<FColor> ColorArray;
	for(const FLinearColor& Each : ImagePixels)
	{
		ColorArray.Add(Each.ToFColor(true));
	} 
	 
	if(ColorArray.Num() != Width * Height) 
	{
		ErrorString = "Error ~ height x width is not equal to the total pixel array length!";
		return false;
	}
	  
	TArray<uint8> CompressedPNG;
	FImageUtils::CompressImageArray( 
		Width, 
		Height, 
		ColorArray, 
		CompressedPNG
	);
	    
	return FFileHelper::SaveArrayToFile(CompressedPNG, *FinalFilename);


There’s not much room here for me to make mistakes of my own, its really just API calls.

But clearly something is amiss, I tested saving as a bmp and got the same unusual results as with compressed png:

I did a test with 0.25 and got 137 as well, instead of what you’d expect, 63.75 (255 * 0.25).

I tested 0.715 and got 220 instead of 182.325

The culprit appears to be the ToFColor function:



//Create FColor version
TArray<FColor> ColorArray;
for(const FLinearColor& Each : ImagePixels)
{
	ColorArray.Add(Each.ToFColor(true)); 
	UE_LOG(LogTemp,Error,TEXT("float is %f, byte added as %d"), Each.R, ColorArray.Last().R); 
} 


yields :



LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.250000, byte added as 137
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 1.000000, byte added as 255
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.715000, byte added as 220
LogTemp:Error: float is 0.000000, byte added as 0


So the conversion you are not enjoying is being by FLinearColor::ToFColor

ToFColor has sRGB option:



/** Quantizes the linear color and returns the result as a FColor with optional sRGB conversion and quality as goal. */
FColor FLinearColor::ToFColor(const bool bSRGB) const
{


The sRGB conversion algorithm can be found in Color.cpp if you want to see it for yourself!

When I set that to false then the values you’d expect are returned:



LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.250000, byte added as 63
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 1.000000, byte added as 255
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.000000, byte added as 0
LogTemp:Error: float is 0.715000, byte added as 183
LogTemp:Error: float is 0.000000, byte added as 0


You can read about sRGB here:

I’ve now made sRGB conversion optional, and off by default :slight_smile:

The update will be in my next plugin release

:slight_smile:

VictoryEd 4.11 worked smoothly, thanks again for your work :smiley:

Hi ,
I have read on GitHub that your level instance loading solution might cause problems in cooked/packaged projects (maybe I misunderstood that comment), but you wrote it was tested.
So is there an actual conflict? And if yes, is there a to have a workaround for it in future?
I started to built on it an important part of my game system (a pseudo random world due to the lack of runtime landscape creation/deformation possibilities), so would be essential for me…
thanks.

NICE JOB ! Thanks a lot to share it!!

I just would like to know if there is any BP to execute an external file, it would save my life.

i really don’t know how to use “FPlatformProcess::CreateProc(TEXT(“C:\Users\Cero\Desktop\Test.exe”), nullptr, true, false, false, nullptr, 0, nullptr, nullptr);”

Yay it works great :slight_smile:
Another bugging question, will you be working on the shift+i similar to merge actors blueprint again? :slight_smile:
it is currently disabled with version :frowning:

How to Ensure Maps Get Packaged With Your Game

Hi there!

I responded on Git hub, with 2 solutions that are already built into UE4, as well as the fact that I rely on my Load Level instance BP node for my own game and it has worked great in packaged win32 and win64, development and shipping.

/EpicGames/UnrealEngine/pull/2320

For those without github access, if you ever find maps are not packaging with the game, you can use 1 of these 2 solutions, that are already built-in with the Engine!

Again I myself have not needed to use these 2 solutions, my maps are stored in a Maps folder and they package great even though not directly referenced as a sublevel, which is what gives my BP node its great usefulness (not having to store the sub-levels in the level list)

I have a wiki on adding non-uasset or uasset/umap files to your cooked build here:
https://wiki.unrealengine.com/How_To_Package_Extra_NonUASSET_Files_With_Your_Game

:heart:

Manually specify maps to include in packaged game

Can add an entire folder of UE4 assets if you want to!

Use “Additional Assets to Cook” for .umaps!

ooooh, that’s a great one!

Will work on it soon as I can :slight_smile:

New BP Node ~ Is Alpha Numeric

Dear Community,

BP node lets you find out if a string contains only letters and numbers!

is very useful when allowing users to pick login names and passwords!


**C++ Code For You**

My solution relies entirely on a core C++ function called isalnum.

So I am not making up my own solution, I am enabling you to call  core C++ function via a BP node, doing the necessary conversion to go from UE4 FString to c++ std::string / UTF8 char string



```


#include <string>
bool UVictoryBPLibrary::IsAlphaNumeric(const FString& String)
{
	std::string str = (TCHAR_TO_UTF8(*String));
	    
	for ( std::string::iterator it=str.begin(); it!=str.end(); ++it)
	{
		if(!isalnum(*it))
		{   
			return false;
		}
	}
	
	return true;
}


```



**New Download (50.21mb, Media Fire)**
https://www.mediafire.com/?ieovbd5l9d7yub2

Please note my downloads also include these packaged binaries:

1. Win64 Development
2. Win64 Shipping  **&lt;~~~~~~ NEW!**
3. Win32 Development
4. Win32 Shipping
4. HTML5 Development

Please see my instructions for [Packaging UE4 Plugins With Your Game](https://forums.unrealengine.com/showthread.php?3851-(39)--s-Extra-Blueprint-Nodes-for-You-as-a-Plugin-No-C-Required!&p=476476&viewfull=1#post476476).

**Donations can be sent to me via:**
http://lightningfitness.org/donate/

♥

Great news, thanks for the prompt answer!

And that wiki page is also super useful for me! But I have a question:

I need a custom level save/load system (not ready), and later want to add some modding features via text files (an advice: never start to develop RTS games :D), and you mention these additional non-uasset directories should be placed out of game project content folder, so is the best practice to make an own directory e.g. “MyOwnData” and use FPaths::ConvertRelativePathToFull(FPaths::GameDir() + “/MyOwnData/”); to access my files runtime in packaged game?
and is there an easy way to have the same work with the development version ? I think in development I should not use ConvertRelativePathToFull(), and there should exist a precompiler directive…

P.S.
with the dark skin your purple letters and really invisible :cool:

Thanks ! I’m donating some good vibes because I am a poor programmer right now. Have had a lot of usage of the plugin over the past year or so. First paycheck and I can donate some actual dollar. GL HF !

Victory Plugin For Mac!

Dear Community,

Today is a happy day!

I now offer a version of my Victory Plugin for Mac, including packaged binaries!


**New Download (50.21mb, Media Fire)**
https://www.mediafire.com/?ieovbd5l9d7yub2

Please note my downloads also include these packaged binaries:

1. Win64 Development
2. Win64 Shipping  **&lt;~~~~~~ NEW!**
3. Win32 Development
4. Win32 Shipping
4. HTML5 Development

Please see my instructions for [Packaging UE4 Plugins With Your Game](https://forums.unrealengine.com/showthread.php?3851-(39)--s-Extra-Blueprint-Nodes-for-You-as-a-Plugin-No-C-Required!&p=476476&viewfull=1#post476476).

**
Mac Editor and Packaged Game Binaries** <~~~~~~ NEW!

  1. Mac Editor Build
  2. Mac Shipping (any architecture)
  3. Mac Development (any architecture)
  4. Source code!

Victory Plugin For Mac (~14.22mb)


**Donations can be sent to me via:**
http://lightningfitness.org/donate/

♥

oooooh, I use Hacker Vision for Chrome, so I did not notice that :slight_smile:

Hey see the just higher post! tell your mac friends!

Wow Mac version now! :slight_smile:
Although I’m not a Mac user, but is great for the Mac community!
Champ cheers once again for your efforts!