Download

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

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?

Yes Rama, that is also a question I had. If I make a bunch of macros for math nodes, could I turn those into a plugin? Do I need C++ knowledge?

Also, maybe you could make a tutorial on how to do this? Maybe just something simple like how to make a node in c++ that adds A & B. Hope you consider it, thanks!

I wrote up a plugin that is a template for BP libraries a while ago! Here’s the wiki link!

You can download that and use that to get started!

Rama’s Plugin Template

:slight_smile:

Yes you do need to use C++ :slight_smile: See my Link!

Rama’s Plugin Template

:slight_smile:

Rama

30+ New Math, Physics, and 3D Geometry Nodes!

Live as of May 1st, 2015

Dear Community,

I have the May Celebration node release for you today!

Community member TK-Master has gifted us with over 30 new BP nodes for Math, Physics, and 3D Geometry calculations!

I highlighted my personal favorite nodes in green!


**UMG Anchor Conversion**
Please note you can now convert UMG Anchor coordinates to other coordinate spaces!

Snap To 3D Grid
You can use the Snap Node to snap any 3D space Vector to a grid size of your choosing!

So you could use this node to to regulate the position of an in-game 3D positioning tool (like for RTS Games!) to a grid of your choosing, while still accounting for rolling hills of landscapes and big vertical differences!


**Convert Physics Linear Velocity**

Ever wonder how fast in **Km/hr** an in-game Unreal Engine physics ball was hurling through the air?

Ever want to know the **meters/second** speed of a falling physics-simulating box?

Or how about the **miles/hour** of your UE4 Physics Vehicle?

Well thanks to TK-Master's new node you can now easily convert the value that you get from GetPhysicsLinearVelocity of any physics-simulating body to a speed in the units of your choosing!

Here's is TK-Master's current list of available conversions!



```


/* 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
};


```



BP Nodes for 3D Geometric Analysis!

Here are pics showing the complete list of the new 3D Geometry Nodes!

To see the full list, get the latest version of my plugin and type in “TK” and you will see all the 30+ new nodes available to you!

3347099af001a575814d73a9d38845c3ad7ceef1.jpeg


**Thank You!**

**Thank you TK-Master for your contribution!**

These nodes are going to be extremely useful for a lot of people !

Most Recent Plugin Download From UE4 Wiki

:slight_smile:

Rama

Oh man, this is a good one. Thanks so much for sharing this!

Veneration for holy Rama! :smiley:
Thanks bunches you two!

Rama, I tried using the VictoryAI plugin template, I placed it in my UE4 Project’s plugins folder, and it tells me that it can’t compile, and that I need to compile from source manually. I have the launcher version of the engine, not GitHub. What am I doing wrong? And how do I recompile plugin once I’ve made my stuff?

Hee hee! You’re welcome!

I’ve thoroughly both of your (very first two!) posts Fayle, great to hear form you!

Compiling Plugins

Hi there!

Yes you definitely need to compile my template yourself, because you also cannot add code to it unless you compile it yourself!

You need Visual Studio Express 2013 for Desktop.

Make sure to get the “Community” edition or the one that says “For Windows Desktop”

Install that, and then you can use VS to compile.

The only alternative to a C++ plugin would be to make a BP Library asset that you share with people.

Enjoy!

:slight_smile:

Rama

30+ New Nodes!
PS: I recently released 30+ new nodes for Math, 3D Geometric Analysis, and Physics!

Hello Rama, I am working on a temperature system, it basically is for games where you want the user to see the temperature where player is at, or anywhere for that matter. You will be able to add heat sources, cold sources, and the temperature will radiate in the game. It will be fully customize-able with room temperature, temperature source influence, temperature flicker, and lots more when I’m done. It is really all just a back-end thing that nobody sees, but if people want, they could have the player take damage if where they are is too hot, and other things. If this works out, I will also make a moisture system as well. I will be making a node to initialize temperatures, node to add temperature source, remove temp source, and all of that. Is this something that you’d like in the Victory Plugin? If so, how would I get that stuff to you if I made it using your plugin template?

I reinstalled my Visual Studio 2013, with the VS 2013 Ultimate for desktop, but how do I compile VictoryAI manually?

Hi there!

So step 1 is to turn your project into a project that has source code: (or see my note below!)

  1. Create a new empty actor class in the editor via File->add code to project
  2. Now you can close the editor and navigate to the folder containing your .uproject.
  3. make sure you are storing my plugin template inside a folder called “Plugins” that is in this same directory as your .uproject
  4. if you dont see a .sln file you can right click on your .uproject and select Generate VS Files
  5. open the .sln that is created and build your project! (“build” from top menu bar)

Because your project is now setup to have source code, the Unreal Build Tool (UBT) will detect the plugin template and compile it along with the source code for your project.

Now you can proceed with modifying my plugin template, and then just keep recompiling your main project .sln file!

Please note, you can use any project to do this process, so you could even create a new C++ project that is really just to compile the plugin, and then use the plugin with your BP-only project.

:slight_smile:

Rama

Can you please make the next node to be a node that enable you to use external audio files like you did with the texture node ?

Sounds cool but I can think a few possible problems, such as UE4 only supports .wav.

What would be the use case though? curious :stuck_out_tongue:

Well, if users could place their own texture packs, why not matching sounds as well?

I Want to give the user the ability to replace audio files for certain actions, like a shooting sound for example.
So the user can replace fire.wav with an other fire.wav and the game will play the current file.

Hey Rama,

thanks a lot for this great plugin!
Could the “Victory Save Pixels” node be extended in a way that it outputs a new Texture2d without saving the file to disk first?

edit: actually, get the pixels of a Texture2d, manipulate, and create a new Texture2d :slight_smile:

Load .Wav From File and play it!

Dear Sahkan,

I already have these nodes for loading audios from file!

Does this give you want?
**
PlaySoundAttachedFromFile
PlaySoundAtLocationFromFile
GetSoundWaveFromFile**



/** Contributed by UE4 forum member n00854180t! Plays a sound from file, attached to and following the specified component. This is a fire and forget sound. Replication is also not handled at this point.
* @param FilePath - Path to sound file to play
* @param AttachComponent - Component to attach to.
* @param AttachPointName - Optional named point within the AttachComponent to play the sound at
* @param Location - Depending on the value of Location Type this is either a relative offset from the attach component/point or an absolute world position that will be translated to a relative offset
* @param LocationType - Specifies whether Location is a relative offset or an absolute world position
* @param bStopWhenAttachedToDestroyed - Specifies whether the sound should stop playing when the owner of the attach to component is destroyed.
* @param VolumeMultiplier - Volume multiplier
* @param PitchMultiplier - PitchMultiplier
* @param AttenuationSettings - Override attenuation settings package to play sound with
*/ 
UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (VolumeMultiplier = "1.0", PitchMultiplier = "1.0", AdvancedDisplay = "2", UnsafeDuringActorConstruction = "true"))
static class **UAudioComponent* PlaySoundAttachedFromFile**(const FString& FilePath, class USceneComponent* AttachToComponent, FName AttachPointName = NAME_None, FVector Location = FVector(ForceInit), EAttachLocation::Type LocationType = EAttachLocation::SnapToTarget, bool bStopWhenAttachedToDestroyed = false, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f, class USoundAttenuation* AttenuationSettings = NULL);

/** Contributed by UE4 forum member n00854180t! Plays a sound at the given location. This is a fire and forget sound and does not travel with any actor. Replication is also not handled at this point.
* @param FilePath - Path to sound file to play
* @param Location - World position to play sound at
* @param World - The World in which the sound is to be played
* @param VolumeMultiplier - Volume multiplier
* @param PitchMultiplier - PitchMultiplier
* @param AttenuationSettings - Override attenuation settings package to play sound with
*/
UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary", meta = (HidePin = "WorldContextObject", DefaultToSelf = "WorldContextObject", VolumeMultiplier = "1.0", PitchMultiplier = "1.0", AdvancedDisplay = "3", UnsafeDuringActorConstruction = "true"))
static void **PlaySoundAtLocationFromFile**(UObject* WorldContextObject, const FString& FilePath, FVector Location, float VolumeMultiplier = 1.f, float PitchMultiplier = 1.f, float StartTime = 0.f, class USoundAttenuation* AttenuationSettings = NULL);

/** Contributed by UE4 forum member n00854180t! Creates a USoundWave* from file path.
* Read .ogg header file and refresh USoundWave metadata.
* @param FilePath		path to file to create sound wave from
*/
UFUNCTION(BlueprintCallable, Category = "VictoryBPLibrary")
static class **USoundWave* GetSoundWaveFromFile**(const FString& FilePath);


Enjoy!

Rama