Download

C++ Blueprint Function not showing up in Blueprint Editor

Hi all,

I am trying to get a C++ function to show up in the Blueprint editor. I create a new C++ class > Copy the code into the .h and .cpp files and change the names to be the name of my game > Build the solution > Open the editor and the function is not there. I tried these exact steps on another project and it worked. So is there something I could have accidental changed that is making this not work for one of my projects? My Engine version is 4.9.2 and I am using Perforce Source Control. Below is the code I am using.

.h


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "HUDBlueprintLibrary.generated.h"

/**
 * 
 */
UCLASS()
class MOSEXAMPLE_API UHUDBlueprintLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:
	/**
	* Converts a world location to screen position for HUD drawing. This differs from the results of FSceneView::WorldToScreen in that it returns a position along the edge of the screen for offscreen locations
	*
	* @param		InLocation	- The world space location to be converted to screen space
	* @param		EdgePercent - How close to the edge of the screen, 1.0 = at edge, 0.0 = at center of screen. .9 or .95 is usually desirable
	* @outparam	OutScreenPosition - the screen coordinates for HUD drawing
	* @outparam	OutRotationAngleDegrees - The angle to rotate a hud element if you want it pointing toward the offscreen indicator, 0° if onscreen
	* @outparam	bIsOnScreen - True if the specified location is in the camera view (may be obstructed)
	*/
	UFUNCTION(BlueprintPure, meta = (WorldContext = "WorldContextObject", CallableWithoutWorldContext), Category = "HUD|Util")
		static void FindScreenEdgeLocationForWorldLocation(UObject* WorldContextObject, const FVector& InLocation, const float EdgePercent, FVector2D& OutScreenPosition, float& OutRotationAngleDegrees, bool &bIsOnScreen);

};

.cpp


// Fill out your copyright notice in the Description page of Project Settings.

#include "MOSExample.h"
#include "HUDBlueprintLibrary.h"

void UHUDBlueprintLibrary::FindScreenEdgeLocationForWorldLocation(UObject* WorldContextObject, const FVector& InLocation, const float EdgePercent, FVector2D& OutScreenPosition, float& OutRotationAngleDegrees, bool &bIsOnScreen)
{
	bIsOnScreen = false;
	OutRotationAngleDegrees = 0.f;	

	if (!GEngine) return;

	const FVector2D ViewportSize = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY());
	const FVector2D  ViewportCenter = FVector2D(ViewportSize.X / 2, ViewportSize.Y / 2);

	UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject);

	if (!World) return;

	APlayerController* PlayerController = (WorldContextObject ? UGameplayStatics::GetPlayerController(WorldContextObject, 0) : NULL);

	if (!PlayerController) return;

	ACharacter* PlayerCharacter = Cast<ACharacter>(PlayerController->GetPawn());

	if (!PlayerCharacter) return;

	FVector Forward = PlayerCharacter->GetActorForwardVector();
	FVector Offset = (InLocation - PlayerCharacter->GetActorLocation()).GetSafeNormal();

	float DotProduct = FVector::DotProduct(Forward, Offset);
	bool bLocationIsBehindCamera = (DotProduct < 0);

	if (bLocationIsBehindCamera)
	{
		// For behind the camera situation, we cheat a little to put the
		// marker at the bottom of the screen so that it moves smoothly
		// as you turn around. Could stand some refinement, but results
		// are decent enough for most purposes.

		FVector DiffVector = InLocation - PlayerCharacter->GetActorLocation();
		FVector Inverted = DiffVector * -1.f;
		FVector NewInLocation = PlayerCharacter->GetActorLocation() * Inverted;

		NewInLocation.Z -= 5000;

		PlayerController->ProjectWorldLocationToScreen(NewInLocation, OutScreenPosition);
		OutScreenPosition.Y = (EdgePercent * ViewportCenter.X) * 2.f;
		OutScreenPosition.X = -ViewportCenter.X - OutScreenPosition.X;
	}

	PlayerController->ProjectWorldLocationToScreen(InLocation, OutScreenPosition);//*ScreenPosition);

	// Check to see if it's on screen. If it is, ProjectWorldLocationToScreen is all we need, return it.	
	if (OutScreenPosition.X >= 0.f && OutScreenPosition.X <= ViewportSize.X
		&& OutScreenPosition.Y >= 0.f && OutScreenPosition.Y <= ViewportSize.Y)
	{
		
		bIsOnScreen = true;
		return;
	}

	OutScreenPosition -= ViewportCenter;

	float AngleRadians = FMath::Atan2(OutScreenPosition.Y, OutScreenPosition.X);
	AngleRadians -= FMath::DegreesToRadians(90.f);

	OutRotationAngleDegrees = FMath::RadiansToDegrees(AngleRadians) + 180.f;

	float Cos = cosf(AngleRadians);
	float Sin = -sinf(AngleRadians);

	OutScreenPosition = FVector2D(ViewportCenter.X + (Sin * 180.f), ViewportCenter.Y + Cos * 180.f);

	float m = Cos / Sin;

	FVector2D ScreenBounds = ViewportCenter * EdgePercent;

	if (Cos > 0)
	{		
		OutScreenPosition = FVector2D(ScreenBounds.Y / m, ScreenBounds.Y);
	}
	else
	{		
		OutScreenPosition = FVector2D(-ScreenBounds.Y / m, -ScreenBounds.Y);
	}

	if (OutScreenPosition.X > ScreenBounds.X)
	{		
		OutScreenPosition = FVector2D(ScreenBounds.X, ScreenBounds.X*m);
	}
	else if (OutScreenPosition.X < -ScreenBounds.X)
	{		
		OutScreenPosition = FVector2D(-ScreenBounds.X, -ScreenBounds.X*m);
	}
	
	OutScreenPosition += ViewportCenter;	

}

This code is from the kind people jeff_lamarche and ZioYuri78 over at this forum post https://forums.unrealengine.com/showthread.php?59398-Easy-Offscreen-Indicator-Blueprint-Node

Quickly tried the function in my own blueprint library and it showed up fine. So everything looks ok really. Assuming MOSEXAMPLE_API is correct for your project?

Compile in Visual Studio as “Development Editor” mode and make sure your library is compiling, listed in the output panel.

Well this is interesting. I had the very same issue. So I just played around with the different Blueprint specifiers, thought maybe my additional spaces before/after the = for the category name would break things. But nothing. Only after I replaced BlueprintPure with BlueprintCallable for my UFUNCTION() static bool Func(); the function appeared after Hot Reload from the editor.

There are several places in the engine source where BlueprintPure is used. And as it seems (at least for my build) even those do not work. For example in LeapMotionFunctionLibrary.h only SetHmdPolicy and SetImagePolicy are BlueprintCallable and both appear for me in the Blueprint Editor. All other UFUNCTIONS in the ULeapMotionFunctionLibrary have BlueprintPure and should be in the same category. But they are simply not there.

So are there any limitations for BlueprintPure? Or is it a bug, known issue?

I’m using 4.9.1 from GitHub. Which one are you using @Gigantoad?

EDIT: I just double checked. And now I feel really stupid. Disable the Context Sensitive option and you should see your function. But I wonder why this is necessary? Shouldn’t a static function always be a valid function to call in any context?

EDIT 2: I checked my Blueprint Context Targets and they are all checked excepted “Node Target”, “Other Object Outputs” and “Pin Type Class” which are greyed-out. There are two more things I find weird. When I just right-click in empty space my function is listed despite the same Blueprint Context Targets settings. However if I drag out a wire from a previous node and then release to have the list pop up, my function is not listed unless I disable the context sensitivity.

EDIT 3: Placing this node in the Blueprint Graph will work. Only that it will not have an “execution” input so you cannot call the function… Maybe that’s just because of my special case though and using the return pin seems to work in that my function is executed. I guess having no execution input pin explains why the function does not appear in the list when context sensitivity is enabled.

1 Like

4.92.

Well yes, that makes a lot of sense. if you drag out from another node, no BlueprintPure node should ever show up in a context sensitive way because there’s simply no way to connect such a node to another. Pure means it doesn’t have an execution pin. it’s there for getting value type of stuff.

Thanks for the help guys. I solved the problem by making a new project and migrating all my content to that project. The C++ class worked there. I do not know why it didn’t work before by it is working now in the new project.

Hi, here I am 5 years later responding to this issue seeing as I encountered it myself. The solution may not apply to everyone, but here is what cause the issue for me:

Your function library resides within a module, if placed directly in Projects source folder it will be Source/ProjectName/ProjectName.Build.cs, if placed within a plugin it will be Plugins/*PluginName/Source/*PluginName/*PluginName.*Build.cs (or similar). Now this module can be set to Editor/Runtime in either the *ProjectName.*uproject or the *PluginName.*uplugin.

If it is set to Editor it will not show your Functions.
So make sure that it is set to Runtime as such:
“Modules”:
{
“Name”: “ProjectName”,
“Type”: “Runtime”,
“LoadingPhase”: “Default”
}
],

Cheers, Linus

I just had this problem. I tried to assign blueprintCallable to the GetAmmo functions in the Shooter Game. After several hot reloads the functions didn’t showed up. The uproject file was set in type runtime for both modules (shooterGame and ShotterLoadingScreen). I changed the category and did a full compile in Visual Studio. Took like 10 minutes but finally the functions appeared in Blueprint.

Mine was already at runtime and I changed it to Editor, this worked for me. Thanks Linus!