2021-09-28 13:33:00 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
2021-11-26 15:48:13 -05:00
# include "Engine/DataAsset.h"
2023-07-18 08:42:51 -04:00
# include "GameplayTagContainer.h"
2023-01-25 02:42:36 -05:00
# include "Math/Box.h"
2022-11-17 07:44:24 -05:00
# include "WorldConditionQuery.h"
# include "WorldConditions/SmartObjectWorldConditionSchema.h"
2023-08-29 07:48:32 -04:00
# include "SmartObjectTypes.h"
2021-11-26 15:48:13 -05:00
# include "SmartObjectDefinition.generated.h"
2021-09-28 13:33:00 -04:00
2023-01-25 02:42:36 -05:00
struct FSmartObjectSlotIndex ;
2021-09-28 13:33:00 -04:00
class UGameplayBehaviorConfig ;
2023-03-27 08:22:19 -04:00
class USmartObjectSlotValidationFilter ;
2022-03-02 13:25:37 -05:00
enum class ESmartObjectTagFilteringPolicy : uint8 ;
2022-03-02 22:33:53 -05:00
enum class ESmartObjectTagMergingPolicy : uint8 ;
2021-09-28 13:33:00 -04:00
2023-03-02 05:58:30 -05:00
/** Indicates how Tags from slots and parent object are combined to be evaluated by a TagQuery from a find request. */
UENUM ( )
enum class ESmartObjectSlotShape : uint8
{
Circle ,
Rectangle
} ;
2021-09-28 13:33:00 -04:00
/**
* Abstract class that can be extended to bind a new type of behavior framework
2021-11-26 15:48:13 -05:00
* to the smart objects by defining the required definition .
2021-09-28 13:33:00 -04:00
*/
2021-11-16 07:45:37 -05:00
UCLASS ( Abstract , NotBlueprintable , EditInlineNew , CollapseCategories , HideDropdown )
2021-11-26 15:48:13 -05:00
class SMARTOBJECTSMODULE_API USmartObjectBehaviorDefinition : public UObject
2021-09-28 13:33:00 -04:00
{
GENERATED_BODY ( )
} ;
2023-08-29 07:48:32 -04:00
/** Helper struct for definition data, which allows to identify items based on GUID in editor (even empty ones). */
USTRUCT ( )
2023-12-04 07:36:52 -05:00
struct SMARTOBJECTSMODULE_API FSmartObjectDefinitionDataProxy
2023-08-29 07:48:32 -04:00
{
GENERATED_BODY ( )
2023-12-04 07:36:52 -05:00
FSmartObjectDefinitionDataProxy ( ) = default ;
2023-08-29 07:48:32 -04:00
2023-12-04 07:36:52 -05:00
template < typename T , typename = std : : enable_if_t < std : : is_base_of_v < FSmartObjectDefinitionData , std : : decay_t < T > > > >
static FSmartObjectDefinitionDataProxy Make ( const T & Struct )
2023-08-29 07:48:32 -04:00
{
2023-12-04 07:36:52 -05:00
FSmartObjectDefinitionDataProxy NewProxy ;
2023-08-29 07:48:32 -04:00
NewProxy . Data . InitializeAsScriptStruct ( TBaseStructure < T > : : Get ( ) , reinterpret_cast < const uint8 * > ( & Struct ) ) ;
# if WITH_EDITORONLY_DATA
NewProxy . ID = FGuid : : NewGuid ( ) ;
# endif
return NewProxy ;
}
UPROPERTY ( EditDefaultsOnly , Category = " Slot " , meta = ( ExcludeBaseStruct ) )
2023-12-04 07:36:52 -05:00
TInstancedStruct < FSmartObjectDefinitionData > Data ;
2023-08-29 07:48:32 -04:00
# if WITH_EDITORONLY_DATA
UPROPERTY ( EditDefaultsOnly , Category = " Slot " , meta = ( Hidden ) )
FGuid ID ;
# endif
} ;
2023-12-04 07:36:52 -05:00
using FSmartObjectSlotDefinitionDataProxy UE_DEPRECATED ( 5.4 , " Deprecated struct. Please use FSmartObjectDefinitionDataProxy instead. " ) = FSmartObjectDefinitionDataProxy ;
2021-09-28 13:33:00 -04:00
/**
2021-11-26 15:48:13 -05:00
* Persistent and sharable definition of a smart object slot .
2021-09-28 13:33:00 -04:00
*/
2023-08-22 12:17:21 -04:00
USTRUCT ( BlueprintType )
2022-01-19 14:16:16 -05:00
struct SMARTOBJECTSMODULE_API FSmartObjectSlotDefinition
2021-09-28 13:33:00 -04:00
{
GENERATED_BODY ( )
2023-08-29 07:48:32 -04:00
// Macro needed to avoid deprecation errors with "Data" being copied or created in the default methods
PRAGMA_DISABLE_DEPRECATION_WARNINGS
FSmartObjectSlotDefinition ( ) = default ;
FSmartObjectSlotDefinition ( const FSmartObjectSlotDefinition & ) = default ;
FSmartObjectSlotDefinition ( FSmartObjectSlotDefinition & & ) = default ;
FSmartObjectSlotDefinition & operator = ( const FSmartObjectSlotDefinition & ) = default ;
FSmartObjectSlotDefinition & operator = ( FSmartObjectSlotDefinition & & ) = default ;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2023-12-04 07:36:52 -05:00
/**
* Returns a reference to the definition data of the specified type .
* Method will fail a check if the slot definition doesn ' t contain the given type .
*/
template < typename T >
const T & GetDefinitionData ( ) const
{
static_assert ( TIsDerivedFrom < T , FSmartObjectDefinitionData > : : IsDerived ,
" Given struct doesn't represent a valid definition data type. Make sure to inherit from FSmartObjectDefinitionData or one of its child-types. " ) ;
for ( const FSmartObjectDefinitionDataProxy & DataProxy : DefinitionData )
{
if ( DataProxy . Data . GetScriptStruct ( ) - > IsChildOf ( T : : StaticStruct ( ) ) )
{
return DataProxy . Data . Get < T > ( ) ;
}
}
checkf ( false , TEXT ( " Failed to find slot definition data " ) ) ;
return nullptr ;
}
/**
* Returns a pointer to the definition data of the specified type .
* Method will return null if the slot doesn ' t contain the given type .
*/
template < typename T >
const T * GetDefinitionDataPtr ( ) const
{
static_assert ( TIsDerivedFrom < T , FSmartObjectDefinitionData > : : IsDerived ,
" Given struct doesn't represent a valid definition data type. Make sure to inherit from FSmartObjectDefinitionData or one of its child-types. " ) ;
for ( const FSmartObjectDefinitionDataProxy & DataProxy : DefinitionData )
{
if ( DataProxy . Data . GetScriptStruct ( ) - > IsChildOf ( T : : StaticStruct ( ) ) )
{
return DataProxy . Data . GetPtr < T > ( ) ;
}
}
return nullptr ;
}
2022-02-17 03:40:43 -05:00
# if WITH_EDITORONLY_DATA
2023-08-29 07:48:32 -04:00
UPROPERTY ( EditDefaultsOnly , Category = " Slot " )
2022-02-17 03:40:43 -05:00
FName Name ;
2023-08-29 07:48:32 -04:00
UPROPERTY ( EditAnywhere , Category = " Slot " , meta = ( DisplayName = " Color " ) )
2022-02-17 03:40:43 -05:00
FColor DEBUG_DrawColor = FColor : : Yellow ;
2022-11-01 15:11:25 -04:00
2023-08-29 07:48:32 -04:00
UPROPERTY ( EditAnywhere , Category = " Slot " , meta = ( DisplayName = " Shape " ) )
2023-03-02 05:58:30 -05:00
ESmartObjectSlotShape DEBUG_DrawShape = ESmartObjectSlotShape : : Circle ;
2023-08-29 07:48:32 -04:00
UPROPERTY ( EditAnywhere , Category = " Slot " , meta = ( DisplayName = " Size " ) )
2023-03-02 05:58:30 -05:00
float DEBUG_DrawSize = 40.0f ;
2023-08-29 07:48:32 -04:00
UPROPERTY ( EditAnywhere , Category = " Slot " , meta = ( Hidden ) )
2022-11-01 15:11:25 -04:00
FGuid ID ;
2022-02-17 03:40:43 -05:00
# endif // WITH_EDITORONLY_DATA
2023-08-29 07:48:32 -04:00
/** Offset relative to the parent object where the slot is located. */
UPROPERTY ( BlueprintReadOnly , EditDefaultsOnly , Category = " Slot " )
FVector3f Offset = FVector3f : : ZeroVector ;
/** Rotation relative to the parent object. */
UPROPERTY ( BlueprintReadOnly , EditDefaultsOnly , Category = " Slot " )
FRotator3f Rotation = FRotator3f : : ZeroRotator ;
2022-11-01 15:11:25 -04:00
/** Whether the slot is enable initially. */
2023-08-29 07:48:32 -04:00
UPROPERTY ( BlueprintReadOnly , EditDefaultsOnly , Category = " Slot " )
2022-11-01 15:11:25 -04:00
bool bEnabled = true ;
2021-09-28 13:33:00 -04:00
/** This slot is available only for users matching this query. */
2023-08-29 07:48:32 -04:00
UPROPERTY ( BlueprintReadOnly , EditDefaultsOnly , Category = " Slot " )
2021-09-28 13:33:00 -04:00
FGameplayTagQuery UserTagFilter ;
2022-03-02 13:25:37 -05:00
/**
* Tags identifying this slot ' s use case . Can be used while looking for slots supporting given activity .
* Depending on the tag filtering policy these tags can override the parent object ' s tags
* or be combined with them while applying filters from requests .
*/
2023-08-29 07:48:32 -04:00
UPROPERTY ( BlueprintReadOnly , EditDefaultsOnly , Category = " Slot " )
2022-03-02 13:25:37 -05:00
FGameplayTagContainer ActivityTags ;
2023-08-29 07:48:32 -04:00
/** Initial runtime tags. */
UPROPERTY ( BlueprintReadOnly , EditDefaultsOnly , Category = " Slot " )
FGameplayTagContainer RuntimeTags ;
2022-11-17 07:44:24 -05:00
/** Preconditions that must pass for the slot to be selected. */
2023-08-29 07:48:32 -04:00
UPROPERTY ( EditDefaultsOnly , Category = " Slot " )
2022-11-17 07:44:24 -05:00
FWorldConditionQueryDefinition SelectionPreconditions ;
2021-09-28 13:33:00 -04:00
/**
2021-11-26 15:48:13 -05:00
* All available definitions associated to this slot .
* This allows multiple frameworks to provide their specific behavior definition to the slot .
* Note that there should be only one definition of each type since the first one will be selected .
2021-09-28 13:33:00 -04:00
*/
2023-08-29 07:48:32 -04:00
UPROPERTY ( BlueprintReadOnly , EditDefaultsOnly , Category = " Slot " , Instanced )
2022-08-18 15:08:49 -04:00
TArray < TObjectPtr < USmartObjectBehaviorDefinition > > BehaviorDefinitions ;
2023-08-29 07:48:32 -04:00
2023-12-04 07:36:52 -05:00
/** Custom definition data items (struct inheriting from SmartObjecDefinitionData) that can be added to the slot definition and accessed through a FSmartObjectSlotView */
2023-08-29 07:48:32 -04:00
UPROPERTY ( EditDefaultsOnly , Category = " Slot " )
2023-12-04 07:36:52 -05:00
TArray < FSmartObjectDefinitionDataProxy > DefinitionData ;
2023-08-29 07:48:32 -04:00
# if WITH_EDITORONLY_DATA
UE_DEPRECATED ( 5.4 , " Use DefinitionData instead. " )
UPROPERTY ( )
TArray < FInstancedStruct > Data_DEPRECATED ;
# endif
2021-09-28 13:33:00 -04:00
} ;
2023-03-27 08:22:19 -04:00
/**
* Data used for previewing in the Smart Object editor .
*/
USTRUCT ( )
struct SMARTOBJECTSMODULE_API FSmartObjectDefinitionPreviewData
{
GENERATED_BODY ( )
/** Actor class used as the object for previewing the definition in the asset editor. */
UPROPERTY ( EditDefaultsOnly , Category = " Object Preview " )
TSoftClassPtr < AActor > ObjectActorClass ;
/** Path of the static mesh used as the object for previewing the definition in the asset editor. */
UPROPERTY ( EditDefaultsOnly , Category = " Object Preview " , meta = ( AllowedClasses = " /Script/Engine.StaticMesh " ) )
FSoftObjectPath ObjectMeshPath ;
/** Actor class used for previewing the smart object user actor in the asset editor. */
UPROPERTY ( EditDefaultsOnly , Category = " User Preview " )
TSoftClassPtr < AActor > UserActorClass ;
/** Validation filter used for previewing the smart object user in the asset editor. */
UPROPERTY ( EditDefaultsOnly , Category = " User Preview " )
TSoftClassPtr < USmartObjectSlotValidationFilter > UserValidationFilterClass ;
} ;
2021-09-28 13:33:00 -04:00
/**
2022-01-19 14:16:16 -05:00
* SmartObject definition asset . Contains sharable information that can be used by multiple SmartObject instances at runtime .
2021-09-28 13:33:00 -04:00
*/
2021-11-26 15:48:13 -05:00
UCLASS ( BlueprintType , Blueprintable , CollapseCategories )
class SMARTOBJECTSMODULE_API USmartObjectDefinition : public UDataAsset
2021-09-28 13:33:00 -04:00
{
GENERATED_BODY ( )
2021-11-26 15:48:13 -05:00
2021-09-28 13:33:00 -04:00
public :
2022-03-02 13:25:37 -05:00
explicit USmartObjectDefinition ( const FObjectInitializer & ObjectInitializer ) ;
2021-09-28 13:33:00 -04:00
/**
2021-11-26 15:48:13 -05:00
* Retrieves a specific type of behavior definition for a given slot .
2021-09-28 13:33:00 -04:00
* When the slot doesn ' t provide one or if the provided index is not valid
2021-11-26 15:48:13 -05:00
* the search will look in the object default definitions .
*
* @ param SlotIndex Index of the slot for which the definition is requested
* @ param DefinitionClass Type of the requested behavior definition
* @ return The behavior definition found or null if none are available for the requested type .
2021-09-28 13:33:00 -04:00
*/
2023-07-18 08:42:51 -04:00
const USmartObjectBehaviorDefinition * GetBehaviorDefinition ( const int32 SlotIndex , const TSubclassOf < USmartObjectBehaviorDefinition > & DefinitionClass ) const ;
2021-09-28 13:33:00 -04:00
2023-01-18 10:52:51 -05:00
/** @return Preconditions that must pass for the object to be found/used. */
const FWorldConditionQueryDefinition & GetPreconditions ( ) const { return Preconditions ; }
/** @return mutable Preconditions that must pass for the object to be found/used. */
FWorldConditionQueryDefinition & GetMutablePreconditions ( ) { return Preconditions ; }
2022-11-01 15:11:25 -04:00
/** @return a view on all the slot definitions */
2022-01-19 14:16:16 -05:00
TConstArrayView < FSmartObjectSlotDefinition > GetSlots ( ) const { return Slots ; }
2023-01-18 10:52:51 -05:00
/** @return slot definition stored at a given index */
2022-11-17 07:44:24 -05:00
const FSmartObjectSlotDefinition & GetSlot ( const int32 Index ) const { return Slots [ Index ] ; }
2023-01-18 10:52:51 -05:00
/** @return mutable slot definition stored at a given index */
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " )
2022-11-17 07:44:24 -05:00
FSmartObjectSlotDefinition & GetMutableSlot ( const int32 Index ) { return Slots [ Index ] ; }
2023-01-18 10:52:51 -05:00
/** @return True if specified slot index is valid. */
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " )
bool IsValidSlotIndex ( const int32 SlotIndex ) const { return Slots . IsValidIndex ( SlotIndex ) ; }
2023-08-22 16:00:16 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " , meta = ( DisplayName = " Get Smart Object Slot Definitions " ) )
2023-08-22 12:17:21 -04:00
const TArray < FSmartObjectSlotDefinition > & K2_GetSlots ( ) const { return Slots ; }
2022-11-01 15:11:25 -04:00
2022-01-19 14:16:16 -05:00
# if WITH_EDITOR
/** Returns a view on all the slot definitions */
TArrayView < FSmartObjectSlotDefinition > GetMutableSlots ( ) { return Slots ; }
2023-03-27 08:22:19 -04:00
/** @return validation filter class for preview. */
TSubclassOf < USmartObjectSlotValidationFilter > GetPreviewValidationFilterClass ( ) const ;
2023-08-29 07:48:32 -04:00
/** @return Index of the slot that has the specified ID, or INDEX_NONE if not found. */
int32 FindSlotByID ( const FGuid ID ) const ;
/**
* Returns slot and definition data indices the ID represents .
* @ param ID ID of the slots or definition data to find
* @ param OutSlotIndex Index of the slot the ID points to
* @ param OutDefinitionDataIndex Index of the definition data the ID points to , or INDEX_NONE , if ID points directly to a slot .
* @ return true if ID matches data in the definition . */
bool FindSlotAndDefinitionDataIndexByID ( const FGuid ID , int32 & OutSlotIndex , int32 & OutDefinitionDataIndex ) const ;
2022-01-19 14:16:16 -05:00
# endif
2021-09-28 13:33:00 -04:00
2022-01-07 14:28:06 -05:00
/** Return bounds encapsulating all slots */
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , Category = " SmartObject " )
2022-01-07 14:28:06 -05:00
FBox GetBounds ( ) const ;
2021-09-28 13:33:00 -04:00
/** Adds and returns a reference to a defaulted slot (used for testing purposes) */
2022-01-19 14:16:16 -05:00
FSmartObjectSlotDefinition & DebugAddSlot ( ) { return Slots . AddDefaulted_GetRef ( ) ; }
2021-09-28 13:33:00 -04:00
/**
* Returns the transform ( in world space ) of the given slot index .
* @ param OwnerTransform Transform ( in world space ) of the slot owner .
* @ param SlotIndex Index within the list of slots .
* @ return Transform ( in world space ) of the slot associated to SlotIndex .
2023-08-29 07:48:32 -04:00
* @ note Method will ensure on invalid slot index .
2021-09-28 13:33:00 -04:00
*/
2023-07-18 08:42:51 -04:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS
UE_DEPRECATED ( 5.3 , " Please use GetSlotWorldTransform() instead. " )
2021-09-28 13:33:00 -04:00
TOptional < FTransform > GetSlotTransform ( const FTransform & OwnerTransform , const FSmartObjectSlotIndex SlotIndex ) const ;
2023-07-18 08:42:51 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
/**
* Returns the transform ( in world space ) of the given slot index .
* @ param OwnerTransform Transform ( in world space ) of the slot owner .
* @ param SlotIndex Index within the list of slots .
* @ return Transform ( in world space ) of the slot associated to SlotIndex , or OwnerTransform if index is invalid .
2023-08-29 07:48:32 -04:00
* @ note Method will ensure on invalid slot index .
2023-07-18 08:42:51 -04:00
*/
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " )
2023-07-18 08:42:51 -04:00
FTransform GetSlotWorldTransform ( const int32 SlotIndex , const FTransform & OwnerTransform ) const ;
2021-09-28 13:33:00 -04:00
2022-03-02 22:33:53 -05:00
/**
* Fills the provided GameplayTagContainer with the activity tags associated to the slot according to the tag merging policy .
* @ param SlotIndex Index of the slot for which the tags are requested
* @ param OutActivityTags Tag container to fill with the activity tags associated to the slot
*/
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " , meta = ( DisplayName = " Get Slot Activity Tags (By Index) " , ScriptName = " GetSlotActivityTagsByIndex " , AutoCreateRefTerm = " OutActivityTags " ) )
2023-07-18 08:42:51 -04:00
void GetSlotActivityTags ( const int32 SlotIndex , FGameplayTagContainer & OutActivityTags ) const ;
2022-03-02 22:33:53 -05:00
/**
* Fills the provided GameplayTagContainer with the activity tags associated to the slot according to the tag merging policy .
* @ param SlotDefinition Definition of the slot for which the tags are requested
* @ param OutActivityTags Tag container to fill with the activity tags associated to the slot
*/
void GetSlotActivityTags ( const FSmartObjectSlotDefinition & SlotDefinition , FGameplayTagContainer & OutActivityTags ) const ;
2022-03-02 13:25:37 -05:00
/** Returns the tag query to run on the user tags provided by a request to accept this definition */
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " )
2021-09-28 13:33:00 -04:00
const FGameplayTagQuery & GetUserTagFilter ( ) const { return UserTagFilter ; }
2022-03-02 13:25:37 -05:00
/** Sets the tag query to run on the user tags provided by a request to accept this definition */
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , Category = " SmartObject " )
2022-03-02 13:25:37 -05:00
void SetUserTagFilter ( const FGameplayTagQuery & InUserTagFilter ) { UserTagFilter = InUserTagFilter ; }
/** Returns the tag query to run on the runtime tags of a smart object instance to accept it */
2023-01-18 10:52:51 -05:00
UE_DEPRECATED ( 5.2 , " Use FWorldCondition_SmartObjectActorTagQuery or FSmartObjectWorldConditionObjectTagQuery in Preconditions instead. " )
const FGameplayTagQuery & GetObjectTagFilter ( ) const { static FGameplayTagQuery Dummy ; return Dummy ; }
2021-09-28 13:33:00 -04:00
2022-03-02 13:25:37 -05:00
/** Sets the tag query to run on the runtime tags of a smart object instance to accept it */
2023-01-18 10:52:51 -05:00
UE_DEPRECATED ( 5.2 , " Use FWorldCondition_SmartObjectActorTagQuery or FSmartObjectWorldConditionObjectTagQuery in Preconditions instead. " )
void SetObjectTagFilter ( const FGameplayTagQuery & InObjectTagFilter ) { }
2022-03-02 13:25:37 -05:00
2021-11-26 15:48:13 -05:00
/** Returns the list of tags describing the activity associated to this definition */
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " )
2021-09-28 13:33:00 -04:00
const FGameplayTagContainer & GetActivityTags ( ) const { return ActivityTags ; }
2022-03-02 13:25:37 -05:00
/** Sets the list of tags describing the activity associated to this definition */
void SetActivityTags ( const FGameplayTagContainer & InActivityTags ) { ActivityTags = InActivityTags ; }
2022-03-02 22:33:53 -05:00
/** Returns the tag filtering policy that should be applied on User tags by this definition */
2023-08-22 12:17:21 -04:00
UFUNCTION ( BlueprintCallable , BlueprintPure , Category = " SmartObject " )
2022-03-02 22:33:53 -05:00
ESmartObjectTagFilteringPolicy GetUserTagsFilteringPolicy ( ) const { return UserTagsFilteringPolicy ; }
2022-03-02 13:25:37 -05:00
2022-03-02 22:33:53 -05:00
/** Sets the tag filtering policy to apply on User tags by this definition */
void SetUserTagsFilteringPolicy ( const ESmartObjectTagFilteringPolicy InUserTagsFilteringPolicy ) { UserTagsFilteringPolicy = InUserTagsFilteringPolicy ; }
/** Returns the tag merging policy to apply on Activity tags from this definition */
ESmartObjectTagMergingPolicy GetActivityTagsMergingPolicy ( ) const { return ActivityTagsMergingPolicy ; }
/** Sets the tag merging policy to apply on Activity tags from this definition */
void SetActivityTagsMergingPolicy ( const ESmartObjectTagMergingPolicy InActivityTagsMergingPolicy ) { ActivityTagsMergingPolicy = InActivityTagsMergingPolicy ; }
2022-03-02 13:25:37 -05:00
2021-09-28 13:33:00 -04:00
/**
2023-01-23 18:48:38 -05:00
* Performs validation for the current definition . The method will return on the first error encountered by default
* but could go through all validations and report all errors ( e . g . when saving the asset errors are reported to the user ) .
* An object using an invalid definition will not be registered in the simulation .
2021-11-02 11:12:43 -04:00
* The result of the validation is stored until next validation and can be retrieved using ` IsValid ` .
2023-01-23 18:48:38 -05:00
* @ param ErrorsToReport Optional list of error messages that could be provided to report them
2021-11-26 15:48:13 -05:00
* @ return true if the definition is valid
2021-09-28 13:33:00 -04:00
*/
2023-01-23 18:48:38 -05:00
bool Validate ( TArray < FText > * ErrorsToReport = nullptr ) const ;
2021-09-28 13:33:00 -04:00
2021-11-26 15:48:13 -05:00
/** Provides a description of the definition */
2022-01-19 14:16:16 -05:00
friend FString LexToString ( const USmartObjectDefinition & Definition )
{
2023-01-18 10:52:51 -05:00
return FString : : Printf ( TEXT ( " NumSlots=%d NumDefs=%d HasUserFilter=%s HasPreConditions=%s " ) ,
2022-01-19 14:16:16 -05:00
Definition . Slots . Num ( ) ,
Definition . DefaultBehaviorDefinitions . Num ( ) ,
* LexToString ( ! Definition . UserTagFilter . IsEmpty ( ) ) ,
2023-01-18 10:52:51 -05:00
* LexToString ( Definition . Preconditions . IsValid ( ) ) ) ;
2022-01-19 14:16:16 -05:00
}
2021-09-28 13:33:00 -04:00
2021-11-02 11:12:43 -04:00
/** Returns result of the last validation if `Validate` was called; unset otherwise. */
TOptional < bool > IsValid ( ) const { return bValid ; }
2022-01-26 07:44:21 -05:00
# if WITH_EDITORONLY_DATA
/** Actor class used for previewing the definition in the asset editor. */
2023-03-27 08:22:19 -04:00
UE_DEPRECATED ( 5.3 , " Use ObjectActorClass in PreviewData instead. " )
2022-03-02 13:25:37 -05:00
UPROPERTY ( )
2023-03-27 08:22:19 -04:00
TSoftClassPtr < AActor > PreviewClass_DEPRECATED ;
2022-01-26 07:44:21 -05:00
/** Path of the static mesh used for previewing the definition in the asset editor. */
2023-03-27 08:22:19 -04:00
UE_DEPRECATED ( 5.3 , " Use ObjectMeshPath in PreviewData instead. " )
2022-03-02 13:25:37 -05:00
UPROPERTY ( )
2023-03-27 08:22:19 -04:00
FSoftObjectPath PreviewMeshPath_DEPRECATED ;
/** Actor class used for previewing the user in the asset editor. */
UPROPERTY ( )
FSmartObjectDefinitionPreviewData PreviewData ;
2022-11-01 15:11:25 -04:00
# endif // WITH_EDITORONLY_DATA
2022-11-17 07:44:24 -05:00
const USmartObjectWorldConditionSchema * GetWorldConditionSchema ( ) const { return WorldConditionSchemaClass . GetDefaultObject ( ) ; }
const TSubclassOf < USmartObjectWorldConditionSchema > & GetWorldConditionSchemaClass ( ) const { return WorldConditionSchemaClass ; }
2023-12-04 07:36:52 -05:00
/**
* Returns a reference to the definition data of the specified type .
* Method will fail a check if the slot definition doesn ' t contain the given type .
*/
template < typename T >
const T & GetDefinitionData ( ) const
{
static_assert ( TIsDerivedFrom < T , FSmartObjectDefinitionData > : : IsDerived ,
" Given struct doesn't represent a valid definition data type. Make sure to inherit from FSmartObjectDefinitionData or one of its child-types. " ) ;
for ( const FSmartObjectDefinitionDataProxy & DataProxy : DefinitionData )
{
if ( DataProxy . Data . GetScriptStruct ( ) - > IsChildOf ( T : : StaticStruct ( ) ) )
{
return DataProxy . Data . Get < T > ( ) ;
}
}
checkf ( false , TEXT ( " Failed to find definition data " ) ) ;
return nullptr ;
}
/**
* Returns a pointer to the definition data of the specified type .
* Method will return null if the slot doesn ' t contain the given type .
*/
template < typename T >
const T * GetDefinitionDataPtr ( ) const
{
static_assert ( TIsDerivedFrom < T , FSmartObjectDefinitionData > : : IsDerived ,
" Given struct doesn't represent a valid definition data type. Make sure to inherit from FSmartObjectDefinitionData or one of its child-types. " ) ;
for ( const FSmartObjectDefinitionDataProxy & DataProxy : DefinitionData )
{
if ( DataProxy . Data . GetScriptStruct ( ) - > IsChildOf ( T : : StaticStruct ( ) ) )
{
return DataProxy . Data . GetPtr < T > ( ) ;
}
}
return nullptr ;
}
2022-11-17 07:44:24 -05:00
2022-11-01 15:11:25 -04:00
protected :
# if WITH_EDITOR
void UpdateSlotReferences ( ) ;
virtual void PostEditChangeChainProperty ( FPropertyChangedChainEvent & PropertyChangedEvent ) override ;
virtual void PreSave ( FObjectPreSaveContext SaveContext ) override ;
2023-04-27 17:53:18 -04:00
virtual EDataValidationResult IsDataValid ( class FDataValidationContext & Context ) const override ;
2022-11-01 15:11:25 -04:00
# endif // WITH_EDITOR
2022-01-26 07:44:21 -05:00
2022-11-17 07:44:24 -05:00
virtual void PostLoad ( ) override ;
2021-09-28 13:33:00 -04:00
private :
2021-11-26 15:48:13 -05:00
/** Finds first behavior definition of a given class in the provided list of definitions. */
static const USmartObjectBehaviorDefinition * GetBehaviorDefinitionByType ( const TArray < USmartObjectBehaviorDefinition * > & BehaviorDefinitions , const TSubclassOf < USmartObjectBehaviorDefinition > & DefinitionClass ) ;
2021-09-28 13:33:00 -04:00
/**
* Where SmartObject ' s user needs to stay to be able to activate it . These
* will be used by AI to approach the object . Locations are relative to object ' s location .
*/
2022-11-01 15:11:25 -04:00
UPROPERTY ( EditDefaultsOnly , Category = " SmartObject " )
2022-01-19 14:16:16 -05:00
TArray < FSmartObjectSlotDefinition > Slots ;
2021-09-28 13:33:00 -04:00
2021-11-26 15:48:13 -05:00
/** List of behavior definitions of different types provided to SO's user if the slot does not provide one. */
2022-11-01 15:11:25 -04:00
UPROPERTY ( EditDefaultsOnly , Category = " SmartObject " , Instanced )
2022-08-18 15:08:49 -04:00
TArray < TObjectPtr < USmartObjectBehaviorDefinition > > DefaultBehaviorDefinitions ;
2021-09-28 13:33:00 -04:00
2022-03-17 11:17:04 -04:00
/** This object is available if user tags match this query; always available if query is empty. */
2022-11-01 15:11:25 -04:00
UPROPERTY ( EditDefaultsOnly , Category = " SmartObject " )
2021-09-28 13:33:00 -04:00
FGameplayTagQuery UserTagFilter ;
2023-01-18 10:52:51 -05:00
# if WITH_EDITORONLY_DATA
2022-03-17 11:17:04 -04:00
/** This object is available if instance tags match this query; always available if query is empty. */
2023-01-18 10:52:51 -05:00
UE_DEPRECATED ( 5.2 , " FWorldCondition_SmartObjectActorTagQuery or FSmartObjectWorldConditionObjectTagQuery used in Preconditions instead. " )
UPROPERTY ( meta = ( DeprecatedProperty , DeprecationMessage = " Use FWorldCondition_SmartObjectActorTagQuery or FSmartObjectWorldConditionObjectTagQuery in Preconditions instead. " ) )
2021-09-28 13:33:00 -04:00
FGameplayTagQuery ObjectTagFilter ;
2023-01-18 10:52:51 -05:00
# endif // WITH_EDITORONLY_DATA
2021-09-28 13:33:00 -04:00
2023-01-18 10:52:51 -05:00
/** Preconditions that must pass for the object to be found/used. */
UPROPERTY ( EditDefaultsOnly , Category = " SmartObject " )
FWorldConditionQueryDefinition Preconditions ;
private :
2021-09-28 13:33:00 -04:00
/** Tags identifying this Smart Object's use case. Can be used while looking for objects supporting given activity */
2022-11-01 15:11:25 -04:00
UPROPERTY ( EditDefaultsOnly , Category = " SmartObject " )
2021-09-28 13:33:00 -04:00
FGameplayTagContainer ActivityTags ;
2021-11-02 11:12:43 -04:00
2023-12-04 07:36:52 -05:00
/** Custom definition data items (struct inheriting from SmartObjectDefinitionData) for the whole Smart Object. */
UPROPERTY ( EditDefaultsOnly , Category = " SmartObject " , meta = ( DisallowedStructs = " /Script/SmartObjectsModule.SmartObjectSlotAnnotation " ) )
TArray < FSmartObjectDefinitionDataProxy > DefinitionData ;
2022-11-17 07:44:24 -05:00
UPROPERTY ( EditDefaultsOnly , Category = " SmartObject " , AdvancedDisplay )
TSubclassOf < USmartObjectWorldConditionSchema > WorldConditionSchemaClass ;
2022-03-02 22:33:53 -05:00
/** Indicates how Tags from slots and parent object are combined to be evaluated by a TagQuery from a find request. */
2022-11-01 15:11:25 -04:00
UPROPERTY ( EditAnywhere , Category = " SmartObject " , AdvancedDisplay )
2022-03-02 22:33:53 -05:00
ESmartObjectTagMergingPolicy ActivityTagsMergingPolicy ;
/** Indicates how TagQueries from slots and parent object will be processed against User Tags from a find request. */
2022-11-01 15:11:25 -04:00
UPROPERTY ( EditAnywhere , Category = " SmartObject " , AdvancedDisplay )
2022-03-02 22:33:53 -05:00
ESmartObjectTagFilteringPolicy UserTagsFilteringPolicy ;
2022-11-17 07:44:24 -05:00
2021-11-02 11:12:43 -04:00
mutable TOptional < bool > bValid ;
2022-11-01 15:11:25 -04:00
friend class FSmartObjectSlotReferenceDetails ;
2023-08-29 07:48:32 -04:00
friend class FSmartObjectViewModel ;
friend class FSmartObjectAssetToolkit ;
2023-12-04 07:36:52 -05:00
friend class FSmartObjectDefinitionDetails ;
2021-09-28 13:33:00 -04:00
} ;
2022-01-19 14:16:16 -05:00
2023-01-25 02:42:36 -05:00
# if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_2
# include "SmartObjectTypes.h"
# endif