Download

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

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:

Rama, you are an unstoppable coding machine! Thank you for continuing to kick such ***! Cheers!

J^2

Hee hee! You’re welcome!

I look forward to any pics you choose to share of the pics you generate using my new node!

Rama

Hey Rama!
I never posted in this thread before, even though I have used your plugin quite a lot! (shame on me…) So let me first take a minute to thank you for all the awesome work you have done! not only some of these nodes are useful (or even essential!) but the plugin as a whole serves as a great base plugin and C++ example.

In fact, you inspired me to make a plugin that I was planing to release with all the custom nodes I have been using in my projects over the last year but apparently I’m way too lazy to finish it :stuck_out_tongue:

I call it the “Math Plugin” :p, it includes various nodes starting from simple (missing) nodes like negate int/float, to more advanced intersection checks (to be used as collision check alternatives etc.)

3347099af001a575814d73a9d38845c3ad7ceef1.jpeg
a06214a8e79329601efa5108641912805f7b6083.jpeg

Let me know if you find any of these interesting… It would be kinda cool to have some of these added to your plugin if you think they are useful :slight_smile:

Hi there TK-Master!

Rest of community is invited to chime in as to which of your nodes they would like, I personally think that the Is Point in Box, that receives the extent and center of box, would be great! (FBox not exposed to BP yet as far as I know)

Line to Line Intersection
Line Inside Sphere (is this an intersection or whole line has to be inside sphere?)
Closest Points between Two Line Segements
Project Point onto Line
Closest Point on Sphere to Line
Closest Point on Line Segment

Set Vector Length
Increment Float
Increment Integer
IsEven
IsPowerOf2
IsMultipleOf
RoundToNearestMultiple
GridSnap

Would all be great!

I think a lot of people will love the Geometry functions and Grid Snap feature!

And the various math functions will be very helpful !

Thanks!

Rama

Been stalking the forums since day 1, but I must say now TK-Master, these would be IMMENSELY helpful. Like, helpful enough to get the ball rolling for something nice.

Also Rama, you’re a saint. :slight_smile:

If you build it, they will come.

Round to nearest multiple would be nice. I round down to the blocks location, so if you click 187, it rounds to 100. In my game, I spawn a grid of blocks, and they are 100 wide each. You can click on em and it removes them. I have to do: block location = blockWidth / 100 -> floor * 100

Hee hee!


Nice to hear from you Jamendxman3!

[FONT=Comic Sans MS]Welcome to the forums Fayle!

:slight_smile:

One of my absolute favorite sayings / movies!

:slight_smile:

Rama

Alright then :wink: I’m just going to drop the header and cpp files here, then it’s up to Rama (and the community) to decide which nodes are added :stuck_out_tongue:

I also added a bonus function to convert velocity to another speed unit, this can be used for car speedometers etc.

.h file


//By TK-Master

#pragma once

#include "Runtime/UMG/Public/UMG.h"
#include "MathFunctionLibrary.generated.h"

/* Speed Units Enum. */
UENUM()
enum ESpeedUnit
{
	/* Centimeter / second (cm/s). This is default unreal velocity unit. */
	CentimeterPerSecond,

	/* Foot / second (ft/s). */
	FootPerSecond,

	/* Meter / second (m/s). */
	MeterPerSecond,

	/* Meter / minute (m/min). */
	MeterPerMinute,

	/* Kilometer / second (km/s). */
	KilometerPerSecond,

	/* Kilometer / minute (km/min). */
	KilometerPerMinute,

	/*Kilometer / hour (km/h). */
	KilometerPerHour,

	/* Mile / hour (mph). */
	MilePerHour,

	/* Knot (kn). Nautical mile per hour. */
	Knot,

	/* Mach (speed of sound) (M) at standard atm. */
	Mach,

	/* Speed of light. */
	SpeedOfLight,

	/* Yard / second. */
	YardPerSecond
};


UCLASS()
class MATHPLUGIN_API UMathFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

public:

	//Reverses the sign (- or +) of a float.
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float NegateFloat(float A);

	//Reverses the sign (- or +) of an integer.
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 NegateInt(int32 A);

	//Reverses the sign (- or +) of a Vector2D.
	UFUNCTION(BlueprintPure, Category = "Math|Vector2D")
	static FVector2D NegateVector2D(FVector2D A);

	//Changes the size (length) of a Vector to the given size (normalized vector * size).
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector SetVectorLength(FVector A, float size);

	//Converts radians to degrees.
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector VectorRadiansToDegrees(FVector RadVector);

	//Converts degrees to radians.
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector VectorDegreesToRadians(FVector DegVector);

	/**
	* Rounds an integer to the lower multiple of the given number.
	* If Skip Self is set to True it will skip to the previous multiple if the integer rounds to itself.
	* @param Multiple - The multiple number to round to.
	* @param skipSelf - Skip to the previous multiple if the integer rounds to itself.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 RoundToLowerMultiple(int32 A, int32 Multiple = 32, bool skipSelf = false);

	/**
	* Rounds an integer to the upper multiple of the given number.
	* If Skip Self is set to True it will skip to the next multiple if the integer rounds to itself.
	* @param Multiple - The multiple number to round to.
	* @param skipSelf - Skip to the next multiple if the integer rounds to itself.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 RoundToUpperMultiple(int32 A, int32 Multiple = 32, bool skipSelf = false);

	/** Rounds an integer to the nearest multiple of the given number. */
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static int32 RoundToNearestMultiple(int32 A, int32 Multiple = 32);

	/** Returns true if the integer is a power of two number. */
	UFUNCTION(BlueprintPure, meta = (CompactNodeTitle = "PwrOf2"), Category = "Math|Integer")
	static bool isPowerOfTwo(int32 x);

	/** Returns true if the integer is a multiple of the given number. */
	UFUNCTION(BlueprintPure, Category = "Math|Integer")
	static bool isMultipleOf(int32 A, int32 Multiple);

	/** Returns true if the number is even (false if it's odd). */
	UFUNCTION(BlueprintPure, meta = (CompactNodeTitle = "isEven"), Category = "Math|Float")
	static bool isEvenNumber(float A);

	/**
	* Find closest point on a Sphere to a Line.
	* When line intersects Sphere, then closest point to LineOrigin is returned.
	* @param SphereOrigin		Origin of Sphere
	* @param SphereRadius		Radius of Sphere
	* @param LineOrigin		Origin of line
	* @param LineDir			Direction of line.
	* @return Closest point on sphere to given line.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector ClosestPointOnSphereToLine(FVector SphereOrigin, float SphereRadius, FVector LineOrigin, FVector LineDir);

	/** Find the point on line segment from LineStart to LineEnd which is closest to Point. */
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector ClosestPointOnLineSeqment(FVector Point, FVector LineStart, FVector LineEnd);

	/** Returns true if the given Point vector is within a box (defined by BoxOrigin and BoxExtent). */
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool isPointInsideBox(FVector Point, FVector BoxOrigin, FVector BoxExtent);

	/** Determines whether a line intersects a sphere. */
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool isLineInsideSphere(FVector LineStart, FVector LineDir, float LineLength, FVector SphereOrigin, float SphereRadius);

	/**
	* Swept-Box vs Box test.
	* Sweps a box defined by Extend from Start to End points and returns whether it hit a box or not plus the hit location and hit normal if successful.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool LineExtentBoxIntersection(FBox inBox, FVector Start, FVector End, FVector Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime);

	/**
	* Get the shortest distance between a point and a plane.
	* The output is signed so it holds information as to which side of the plane normal the point is.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static float SignedDistancePlanePoint(FVector planeNormal, FVector planePoint, FVector point);

	/**
	* Returns a vector point which is a projection from a point to a line (defined by the vector couple LineOrigin, LineDirection).
	* The line is infinite (in both directions).
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector ProjectPointOnLine(FVector LineOrigin, FVector LineDirection, FVector Point);

	/**
	* Performs a sphere vs box intersection test.
	* @param SphereOrigin the center of the sphere being tested against the box.
	* @param SphereRadius the size of the sphere being tested.
	* @param BoxOrigin the box origin being tested against.
	* @param BoxExtent the box extend (width, depth, height).
	* @return Whether the sphere/box intersect or not.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool SphereBoxIntersection(FVector SphereOrigin, float SphereRadius, FVector BoxOrigin, FVector BoxExtent);

	/**
	* Find closest points between 2 line segments.
	* @param	(Line1Start, Line1End)	defines the first line segment.
	* @param	(Line2Start, Line2End)	defines the second line segment.
	* @param	LinePoint1		Closest point on segment 1 to segment 2.
	* @param	LinePoint2		Closest point on segment 2 to segment 1.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static void ClosestPointsOfLineSegments(FVector Line1Start, FVector Line1End, FVector Line2Start, FVector Line2End, FVector& LinePoint1, FVector& LinePoint2);

	/**
	* Calculate the intersection point of two infinitely long lines. Returns true if lines intersect, otherwise false.
	* Note that in 3d, two lines do not intersect most of the time.
	* So if the two lines are not in the same plane, use Closest Points On Two Lines instead.
	* @param IntersectionPoint The intersection point of the lines. Returns zero if the lines do not intersect or the operation fails.
	* @param LinePoint1 Line point of the first line.
	* @param LineDir1 Line direction (normal) of the first line. Should be a normalized vector.
	* @param LinePoint2 Line point of the second line.
	* @param LineDir2 Line direction (normal) of the second line. Should be a normalized vector.
	* @return true if lines intersect, otherwise false.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool LineToLineIntersection(FVector& IntersectionPoint, FVector LinePoint1, FVector LineDir1, FVector LinePoint2, FVector LineDir2);

	/*
	* Calculate the closest points between two infinitely long lines.
	* If lines are intersecting (not parallel) it will return false! Use Line To Line Intersection instead.
	* @param closestPointLine1 The closest point of line1 to line2. Returns zero if the lines intersect.
	* @param closestPointLine2 The closest point of line2 to line1. Returns zero if the lines intersect.
	* @param linePoint1 Line point of the first line.
	* @param lineVec1 Line direction (normal) of the first line. Should be a normalized vector.
	* @param linePoint2 Line point of the second line.
	* @param lineVec2 Line direction (normal) of the second line. Should be a normalized vector.
	* @return true if lines are parallel, false otherwise.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static bool ClosestPointsOnTwoLines(FVector& closestPointLine1, FVector& closestPointLine2, FVector linePoint1, FVector lineVec1, FVector linePoint2, FVector lineVec2);

	/*
	* Returns 0 if point is on the line segment.
	* Returns 1 if point is not on the line segment and it is on the side of linePoint1.
	* Returns 2 if point is not on the line segment and it is on the side of linePoint2.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static int32 PointOnWhichSideOfLineSegment(FVector linePoint1, FVector linePoint2, FVector point);

	/*
	* Returns true if the two line segments are intersecting and not parallel.
	* If you need the intersection point, use Closest Points On Two Lines.
	*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool AreLineSegmentsCrossing(FVector pointA1, FVector pointA2, FVector pointB1, FVector pointB2);

	/*Returns true if vector point is inside a rectangle defined by the rectA/rectC/rectB/rectD corner points.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector|Intersection")
	static bool isPointInsideRectangle(FVector point, FVector rectA, FVector rectC, FVector rectB, FVector rectD);

	/*Snaps vector to nearest grid multiple.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static FVector GridSnap(FVector A, float Grid);

	/*Calculates the distance between two vectors.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static float VectorDistance(FVector VectorA, FVector VectorB);

	/*What is P% of number A?*/
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float CalculatePercentageOfNumber(float P, float A);

	/*A is what percent of B?*/
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float CalculatePercentageRatio(float A, float B);

	/*A is P% of what?*/
	UFUNCTION(BlueprintPure, Category = "Math|Float")
	static float CalculateNumberFromPercentage(float A, float P);

	/*Converts UMG layout offsets to another anchor.*/
	UFUNCTION(BlueprintPure, Category = "Math|Anchor", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject"))
	static void ConvertAnchorToAnchor(UObject* WorldContextObject, FAnchors CurrentAnchor, FMargin Offsets, FAnchors TargetAnchor, FMargin& ConvertedOffsets);

	/*Converts linear velocity vector to a more useful speed unit.*/
	UFUNCTION(BlueprintPure, Category = "Math|Vector")
	static float ConvertLinearVelocity(FVector Velocity, TEnumAsByte<enum ESpeedUnit> SpeedUnit);

	//Other misc. functions.

	/* Returns true if ColorA is equal to ColorB (A == B)*/
	UFUNCTION(BlueprintPure, meta = (FriendlyName = "Equal (Linear Color)", CompactNodeTitle = "==", Keywords = "== equal"), Category = "Math|Color")
	static bool EqualEqual_LinearColorLinearColor(FLinearColor ColorA, FLinearColor ColorB);

	/*Get the value for given console variable name.*/
	UFUNCTION(BlueprintPure, Category = "Development")
	static float GetConsoleVariableFloat(FString VariableName);

	/*Get the value for given console variable name.*/
	UFUNCTION(BlueprintPure, Category = "Development")
	static int32 GetConsoleVariableInt(FString VariableName);

	//------------------------------------------------------------
	//Physics functions! (why aren't these exposed by Epic yet?!)

	/**
	* Get the current world velocity of a point on a physics-enabled component.
	* @param Point - Point in world space.
	* @param DrawDebugInfo - Draw debug point & string.
	* @param BoneName - If a SkeletalMeshComponent, name of body to get velocity of. 'None' indicates root body.
	* @return The velocity of the point in world space.
	*/
	UFUNCTION(BlueprintCallable, Category = "Physics")
	static FVector GetVelocityAtPoint(UPrimitiveComponent* Target, FVector Point, FName BoneName = NAME_None, bool DrawDebugInfo = false);

	/*
	* Set the physx center of mass offset.
	* Note: this offsets the physx-calculated center of mass (it is not an offset from the pivot point).
	*/
	UFUNCTION(BlueprintCallable, Category = "Physics")
	static void SetCenterOfMassOffset(UPrimitiveComponent* Target, FVector Offset, FName BoneName = NAME_None);

};


.cpp file


//By TK-Master

#include "MathPluginPrivatePCH.h"
#include "StaticMeshResources.h"
#include "PhysXIncludes.h"
#include "PhysicsPublic.h"

UMathFunctionLibrary::UMathFunctionLibrary(const class FObjectInitializer& PCIP)
	: Super(PCIP)
{
}

float UMathFunctionLibrary::NegateFloat(float A)
{
	return -A;
}

int32 UMathFunctionLibrary::NegateInt(int32 A)
{
	return -A;
}

FVector2D UMathFunctionLibrary::NegateVector2D(FVector2D A)
{
	return -A;
}

FVector UMathFunctionLibrary::SetVectorLength(FVector A, float size)
{
	return A.GetSafeNormal() * size;
}

FVector UMathFunctionLibrary::VectorRadiansToDegrees(FVector RadVector)
{
	return FVector::RadiansToDegrees(RadVector);
}

FVector UMathFunctionLibrary::VectorDegreesToRadians(FVector DegVector)
{
	return FVector::DegreesToRadians(DegVector);
}

int32 UMathFunctionLibrary::RoundToLowerMultiple(int32 A, int32 Multiple, bool skipSelf)
{
	int32 result = (A / Multiple) * Multiple;
	if (skipSelf && result == A && result != 0)
	{
		return ((A-1) / Multiple) * Multiple;
	}
	return result;
}

int32 UMathFunctionLibrary::RoundToUpperMultiple(int32 A, int32 Multiple, bool skipSelf)
{
	if (skipSelf || FMath::Fmod(A, Multiple) != 0)
	{
		A = ((A + Multiple) / Multiple) * Multiple;
	}
	return A;
}

int32 UMathFunctionLibrary::RoundToNearestMultiple(int32 A, int32 Multiple)
{
	return ((A + Multiple / 2) / Multiple) * Multiple;
}

bool UMathFunctionLibrary::isPowerOfTwo(int32 x)
{
	//return x && ((x&-x) == x);
	return FMath::IsPowerOfTwo(x);
}

bool UMathFunctionLibrary::isMultipleOf(int32 A, int32 Multiple)
{
	return FMath::Fmod(A, Multiple) == 0;
}

bool UMathFunctionLibrary::isEvenNumber(float A)
{
	return FMath::Fmod(A, 2) == 0;
}

FVector UMathFunctionLibrary::ClosestPointOnSphereToLine(FVector SphereOrigin, float SphereRadius, FVector LineOrigin, FVector LineDir)
{
	static FVector OutClosestPoint;
	FMath::SphereDistToLine(SphereOrigin, SphereRadius, LineOrigin, LineDir.GetSafeNormal(), OutClosestPoint);
	return OutClosestPoint;
}

FVector UMathFunctionLibrary::ClosestPointOnLineSeqment(FVector Point, FVector LineStart, FVector LineEnd)
{
	return FMath::ClosestPointOnLine(LineStart, LineEnd, Point);
}

bool UMathFunctionLibrary::isPointInsideBox(FVector Point, FVector BoxOrigin, FVector BoxExtent)
{
	FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
	return FMath::PointBoxIntersection(Point, Box);
}

bool UMathFunctionLibrary::SphereBoxIntersection(FVector SphereOrigin, float SphereRadius, FVector BoxOrigin, FVector BoxExtent)
{
	FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
	return FMath::SphereAABBIntersection(SphereOrigin, FMath::Square(SphereRadius), Box);
}

bool UMathFunctionLibrary::isLineInsideSphere(FVector LineStart, FVector LineDir, float LineLength, FVector SphereOrigin, float SphereRadius)
{
	return FMath::LineSphereIntersection(LineStart, LineDir, LineLength, SphereOrigin, SphereRadius);
}

bool UMathFunctionLibrary::LineExtentBoxIntersection(FBox inBox, FVector Start, FVector End, FVector Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime)
{
	return FMath::LineExtentBoxIntersection(inBox, Start, End, Extent, HitLocation, HitNormal, HitTime);
}

float UMathFunctionLibrary::SignedDistancePlanePoint(FVector planeNormal, FVector planePoint, FVector point)
{
	return FVector::DotProduct(planeNormal, (point - planePoint));
}

FVector UMathFunctionLibrary::ProjectPointOnLine(FVector LineOrigin, FVector LineDirection, FVector Point)
{
	//FVector linePointToPoint = point - linePoint;
	//float t = FVector::DotProduct(linePointToPoint, lineDir);
	//return linePoint + lineDir * t;

	//FVector closestPoint;
	//OutDistance = FMath::PointDistToLine(point, lineDir, linePoint, closestPoint);
	//return closestPoint;

	FVector SafeDir = LineDirection.GetSafeNormal();
	return LineOrigin + (SafeDir * ((Point - LineOrigin) | SafeDir));
}

void UMathFunctionLibrary::ClosestPointsOfLineSegments(FVector Line1Start, FVector Line1End, FVector Line2Start, FVector Line2End, FVector& LinePoint1, FVector& LinePoint2)
{
	FMath::SegmentDistToSegmentSafe(Line1Start, Line1End, Line2Start, Line2End, LinePoint1, LinePoint2);
}

bool UMathFunctionLibrary::LineToLineIntersection(FVector& IntersectionPoint, FVector LinePoint1, FVector LineDir1, FVector LinePoint2, FVector LineDir2)
{
	//Are lines coplanar?
	if (!FVector::Coplanar(LinePoint1, LineDir1, LinePoint2, LineDir2, DELTA))
	{
		return false;
	}

	FVector LineDir3 = LinePoint2 - LinePoint1;
	FVector CrossDir1And2 = FVector::CrossProduct(LineDir1, LineDir2);
	FVector CrossDir3And2 = FVector::CrossProduct(LineDir3, LineDir2);

	float s = FVector::DotProduct(CrossDir3And2, CrossDir1And2) / CrossDir1And2.SizeSquared();

	if (s > 1.0f || s < 0.0f)
	{
		return false;
	}
	else
	{
		IntersectionPoint = LinePoint1 + (LineDir1 * s);
		return true;
	}
}

bool UMathFunctionLibrary::ClosestPointsOnTwoLines(FVector& closestPointLine1, FVector& closestPointLine2, FVector linePoint1, FVector lineVec1, FVector linePoint2, FVector lineVec2)
{
	float a = FVector::DotProduct(lineVec1, lineVec1);
	float b = FVector::DotProduct(lineVec1, lineVec2);
	float e = FVector::DotProduct(lineVec2, lineVec2);

	float d = a*e - b*b;

	//lines are not parallel
	if (d != 0.0f)
	{
		FVector r = linePoint1 - linePoint2;
		float c = FVector::DotProduct(lineVec1, r);
		float f = FVector::DotProduct(lineVec2, r);

		float s = (b*f - c*e) / d;
		float t = (a*f - c*b) / d;

		closestPointLine1 = linePoint1 + lineVec1 * s;
		closestPointLine2 = linePoint2 + lineVec2 * t;

		return true;
	}
	else
	{
		return false;
	}
}

int32 UMathFunctionLibrary::PointOnWhichSideOfLineSegment(FVector linePoint1, FVector linePoint2, FVector point)
{
	FVector lineVec = linePoint2 - linePoint1;
	FVector pointVec = point - linePoint1;

	float dot = FVector::DotProduct(pointVec, lineVec);

	//point is on side of linePoint2, compared to linePoint1
	if (dot > 0)
	{
		//point is on the line segment
		if (pointVec.Size() <= lineVec.Size())
		{
			return 0;
		}

		//point is not on the line segment and it is on the side of linePoint2
		else
		{
			return 2;
		}
	}

	//Point is not on side of linePoint2, compared to linePoint1.
	//Point is not on the line segment and it is on the side of linePoint1.
	else
	{
		return 1;
	}
}

bool UMathFunctionLibrary::AreLineSegmentsCrossing(FVector pointA1, FVector pointA2, FVector pointB1, FVector pointB2)
{
	FVector closestPointA;
	FVector closestPointB;
	int32 sideA;
	int32 sideB;

	FVector lineVecA = pointA2 - pointA1;
	FVector lineVecB = pointB2 - pointB1;

	bool valid = ClosestPointsOnTwoLines(closestPointA, closestPointB, pointA1, lineVecA.GetSafeNormal(), pointB1, lineVecB.GetSafeNormal());

	//lines are not parallel
	if (valid)
	{
		sideA = PointOnWhichSideOfLineSegment(pointA1, pointA2, closestPointA);
		sideB = PointOnWhichSideOfLineSegment(pointB1, pointB2, closestPointB);

		if ((sideA == 0) && (sideB == 0))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	//lines are parallel
	else
	{
		return false;
	}
}

bool UMathFunctionLibrary::isPointInsideRectangle(FVector point, FVector rectA, FVector rectC, FVector rectB, FVector rectD)
{
	FVector vector;
	FVector linePoint;

	//get the center of the rectangle
	vector = rectC - rectA;
	float size = -(vector.Size() / 2.0f);

	vector = vector.GetSafeNormal() * (vector.Size() + size);
	FVector middle = rectA + vector;

	FVector xVector = rectB - rectA;
	float width = xVector.Size() / 2.0f;

	FVector yVector = rectD - rectA;
	float height = yVector.Size() / 2.0f;

	linePoint = ProjectPointOnLine(middle, xVector.GetSafeNormal(), point);
	vector = linePoint - point;
	float yDistance = vector.Size();

	linePoint = ProjectPointOnLine(middle, yVector.GetSafeNormal(), point);
	vector = linePoint - point;
	float xDistance = vector.Size();

	if ((xDistance <= width) && (yDistance <= height))
	{
		return true;
	}
	else
	{
		return false;
	}
}

FVector UMathFunctionLibrary::GridSnap(FVector A, float Grid)
{
	return A.GridSnap(Grid);
}

float UMathFunctionLibrary::VectorDistance(FVector VectorA, FVector VectorB)
{
	return (VectorA - VectorB).Size();
}

float UMathFunctionLibrary::CalculatePercentageOfNumber(float P, float A)
{
	return (P / 100) * A;
}

float UMathFunctionLibrary::CalculatePercentageRatio(float A, float B)
{
	return A * 100 / B;
}

float UMathFunctionLibrary::CalculateNumberFromPercentage(float A, float P)
{
	return A / (P / 100);
}

void UMathFunctionLibrary::ConvertAnchorToAnchor(UObject* WorldContextObject, FAnchors CurrentAnchor, FMargin Offsets, FAnchors TargetAnchor, FMargin& ConvertedOffsets)
{
	if (CurrentAnchor.Minimum == TargetAnchor.Minimum && CurrentAnchor.Maximum == TargetAnchor.Maximum)
	{
		ConvertedOffsets = Offsets;
		return;
	}

	FVector2D View = FVector2D(1, 1);
	UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject);
	if (World && World->IsGameWorld())
	{
		if (UGameViewportClient* ViewportClient = World->GetGameViewport())
		{
			ViewportClient->GetViewportSize(View);
		}
	}

	FMargin ZeroAnchorOffsets = Offsets;
	//Convert to 0,0 anchor first.
	if (CurrentAnchor.Minimum != FVector2D(0, 0) || CurrentAnchor.Maximum != FVector2D(0, 0))
	{
		ZeroAnchorOffsets.Left = View.X * CurrentAnchor.Minimum.X + Offsets.Left;
		ZeroAnchorOffsets.Top = View.Y * CurrentAnchor.Minimum.Y + Offsets.Top;

		if (CurrentAnchor.Minimum.X != CurrentAnchor.Maximum.X)
		{
			ZeroAnchorOffsets.Right = View.X * CurrentAnchor.Maximum.X - (Offsets.Right + Offsets.Left);
		}
		if (CurrentAnchor.Minimum.Y != CurrentAnchor.Maximum.Y)
		{
			ZeroAnchorOffsets.Bottom = View.Y * CurrentAnchor.Maximum.Y - (Offsets.Bottom + Offsets.Top);
		}

		if (TargetAnchor.Minimum == FVector2D(0, 0) && TargetAnchor.Maximum == FVector2D(0, 0))
		{
			ConvertedOffsets = ZeroAnchorOffsets;
			return;
		}
	}

	//Convert 0,0 anchor offsets to target anchor offsets.
	ConvertedOffsets.Left = (-View.X) * TargetAnchor.Minimum.X + ZeroAnchorOffsets.Left;
	ConvertedOffsets.Top = (-View.Y) * TargetAnchor.Minimum.Y + ZeroAnchorOffsets.Top;

	ConvertedOffsets.Right = TargetAnchor.Minimum.X != TargetAnchor.Maximum.X ? View.X * TargetAnchor.Maximum.X - (ZeroAnchorOffsets.Left + ZeroAnchorOffsets.Right) : ZeroAnchorOffsets.Right;
	ConvertedOffsets.Bottom = TargetAnchor.Minimum.Y != TargetAnchor.Maximum.Y ? View.Y * TargetAnchor.Maximum.Y - (ZeroAnchorOffsets.Top + ZeroAnchorOffsets.Bottom) : ZeroAnchorOffsets.Bottom;
}

float UMathFunctionLibrary::ConvertLinearVelocity(FVector Velocity, TEnumAsByte<enum ESpeedUnit> SpeedUnit)
{
	if (Velocity.IsZero()) return 0.f;

	float unit = 0;
	switch (SpeedUnit)
	{
		case CentimeterPerSecond:
			unit = 1;
			break;
		case FootPerSecond:
			unit = 0.03280839895013;
			break;
		case MeterPerSecond:
			unit = 0.01;
			break;
		case MeterPerMinute:
			unit = 0.6;
			break;
		case KilometerPerSecond:
			unit = 0.00001;
		case KilometerPerMinute:
			unit = 0.0006;
			break;
		case KilometerPerHour:
			unit = 0.036;
			break;
		case MilePerHour:
			unit = 0.02236936292054;
			break;
		case Knot:
			unit = 0.01943844492441;
			break;
		case Mach:
			unit = 0.00002915451895044;
			break;
		case SpeedOfLight:
			unit = 3.335640951982E-11;
			break;
		case YardPerSecond:
			unit = 0.01093613298338;
			break;
		default:
			break;
	};

	return Velocity.Size() * unit;
}

bool UMathFunctionLibrary::EqualEqual_LinearColorLinearColor(FLinearColor ColorA, FLinearColor ColorB)
{
	return ColorA == ColorB;
}

float UMathFunctionLibrary::GetConsoleVariableFloat(FString VariableName)
{
	static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(*VariableName);

	if (CVar != 0)
	{
		//return CVar->GetValueOnGameThread();
		return CVar->GetValueOnAnyThread();
	}
	return 0.f;
}

int32 UMathFunctionLibrary::GetConsoleVariableInt(FString VariableName)
{
	static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(*VariableName);

	if (CVar != 0)
	{
		return CVar->GetValueOnGameThread();
	}
	return 0;
}


FVector UMathFunctionLibrary::GetVelocityAtPoint(UPrimitiveComponent* Target, FVector Point, FName BoneName, bool DrawDebugInfo)
{
	/** //Math version of this function
	FTransform Transform = Target->GetComponentTransform();
	FVector LocalLinearVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsLinearVelocity());
	FVector LocalAngularVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsAngularVelocity());
	FVector ResultPointVelocity = LocalLinearVelocity + FVector::CrossProduct(FVector::DegreesToRadians(LocalAngularVelocity), Transform.InverseTransformVectorNoScale(Point - Target->GetCenterOfMass()));
	*/

	if (!Target) return FVector::ZeroVector;

	//You can actually get it from the physx body instance instead.
	FBodyInstance* BI = Target->GetBodyInstance(BoneName);
	if (BI && BI->IsValidBodyInstance())
	{
		FVector PointVelocity = BI->GetUnrealWorldVelocityAtPoint(Point);

		UWorld* TheWorld = Target->GetWorld();
		if (DrawDebugInfo && TheWorld)
		{
			DrawDebugPoint(TheWorld, Point, 10, FColor(FLinearColor(1.0f, 0.8f, 0.0f, 1.0f)), false, -1.0f);
			DrawDebugString(TheWorld, Point, FString::SanitizeFloat(PointVelocity.Size()), NULL, FColor::White, 0.0f);
		}

		return PointVelocity;
	}
	return FVector::ZeroVector;
}

void UMathFunctionLibrary::SetCenterOfMassOffset(UPrimitiveComponent* Target, FVector Offset, FName BoneName)
{
	if (!Target) return;

	FBodyInstance* BI = Target->GetBodyInstance(BoneName);
	if (BI && BI->IsValidBodyInstance())
	{
		BI->COMNudge = Offset;
		BI->UpdateMassProperties();
	}
}


Hey,Rama!You really did a wonderful job!
How can i make a plugin?
I wrote a function library and i want to make it a plugin.Can you help me?