Base class for creating Smart Objects related World Conditions. Smart objects use these as “preconditions” - rules to determine whether a given smart object or Smart Object Slot is valid to claim.

Basic code template

//.h
USTRUCT(DisplayName="Nice Displayname")
struct MY_API FMyWorldCondition : public FSmartObjectWorldConditionBase
{
	GENERATED_BODY()
 
	virtual bool Initialize(const UWorldConditionSchema& Schema) override;
	virtual bool Activate(const FWorldConditionContext& Context) const override;
	virtual FWorldConditionResult IsTrue(const FWorldConditionContext& Context) const override;
	
	FWorldConditionContextDataRef SmartObjectActorRef;
	FWorldConditionContextDataRef UserActorRef;
 
#if WITH_EDITOR
	virtual FText GetDescription() const override;
#endif
};
 
 
//.cpp
bool FMyWorldCondition::Initialize(const UWorldConditionSchema& Schema)
{
	//Initialize is used to collect data references from the schema
	//so they can be used later
	const USmartObjectWorldConditionSchema* SmartObjectSchema = Cast<USmartObjectWorldConditionSchema>(&Schema);
 
	SmartObjectActorRef = SmartObjectSchema->GetSmartObjectActorRef();
	UserActorRef = SmartObjectSchema->GetUserActorRef();
 
	return true;
}
 
bool FMyWorldCondition::Activate(const FWorldConditionContext& Context) const
{
	//Activate can be used to validate that the references are valid, or
	//perform other kinds of initialization work
	if (!SmartObjectActorRef.IsValid())
	{
		return false;
	}
	
	if (!UserActorRef.IsValid())
	{
		return false;
	}
	
	return true;
}
 
FWorldConditionResult FMyWorldCondition::IsTrue(const FWorldConditionContext& Context) const
{
	//Perform the actual condition checking here
	
	//We can get the actual objects the references point to here:
	const AActor* const SmartObjectActor = Context.GetContextDataPtr<AActor>(SmartObjectActorRef);
	const AActor* const UserActor = Context.GetContextDataPtr<AActor>(UserActorRef);
 
	FWorldConditionResult Result(EWorldConditionResultValue::IsFalse, false);
	if(SomeConditionToCheck)
	{
		Result.Value = EWorldConditionResultValue::IsTrue;
	}
 
	return Result;
}
 
#if WITH_EDITOR
FText FMyWorldCondition::GetDescription() const
{
	return INVTEXT("Nice Description for Editor");
}
#endif

Other

  • There is also a Deactivate function which can be overridden to perform logic when the condition is no longer active.
  • It’s valid to add UPROPERTY(EditAnywhere) properties to the condition. These will be editable in the editor.