Download

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

Yeah, I’ve tried both 4.5 and 4.6 using the appropriate plugin, still doesn’t work… And just to be sure we’re on the same page, the plugin itself works just fine, it’s just that when I build the game and try to run the built game I get this error, have you been able to build a game with a plugin? Anything else I need doing for it to work? My project is blueprint only, maybe I need to have a code project?

My project is blueprint only, maybe I need to have a code project?

Yes you do need code based project for now, this issue of plugins not working for BP-only projects is going to be resolved soon by Epic.

This is great Saxon Rah!

If you send me the code or send me my latest plugin version with your code integrated I can add it to Victory Master Branch

:slight_smile:

Rama

Hee Hee!

Have fun with your Get My IP node!

:heart:

Rama

Rama’s Suite of Powerful UMG Nodes

Here are the 3 core BP nodes that I’ve been using to make all of my complicated interacting UMG menus, including an in-game file browser and a menu that allows you to change the materials on any skeletal mesh, while in-game!

These nodes are available to you now!


**Get All Widgets of Class**

Allows you to not have to store references everywhere to your widgets, making it easy to interact with the Player Controller and My Character blueprints :) 

Also makes it easy to remove a loading screen after a level transition, without storing refs in Game Instance class

Remove All Widgets Of Class

You can find and remove any widget any time this way, no matter where you are in BP! (here I am in the Level BP)

Rama Tip:
If you make a general superclass for all your widgets (Reparent to a blank UserWidget of your own making), you can clear your entire UI system from the viewport with a single call to RemoveAllWidgetsOfClass, supplying the class that is your super class for all your user widgets!

So lets say you have 3 user widgets that you made, make a 4th that is blank, reparent your existing 3 to your new empty 4th widget (“WidgetMaster” for example).

Now you can just call RemoveAllWidgetsOfClass on your new 4th widget, WidgetMaster, and all 3 of your existing widgets will be removed automatically from the viewport!


**Is Widget Of Class In Viewport**

Take action based on the dynamic lookup of whether a certain widget is currently visible!

No need to store refs or bools anywhere, just do a dynamic look up that is lightning fast!

♥

Rama

![9b7a621d3332fdafbe78b687447eb1c37f3f558c.jpeg|1035x750](upload://mbqdc9TTsCkJHaeTMyxg2GR6Hak.jpeg)

BP Node to Get Your Computer’s IP Address!

Dear Community,

I’ve finally succeeded at implementing a node that many have been trying to implement since the Beta!

This is a BP node that gets the IP address of your computer!

My node relies on http://api.ipify.org, a free and easy way to get your current IP address.

Because this node involves an HTTP request I can’t make it a static library node, so I instead made a VictoryPC class that contains only this functionality.

You can easily re-parent your current player controller blueprint to use my plugin VictoryPC class!

File->Reparent

and if you are not using a PC already, make sure to go to World Settings and use my VictoryPC as your player controller!

As long as my Victory BP Library is an active plugin for you, then this VictoryPC class will show up!

Download:


**Celebration!**

Yay!

Now we can all get the IP address of the local computer for use with multiplayer games or webserver activities!

Enjoy!

Rama

Pic

Here’s the setup you should create in your Blueprinted version of my VictoryPC!

2902549c08d489d31bb43f8a7049793370d4801e.jpeg


**C++ Source Code For You**

Here is the C++ source code I wrote just earlier today!



```


bool AVictoryPC::VictoryPC_GetMyIP_SendRequest()
{
	FHttpModule* Http = &FHttpModule::Get();
	
	if(!Http)
	{
		return false;
	}
	 
	if(!Http->IsHttpEnabled()) 
	{
		return false;
	} 
	//~~~~~~~~~~~~~~~~~~~
	
	FString TargetHost = "http://api.ipify.org";
	TSharedRef < IHttpRequest > Request = Http->CreateRequest(); 
	Request->SetVerb("GET");
	Request->SetURL(TargetHost);
	Request->SetHeader("User-Agent", "VictoryBPLibrary/1.0");
	Request->SetHeader("Content-Type" ,"text/html");
 
	Request->OnProcessRequestComplete().BindUObject(this, &AVictoryPC::HTTPOnResponseReceived);
	if (!Request->ProcessRequest())
	{
		return false;
	}
	  
	return true;
}
	
void AVictoryPC::HTTPOnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
	this->VictoryPC_GetMyIP_DataReceived(Response->GetContentAsString());
}
 


```



♥

Rama

Video Guide to Installing Victory Plugin

By Sahkan

Here’s a guide to installing my Victory Plugin, thanks for making it Sahkan!

Code for you!

Let me know if you want an actual copy.
(note: all of my code should be within BeginRandom and EndRandom comments for ctrl-f ability)

Also you are more than welcome to change anything you see fit. Code is 10000% free

I know it’s been a while, but here’s the info:

I’ve been running it as a dedicated server, and this issue resurfaced recently when I just tried to implement your GetAllWidgetsOfClass and RemoveAllWidgetsOfClass methods. If I have a function library with the method signature “static void testMethod(UObject* WorldContextObject);”, there is no error.

However, “static void testMethodUObject* WorldContextObject, TSubclassOf<UUserWidget> WidgetClass);” crashes on dedicated server. I’m not calling the method anywhere, just declaring it in a method header. I believe the issue is that UUserWidget does not exist in a strictly server context, so it can’t resolve what it’s a subclass of (hence trying to cast a null to a Blueprint). This would be why it compiles fine and only crashes on server runtime.

I tried adding “Client” to the UFUNCTION macro, but it gives me an error saying static functions can’t be replicated, so no luck there.

I didn’t find the log file particularly helpful (though it is full of UMG errors that might give credence to my theory that a designated server doesn’t know what a widget is), and it is extremely large, so I’ve cut out most of the middle and attached it here.

I’ll keep working on getting it working, but let me know if you need any more info from me!

EDIT: I tried adding
[FONT=Lucida Console]
virtual bool NeedsLoadForClient() const override
{
return false;
}
virtual bool NeedsLoadForServer() const override
{
return false;
}

to the Blueprint Function Library class (as suggested by this AnswerHub question) but that didn’t seem to do anything, no matter what combination of true and false I put in the return statements. After I added some debug statements to it, it didn’t seem like it was ever calling NeedsLoadForServer/Client from the BlueprintFunctionLibrary.

Wohoo!

I look forward to integrating this!

Yes please send me the code by pm :slight_smile:

Rama

**Rama’s Multiplayer Game Mode Solution

Find Player Start

Choose Player Start

Can Player Restart

These core Multiplayer functions are now fully implementable/overridable in Blueprints!**

I have found a solution for the issue of implementing FindPlayerStart, ChoosePlayerStart, and CanPlayerRestart in Blueprints!

And I’ve tested it as working!

**You can now implement core network coding of choosing player starts entirely in Blueprints!
**


**How To Use**

In my picture below I show how to use my Game Mode overrides!

1. **First make a new BP and select my VictoryGameMode class** which comes with my Victory BP Library (make sure you have the latest download https://wiki.unrealengine.com/File:VictoryPlugin.zip)

If you already have a Game Mode BP, choose File -&gt; Reparent and use my Victory Game Mode BP


2. Make sure you are using my Victory Game Mode in your **World Settings**!

3. Setup the Victory Game Mode BP the same as my picture below!

4. Celebrate! You can now implement core multiplayer logic in Blueprints!

*(right click -&gt; new tab to see larger pic)*
![VictoryGameMode.jpg|1280x960](upload://1psgB0eeaCt9i59C4zf1sNwPmLm.jpeg)

CPP Override and CPP Override Var

Please note the notation I am using, any variable that has CPPOverride Var in its name is used only with the corresponding event. This is how I enable you to implement core multiplayer coding logic in Blueprints!


**Simple Data Types**

Please note that for the function that is designed to return a boolean value, CanPlayerRestart, you must pass the boolean and also a special variable, **CPPOverride SelfReference**, this is how you tell the CPP that you are implementing the Game Mode function in BP!

Non Destructive Solution

My solution is entirely optional and if you do not implement the event in Blueprints, and your programmer does it in C++, my solution will not interfere at all with your existing code base!


**Log Message**

If you do implement my solution in BP, I am printing log information to indicate this, so you/your programmer knows you are using a BP override and any C++ code will not be run.

C++ Code

Here is my C++ code for FindPlayerStart which shows how I worked around the issue of overriding FindPlayerStart via Blueprints!

Again I’ve tested this as entirely working in PIE and commandline games!

.h



//Find Player Start
public:
	/** Use this var inside the body of CPP Override ~ Find Player Start event to override the C++ functionality! */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Victory Game Mode")
	AActor* CPPOverrideVar_FindPlayerStart;
	
	/** 
	 * Use CPPOverrideVar_FindPlayerStart inside of this event to implement FindPlayerStart in BP ! <3 Rama
	 *
	 * Return the 'best' player start for this player to start from.
	 * @param Player - is the AController for whom we are choosing a playerstart
	 * @param IncomingName - specifies the tag of a Playerstart to use
	 * @returns Actor chosen as player start (usually a PlayerStart)
	 */
	UFUNCTION(BlueprintImplementableEvent, meta=(FriendlyName = "CPP Override ~ Find Player Start"))
	virtual void CPPOverride_FindPlayerStart();

	virtual class AActor* FindPlayerStart( AController* Player, const FString& IncomingName = TEXT("") ) override;


.cpp



//Find
AActor* AVictoryGameMode::FindPlayerStart( AController* Player, const FString& IncomingName )
{
	//Clear any previous to indicate whether BP did an override
	CPPOverrideVar_FindPlayerStart = NULL;
	
	//=======================
	//BP Hook by Rama
	this->CPPOverride_FindPlayerStart();
	//=======================
	
	if(CPPOverrideVar_FindPlayerStart) //Did BP programmer set the var?
	{ 
		//Indicate that the BP override was found and is being used.
		UE_LOG(VictoryGameModeLog, Log, TEXT("

"));
		UE_LOG(VictoryGameModeLog, Log, TEXT("FindPlayerStart: CPP override found in %s and used instead of C++ implementation"), *GetName());
		UE_LOG(VictoryGameModeLog, Log, TEXT("

"));

		return CPPOverrideVar_FindPlayerStart;
	} 
	 
	//Default C++ Implementation
	return Super::FindPlayerStart(Player,IncomingName);
}



**Enjoy!**

Rama

SaxonRah’s Super Random BP Nodes For You!

Dear Community,

Community member SaxonRah has gifted us all with a whole new set of Randomization nodes!

Check out these pics!


**Latest Version of My Plugin Has The Additions**

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

C++ Code

Here is the C++ code for SaxonRah’s additions to my Victory BP Library

.h



/** Seed Rand with value passed
* @param seed - value to pass to the prng as the seed
*/
UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
static void seedRand(int32 seed);

/** Seed Rand with current time
*/
UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
static void seedRandWithTime();

/** Seed Rand with entropy
* @param seed - value to pass to the prng as the seed
*/
UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary|Random")
static void seedRandWithEntropy();

/** Random Bool - Bernoulli distribution
* @param fBias - Bias of Bernoulli distribution
* @return uniformly distributed bool based on bias parameter
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static bool RandBool_Bernoulli(float fBias);

/** Random Integer - Zero to One Uniform distribution
* @return int32 - uniform distribution from 0 to 1
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static int32 RandInt_uniDis();

/** Random Integer - MIN to MAX Uniform distribution
* @param iMin - Minimum value of uniform distribution
* @param iMax - Maximum value of uniform distribution
* @return int32 - uniform distribution from iMin to iMax parameters
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static int32 RandInt_MINMAX_uniDis(int32 iMin, int32 iMax);

/** Random Double - Zero to One Uniform distribution
* @return double - uniform distribution from 0 to 1
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static float RandFloat_uniDis();

/** Random Double - Uniform distribution based on MIN to MAX parameters
* @param iMin - Minimum value of uniform distribution
* @param iMax - Maximum value of uniform distribution
* @return double - uniform distribution from iMin to iMax parameters
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static float RandFloat_MINMAX_uniDis(float iMin, float iMax);

/** Random Bool - Bernoulli distribution - Mersenne Twister
* @param fBias - Bias of Bernoulli distribution
* @return uniformly distributed bool based on bias parameter
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static bool RandBool_Bernoulli_MT(float fBias);

/** Random Integer - Zero to One Uniform distribution - Mersenne Twister
* @return int32 - uniform distribution from 0 to 1
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static int32 RandInt_uniDis_MT();

/** Random Integer - MIN to MAX Uniform distribution - Mersenne Twister
* @param iMin - Minimum value of uniform distribution
* @param iMax - Maximum value of uniform distribution
* @return int32 - uniform distribution from iMin to iMax parameters
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static int32 RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax);

/** Random Float - Zero to One Uniform distribution -  Mersenne Twister
* @return float - uniform distribution from 0 to 1
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static float RandFloat_uniDis_MT();

/** Random Float - Uniform distribution based on MIN to MAX parameters - Mersenne Twister
* @param iMin - Minimum value of uniform distribution
* @param iMax - Maximum value of uniform distribution
* @return float - uniform distribution from iMin to iMax parameters
*/
UFUNCTION(BlueprintPure, Category = "VictoryBPLibrary|Random")
static float RandFloat_MINMAX_uniDis_MT(float iMin, float iMax);


.cpp



/**
* Contributed by: SaxonRah
* Better random numbers. Seeded with a random device. if the random device's entropy is 0; defaults to current time for seed.
* can override with seed functions;
*/
//----------------------------------------------------------------------------------------------BeginRANDOM
std::random_device rd;		
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

std::mt19937 rand_MT;
std::default_random_engine rand_DRE;

/** Construct a random device and set seed for engines dependent on entropy */
void UVictoryBPFunctionLibrary::constructRand()
{
	seed = std::chrono::system_clock::now().time_since_epoch().count();

	if (rd.entropy() == 0)
	{
		seedRand(seed);
	}else{
		seedRand(rd());
	}
}
/** Set seed for Rand */
void UVictoryBPFunctionLibrary::seedRand(int32 _seed)
{
	seed = _seed;
}

/** Set seed with time for Rand */
void UVictoryBPFunctionLibrary::seedRandWithTime()
{
	seed = std::chrono::system_clock::now().time_since_epoch().count();
}

/** Set seed with entropy for Rand */
void UVictoryBPFunctionLibrary::seedRandWithEntropy()
{
	seedRand(rd());
}

/** Random Bool - Bernoulli distribution */
bool UVictoryBPFunctionLibrary::RandBool_Bernoulli(float fBias)
{
	std::bernoulli_distribution dis(fBias);
	return dis(rand_DRE);
}

/** Random Integer - Uniform distribution */
int32 UVictoryBPFunctionLibrary::RandInt_uniDis()
{
	std::uniform_int_distribution<int32> dis(0, 1);
	return dis(rand_DRE);
}
/** Random Integer - Uniform distribution */
int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis(int32 iMin, int32 iMax)
{
	std::uniform_int_distribution<int32> dis(iMin, iMax);
	return dis(rand_DRE);
}

/** Random Float - Zero to One Uniform distribution */
float UVictoryBPFunctionLibrary::RandFloat_uniDis()
{
	std::uniform_real_distribution<float> dis(0, 1);
	return dis(rand_DRE);
}
/** Random Float - MIN to MAX Uniform distribution */
float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis(float iMin, float iMax)
{
	std::uniform_real_distribution<float> dis(iMin, iMax);
	return dis(rand_DRE);
}

/** Random Bool - Bernoulli distribution  -  Mersenne Twister */
bool UVictoryBPFunctionLibrary::RandBool_Bernoulli_MT(float fBias)
{
	std::bernoulli_distribution dis(fBias);
	return dis(rand_MT);
}

/** Random Integer - Uniform distribution  -  Mersenne Twister */
int32 UVictoryBPFunctionLibrary::RandInt_uniDis_MT()
{
	std::uniform_int_distribution<int32> dis(0, 1);
	return dis(rand_MT);
}
/** Random Integer - Uniform distribution  -  Mersenne Twister */
int32 UVictoryBPFunctionLibrary::RandInt_MINMAX_uniDis_MT(int32 iMin, int32 iMax)
{
	std::uniform_int_distribution<int32> dis(iMin, iMax);
	return dis(rand_MT);
}

/** Random Float - Zero to One Uniform distribution  -  Mersenne Twister */
float UVictoryBPFunctionLibrary::RandFloat_uniDis_MT()
{
	std::uniform_real_distribution<float> dis(0, 1);
	return dis(rand_MT);
}
/** Random Float - MIN to MAX Uniform distribution  -  Mersenne Twister */
float UVictoryBPFunctionLibrary::RandFloat_MINMAX_uniDis_MT(float iMin, float iMax)
{
	std::uniform_real_distribution<float> dis(iMin, iMax);
	return dis(rand_MT);
}


Drooling This is so awesome! Thank you SaxonRah and Rama, you guys are great!

Hee hee!

I hope you enjoy the new advanced Randomization nodes!

:slight_smile:

Rama

Victory BP Library Holiday Special

Dear Community,

For Christmas I have a special of the following new additions!

**Random Number Generator nodes by SaxonRah

3 Nodes by Kris

2 Nodes by Me**


**Saxon Rah Super Random Nodes**
https://forums.unrealengine.com/showthread.php?3851-(39)-Rama-s-Extra-Blueprint-Nodes-for-You-as-a-Plugin-No-C-Required!&p=195924&viewfull=1#post195924

Nodes by Kris

Kris has offered us an easy way to project the results of a SceneCapture or SceneCaptureComponent2D !

This is very useful for making minimaps!

C++ Code

I thought Kris’s project node was particularly neat!

Here’s the code for it!



bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureComponent2D* Target, FVector Location, FVector2D& OutPixelLocation)
{
    if ((Target == nullptr) || (Target->TextureTarget == nullptr))
    {
        return false;
    }
    
    const FTransform& Transform = Target->GetComponentToWorld();
    FMatrix ViewMatrix = Transform.ToInverseMatrixWithScale();
    FVector ViewLocation = Transform.GetTranslation();

    // swap axis st. x=z,y=x,z=y (unreal coord space) so that z is up
    ViewMatrix = ViewMatrix * FMatrix(
        FPlane(0,    0,    1,    0),
        FPlane(1,    0,    0,    0),
        FPlane(0,    1,    0,    0),
        FPlane(0,    0,    0,    1));

    const float FOV = Target->FOVAngle * (float)PI / 360.0f;

    FIntPoint CaptureSize(Target->TextureTarget->GetSurfaceWidth(), Target->TextureTarget->GetSurfaceHeight());
    
    float XAxisMultiplier;
    float YAxisMultiplier;

    if (CaptureSize.X > CaptureSize.Y)
    {
        // if the viewport is wider than it is tall
        XAxisMultiplier = 1.0f;
        YAxisMultiplier = CaptureSize.X / (float)CaptureSize.Y;
    }
    else
    {
        // if the viewport is taller than it is wide
        XAxisMultiplier = CaptureSize.Y / (float)CaptureSize.X;
        YAxisMultiplier = 1.0f;
    }

    FMatrix    ProjectionMatrix = FReversedZPerspectiveMatrix (
        FOV,
        FOV,
        XAxisMultiplier,
        YAxisMultiplier,
        GNearClippingPlane,
        GNearClippingPlane
        );

    FMatrix ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;

    FVector4 ScreenPoint = ViewProjectionMatrix.TransformFVector4(FVector4(Location,1));
    
    if (ScreenPoint.W > 0.0f)
    {
        float InvW = 1.0f / ScreenPoint.W;
        float Y = (GProjectionSignY > 0.0f) ? ScreenPoint.Y : 1.0f - ScreenPoint.Y;
        FIntRect ViewRect = FIntRect(0, 0, CaptureSize.X, CaptureSize.Y);
        OutPixelLocation = FVector2D(
            ViewRect.Min.X + (0.5f + ScreenPoint.X * 0.5f * InvW) * ViewRect.Width(),
            ViewRect.Min.Y + (0.5f - Y * 0.5f * InvW) * ViewRect.Height()
            );
        return true;
    }

    return false;
}    



**Get Player Start by Name & Server Travel**

You can use the **Server Travel** node to initiate an asynchronous loading process, which enables you to put up a transition effect! You can use UMG and my RemoveAllWidgetsOfClass node to remove the transition effect after the level change completes!

You can save a Player start name to disk using my Config Suite, and then find that player start in the new level using **GetPlayerStart!**

![GetPlayerStart.jpg|677x369](upload://tW07AIMWu5w2rS6ZpHVlUBqEJQp.jpeg)

![58e8db0bd195f663d541d47ba740f62b6fe35566.jpeg|582x440](upload://cGwUjBIqGJ7Gl1x9AhuKO74OJyC.jpeg)

Enjoy!

Rama

Hope that the Scene Capture Project functions & CreateTextureRenderTarget2D function are of use to someone.

We’ve been using CreateTextureRenderTarget2D() for our optical sights and UI related elements for quite some time. It allows us to create texture render targets on the fly and not have to worry about creating them manually in the content browser.

We use Project() for rendering attachment points for our character and items in the customisation UI.

I created a crappy quick mini-map project that uses it as an example.
I’ll see about getting it online soon.

Kris.

Very handy stuff as usual. Thanks Rama and all the contributors!

Great to hear from you as always Jacky!


I now got the picture where Kris demonstrates how his SceneCaptureComponent2D projection code works! Full details below!

These nodes are in my Victory BP Library already!

**Nodes by Kris**

Kris has offered us an easy way to project the results of a SceneCapture or SceneCaptureComponent2D !

This is very useful for making minimaps!

![Capture2DProject.jpg|1047x729](upload://z58uCuMnVJQAwPzLeYOCStkE6Lh.jpeg)

http://i.imgur.com/piZKZNe.jpg

**C++ Code**

I thought Kris's project node was particularly neat!

Here's the code for it!



```


bool UVictoryBPFunctionLibrary::CaptureComponent2D_Project(class USceneCaptureComponent2D* Target, FVector Location, FVector2D& OutPixelLocation)
{
    if ((Target == nullptr) || (Target->TextureTarget == nullptr))
    {
        return false;
    }
    
    const FTransform& Transform = Target->GetComponentToWorld();
    FMatrix ViewMatrix = Transform.ToInverseMatrixWithScale();
    FVector ViewLocation = Transform.GetTranslation();

    // swap axis st. x=z,y=x,z=y (unreal coord space) so that z is up
    ViewMatrix = ViewMatrix * FMatrix(
        FPlane(0,    0,    1,    0),
        FPlane(1,    0,    0,    0),
        FPlane(0,    1,    0,    0),
        FPlane(0,    0,    0,    1));

    const float FOV = Target->FOVAngle * (float)PI / 360.0f;

    FIntPoint CaptureSize(Target->TextureTarget->GetSurfaceWidth(), Target->TextureTarget->GetSurfaceHeight());
    
    float XAxisMultiplier;
    float YAxisMultiplier;

    if (CaptureSize.X > CaptureSize.Y)
    {
        // if the viewport is wider than it is tall
        XAxisMultiplier = 1.0f;
        YAxisMultiplier = CaptureSize.X / (float)CaptureSize.Y;
    }
    else
    {
        // if the viewport is taller than it is wide
        XAxisMultiplier = CaptureSize.Y / (float)CaptureSize.X;
        YAxisMultiplier = 1.0f;
    }

    FMatrix    ProjectionMatrix = FReversedZPerspectiveMatrix (
        FOV,
        FOV,
        XAxisMultiplier,
        YAxisMultiplier,
        GNearClippingPlane,
        GNearClippingPlane
        );

    FMatrix ViewProjectionMatrix = ViewMatrix * ProjectionMatrix;

    FVector4 ScreenPoint = ViewProjectionMatrix.TransformFVector4(FVector4(Location,1));
    
    if (ScreenPoint.W > 0.0f)
    {
        float InvW = 1.0f / ScreenPoint.W;
        float Y = (GProjectionSignY > 0.0f) ? ScreenPoint.Y : 1.0f - ScreenPoint.Y;
        FIntRect ViewRect = FIntRect(0, 0, CaptureSize.X, CaptureSize.Y);
        OutPixelLocation = FVector2D(
            ViewRect.Min.X + (0.5f + ScreenPoint.X * 0.5f * InvW) * ViewRect.Width(),
            ViewRect.Min.Y + (0.5f - Y * 0.5f * InvW) * ViewRect.Height()
            );
        return true;
    }

    return false;
}    


```

Holiday Special

See the upper 3 posts for my Victory BP Library Holiday Special!

Rama

Your “Get all widgets of class” is just AWESOME. Thank you so much :smiley: