Reference existing component

in my c++ class I have added:



UPROPERTY(EditAnywhere, BlueprintReadWrite)
USceneComponent*	RollNode;


It shows in in the blueprint editor but wants to create a new component, I cant drag and drop an existing component from the component hierarchy, which is what I want to do.

I don’t think there’s an easy way to do drag and drop directly, but you can use an FComponentReference instead of a USceneComponent* and it will let you type in the name of the component in the blueprint defaults, and you can use RollNode->GetComponent(this) to get the actual pointer to it in your code.

1 Like

hrmm this seems not to be working. I have it setup like so with the node I want to access in code circled in red

in Code I have:



UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FComponentReference RollNode;


	USceneComponent*	m_rollNode;




m_rollNode = RollNode.GetComponent(m_owner);


m_rollNode is null.

Unfortunately it seems the names shown in the component tree tab do not necessarily match with the underlying FName of the component. For example, with C++ based components, the displayed name is the name of the actual property member, whereas the actual component name is whatever is supplied to CreateDefaultSubobject. I’m not sure how you can find the underlying name manually from within the editor.

Edit: Forget that, it looks like FComponentReference works on property name anyway, not internal name. So I don’t know why it wouldn’t be working.

Looks like the implementation of FComponentReference is trying to cast to UPrimitiveComponent, which will return null for any other type of component.
I think it’s a bug, I’ve filed a report.

I worked around the bug using a modified GetComponent:



/*!
	Work around for FComponentReference.GetComponent not working correctly
	https://answers.unrealengine.com/questions/179994/fcomponentreference-works-only-for-uprimitivecompo.html
*/
USceneComponent* GetComponent(FComponentReference& Component, AActor* OwningActor)
{
	USceneComponent* Result = NULL;
	// Component is specified directly, use that
	if (Component.OverrideComponent.IsValid())
	{
		Result = Component.OverrideComponent.Get();
	}
	else
	{
		// Look in Actor if specified, OwningActor if not
		AActor* SearchActor = (Component.OtherActor != NULL) ? Component.OtherActor : OwningActor;
		if (SearchActor)
		{
			if (Component.ComponentProperty != NAME_None)
			{
				UObjectPropertyBase* ObjProp = FindField<UObjectPropertyBase>(SearchActor->GetClass(), Component.ComponentProperty);
				if (ObjProp != NULL)
				{
					// .. and return the component that is there
					Result = Cast<USceneComponent>(ObjProp->GetObjectPropertyValue_InContainer(SearchActor));
				}
			}
			else
			{
				Result = Cast<USceneComponent>(SearchActor->GetRootComponent());
			}
		}
	}

	return Result;
}


1 Like

In case somebody is wondering about the state of this bug:

It was fixed in 4.8 :slight_smile:

1 Like