[Question]Ensure condition failed: false Unsupported context object of class Effect10s_C (SuperClass(es) - RPGEffectBase, Object). You must add a way to retrieve context to a class in the hierarchy

It just poped out of nowhere.

There is full relevelant communicate from log:

D:\BuildFarm\buildmachine_++depot+UE4-Rocket+Beta6\Engine\Source\Runtime\Engine\Private\UnrealEngine.cpp(7882): Ensure condition failed: false
Unsupported context object of class Effect10s_C (SuperClass(es) - RPGEffectBase, Object). You must add a way to retrieve context to a class in the hierarchy.
RocketEditor.exe has triggered a breakpoint.

It happens because I try to use:

UFUNCTION(BlueprintImplementableEvent, Category=AbilityEffects)
void OnEffectAppiled();

In my blueprint.

Then it break here:

IMPLEMENT_CLASS(URPGEffectBase);
void URPGEffectBase::OnEffectAppiled()
{
	ProcessEvent(FindFunctionChecked(RPG_OnEffectAppiled),NULL);
}

In RPG.generated.inl

And this is my header file:

#pragma once

#include "RPGEffectBase.generated.h"
//DECLARE_DYNAMIC_MULTICAST_DELEGATE(FEffectAppiledToTarget);
enum EffectAlligment
{
	Effect_Negative,
	Effect_Neutral,
	Effect_Positive
};

/**
 * 
 */
UCLASS(Blueprintable)
class URPGEffectBase : public UObject
{
	GENERATED_UCLASS_BODY()
(...)

Here is where event is called in code:

void URPGEffectBase::Initialize()
{
	ARPGCharacter* GC = Cast(AffectedTarget);
	if(GC)
	{
		OnEffectAppiled();
		//OnEffectAppiledtoTarget.Broadcast();
		UWorld* world = GetCurrentWorld(GC);
		if(world)
		{
			if(ShouldEffectTick)
			{
				FTimerDynamicDelegate eventTick;
				eventTick.BindDynamic(this, &URPGEffectBase::SetEffectTick);
				world->GetTimerManager().SetTimer(eventTick, TickDuration, true);
			}
			FTimerDynamicDelegate tdd;
			tdd.BindDynamic(this, &URPGEffectBase::RemoveFromArray);
			world->GetTimerManager().SetTimer(tdd, Duration, false);

			FTimerDelegate td;
			td.BindUObject(this, &URPGEffectBase::SetOnEffectRemoved);
			world->GetTimerManager().SetTimer(td, Duration, false);
		}
	}
}

And here is how it is added to character:

void URPGEffectManagerComponent::AddEffect(URPGEffectBase* newEffect)
{
	newEffect->Initialize();
	EffectsList.Add(newEffect);
	//FTimerDelegate td;
	
}

And there blueprint function that is used to apply:

void URPGEffectBPLibrary::ApplyEffect(AActor* effectTarget, AActor* causedBy, TSubclassOf appiledEffect)
{
	ARPGCharacter* GC = Cast(effectTarget);
	if(GC)
	{
		if(appiledEffect)
		{
			//static ConstructorHelpers::FObjectFinder spawnEffect (appiledEffect.Class);
			//GC->EffectManager->EffectsList.Add(appiledEffect.GetDefaultObject());
			URPGEffectBase* effect = ConstructObject(appiledEffect);
			effect->AffectedTarget = effectTarget;
			effect->CausedBy = causedBy;
			GC->EffectManager->AddEffect(effect);
		}
	}
}

It does not cause crash, only this annoying break.

Moreover it happen only on first usage of said event. After that any other usage of this event work fine.

Hi Lukasz,

This error message means that something tried to use your URPGEffectBase object to retrieve a UWorld pointer that it doesn’t have. You have a few options here.

  1. Create a custom WorldFromContextGetter class for your project and write custom code to figure out the appropriate UWorld for your object.
  2. Derive URPGEffectBase from AActor instead.
  3. Figure out from the callstack what is causing the game to try and get a UWorld context from this object and fix it at that level.

The 2nd option looks like a good option to me, since you clearly want it to tick and you could then easily add visual components to it. I’m making some guesses about your intent there though, so take that with a grain of salt.

Also, FYI I’ve improved that error message as it was pretty unclear what was going on.

Cheers!
Jeff

Thanks!
Idd, I’m creating world context during object creation. I didn’t know what error message really meant, now I can try to fix it

I’d rather try to pass world context in some different way, than deriving from AActor, since this class is pretty small, and I never intend it to be place on level. Only “attached” to actor for set period of time and then destroyed. Deriving from AActor seam bit like overkill, at this stage.

Just for further refence if someone would run into similiar issue and don’t know how to get around it. In my case issue was here:

if(GC)
{
	/*OnHealthChange.BindDynamic(this, &URPGEffectBase::HealthChange);
	OnHealthChange.Broadcast(GC->Attributes.Health);*/
	UWorld* world = GetCurrentWorld(AffectedTarget);
	if(world)
	{
		if(ShouldEffectTick)
		{
			FTimerDynamicDelegate eventTick;
			eventTick.BindDynamic(this, &URPGEffectBase::SetEffectTick);
			world->GetTimerManager().SetTimer(eventTick, TickDuration, true);
		}
		FTimerDynamicDelegate tdd;
		tdd.BindDynamic(this, &URPGEffectBase::RemoveFromArray);
		world->GetTimerManager().SetTimer(tdd, Duration, false);

		//FTimerDelegate td;
		//td.BindUObject(this, &URPGEffectBase::SetOnEffectRemoved);
		//world->GetTimerManager().SetTimer(td, Duration, false);
		OnEffectAppiled();
	}
}

In original version I called OnEffectAppiled(); event outside of if(world) block (and more over before world context have been acquired), The event is used in various places in blueprints, to initialize whatever blueprint needs to do. But since there was no world context for said event, it was unclear where to do things (;.

It’s odd the issue returned. The fix for the issue was to delete blueprints, and recreate them from scratch. As I’m now 100% I have resolved the world context problem as I just get it locally from actors passed around.
It might be bug, that blueprints do not get new… Whatever they get after recompilation of code. I can post stripped code, or upload project that will show it, As at this point I’m not sure if it is my fault, or engine.