Blueprint functions not accessible from UObject derived classes

Hello,

when scripting in a blueprint that derives from UObject but not from AActor certain functions cannot be seen in the “All actions for this blueprint” search bar with “Context Sensitive” disabled.

Reproducing the bug:

  1. Add C++ Class inheriting directly from UObject
  2. Add the following class specifiers: BlueprintType, Blueprintable
  3. Add a method with a pointer to an actor as parameter.
  4. Add the following function specifiers: BlueprintNativeEvent, Category
  5. Create Blueprint deriving from C++ class and implement the native event
  6. Right-click and experience missing functions, such as: Add Child Actor Component. Even using the actor parameter which could be used as “Target” does not show up.

See also: https://answers.unrealengine.com/questions/218297/blueprint-function-library-is-not-always-accessibl.html

Edited 11/05 at request of Sean Flint :
First off, I would like to thank you for looking into this issue more deeply.
The below code snippet is the class I wish to use as a parent in a blueprint; please assume that Callback_Implementation, which is required for native events, is defined and is empty.

UCLASS(Blueprintable, BlueprintType, EditNewInline)
class SOME_API UCallable : public UObject
{
	GENERATED_BODY()

	UFUNCTION(BlueprintNativeEvent, Category = SomeCategory)
    void Callback(AActor* Actor);
};

I am aware the particular function which was mentoined in step 6, “Add Child Actor Component”, is not a function contained in UObject; it is contained in AActor I presume. However, it should be possible to call “Add Child Actor Component” by using the actor as a target to call on. For instance, in C++ you could still call Actor->AddChildActorComponent(args) in the implementation of Callback even though AddChildActorComponent is not defined in UObject (assuming it is indeed a member function of AActor). Elaborating on Sean’s point more, the component would then be stored as a child of the “Actor” parameter on which we called the function.

The bug I am experiencing is that the function “Add Child Actor Component” and many other functions do not show up in the search bar of the blueprint. I expect functions which were not defined in UObject but in other classes, such as AActor, which have a target, to show up and be able to call them; in blueprints I expect to be able to do the equivalent of: Actor->AddChildActorComponent(args). This assumes that “AddChildActorComponent” is indeed a member function of AActor but I just use it to better explain my pointer; member functions, hence those that have an implicit ‘this’ pointer, should be callable in that setting.

I have further experimented with the bug and discovered that if UCallable inherited from UActorComponent instead, all functions would show up in the search bar. This is bizarre as UActorComponent directly inherits from UObject, as well, which leads me to believe this is some kind of bug.

Thank you for your time and efforts.

Cheers,
Univise

You’ve probably tried it, but every time I write a new function I have to restart the editor for it to show up in BP.

Hello,

A few things:

  • Could you provide the full code that you are using to reproduce this issue?
  • In UObject classes, you wouldn’t be able to call these functions, as these are not functions contained within that class. Also, even if you did use Add Child Actor Component, the UObject blueprint has nowhere to store that component.

Could you describe your issue in a bit more detail? What sort of behavior are you expecting, and what exactly are you seeing?

Thank you

Thank your for your response. I have updated the question to reflect your inquiries.

Thanks for your response but it is not my functions that are not being shown; the functions that come with the engine are not showing up. The functions that I define in my object are perfectly showing up.

Could you name a few of the functions that you are not able to see that you are expecting to see?

Also, are you able to see functions such as Get Actor Location?

GetActorLocation() does show up. Some functions that does not show up: PlaySoundAtLocation, while PlaySoundAttached does show up; Spawn Actor From Class; Spawn Effect At Location. The pattern is that generally those functions the have an exec connection do not show up and those that do not, like GetActorLocation(), do though that is just an impression I have gotten from the few functions I have (not) seen.

Note that the functions I have listed show up if the blueprint inherits from UActorComponent. They do not show up when it inherits from UObject. Clearly, the functions are not defined in neither UActorComponent nor UObject.

Hello,

After some investigation and conversations with our developers, it appears that the functions that are not showing up are those that require a World Context Object. This is currently an expected limitation of the API, but is something that we are eventually looking into improving.

In the meantime, you can base your class on Actor instead, which as long as you don’t use tick won’t cost much more in terms of performance. Also, you could try making your own UObject subclass and add meta=(ShowWorldContextPin) to the UCLASS declaration.

Have a great day

Sean, thank you so much for the meta=(ShowWorldContextPin) tip! Works great for my custom UObjects and this tip has saved me a lot of work :slight_smile:

Got the definitive solution and here I share it!

Add this override to your UObject child class header:

virtual UWorld* GetWorld() const override
{
	if (HasAllFlags(RF_ClassDefaultObject))
	{
		// If we are a CDO, we must return nullptr instead of calling Outer->GetWorld() to fool UObject::ImplementsGetWorld.
		return nullptr;
	}
	return GetOuter()->GetWorld();
}

Wow. This worked for me. I was about to do the “meta=(ShowWorldContextPin)” solution but was amazed to see your’s worked.

My UObject is now able to call things that require a world context object like Spawn Emitter at Location.

I can confirm this works with 4.15.2 compiled with VS2017

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

#pragma once

#include "UObject/NoExportTypes.h"
#include "ActionEffectUObject.generated.h"

/**
 * 
 */
UCLASS(Blueprintable)
class GAMENAME_API UObjectWithBlueprintFunctionsAccess : public UObject
{
	GENERATED_BODY()
	
public:
	virtual UWorld* GetWorld() const override
	{
		if (HasAllFlags(RF_ClassDefaultObject))
		{
			// If we are a CDO, we must return nullptr instead of calling Outer->GetWorld() to fool UObject::ImplementsGetWorld.
			return nullptr;
		}
		return GetOuter()->GetWorld();
	}
};

It works for me, but adds serious lag to first call of any world context dependant functions. So I used different approach - I pass GameInstance to my UObject upon creation and then delegate GetWorld call to it instead of GetOuter(). Could be any other world context aware object, I just had reference to GameInstance already avalible.