@ -0,0 +1,16 @@
|
||||
#include "CSActorComponentExtensions.h"
|
||||
|
||||
void UCSActorComponentExtensions::AddReplicatedSubObject(UActorComponent* ActorComponent, UObject* SubObject, ELifetimeCondition NetCondition)
|
||||
{
|
||||
ActorComponent->AddReplicatedSubObject(SubObject, NetCondition);
|
||||
}
|
||||
|
||||
void UCSActorComponentExtensions::RemoveReplicatedSubObject(UActorComponent* ActorComponent, UObject* SubObject)
|
||||
{
|
||||
ActorComponent->RemoveReplicatedSubObject(SubObject);
|
||||
}
|
||||
|
||||
bool UCSActorComponentExtensions::IsReplicatedSubObjectRegistered(UActorComponent* ActorComponent, UObject* SubObject)
|
||||
{
|
||||
return ActorComponent->IsReplicatedSubObjectRegistered(SubObject);
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSActorComponentExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSActorComponentExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void AddReplicatedSubObject(UActorComponent* ActorComponent, UObject* SubObject, ELifetimeCondition NetCondition);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void RemoveReplicatedSubObject(UActorComponent* ActorComponent, UObject* SubObject);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsReplicatedSubObjectRegistered(UActorComponent* ActorComponent, UObject* SubObject);
|
||||
};
|
||||
@ -0,0 +1,158 @@
|
||||
#include "CSActorExtensions.h"
|
||||
|
||||
#include "UnrealSharpCore.h"
|
||||
#include "Engine/InheritableComponentHandler.h"
|
||||
#include "Engine/SCS_Node.h"
|
||||
#include "Engine/SimpleConstructionScript.h"
|
||||
#include "TypeGenerator/CSClass.h"
|
||||
#include "TypeGenerator/Register/CSGeneratedClassBuilder.h"
|
||||
#include "Utils/CSClassUtilities.h"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wextern-initializer"
|
||||
#endif
|
||||
|
||||
namespace ReflectionHelper
|
||||
{
|
||||
extern inline FName Records = FName(TEXT("Records"));
|
||||
extern inline FString RootPrefix = TEXT("ICH-");
|
||||
}
|
||||
|
||||
void UCSActorExtensions::AddReplicatedSubObject(AActor* Actor, UObject* SubObject, ELifetimeCondition NetCondition)
|
||||
{
|
||||
Actor->AddReplicatedSubObject(SubObject, NetCondition);
|
||||
}
|
||||
|
||||
void UCSActorExtensions::RemoveReplicatedSubObject(AActor* Actor, UObject* SubObject)
|
||||
{
|
||||
Actor->RemoveReplicatedSubObject(SubObject);
|
||||
}
|
||||
|
||||
bool UCSActorExtensions::IsReplicatedSubObjectRegistered(AActor* Actor, UObject* SubObject)
|
||||
{
|
||||
return Actor->IsReplicatedSubObjectRegistered(SubObject);
|
||||
}
|
||||
|
||||
UActorComponent* UCSActorExtensions::GetComponentTemplate(const AActor* Actor, FName ComponentName)
|
||||
{
|
||||
if (!IsValid(Actor))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UBlueprintGeneratedClass* CurrentClass = FCSClassUtilities::GetFirstManagedClass(Actor->GetClass());
|
||||
while (IsValid(CurrentClass))
|
||||
{
|
||||
if (USimpleConstructionScript* SCS = CurrentClass->SimpleConstructionScript)
|
||||
{
|
||||
if (USCS_Node* Node = SCS->FindSCSNode(ComponentName))
|
||||
{
|
||||
return Node->ComponentTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
// If it's not our component, it's inherited and we need to create a new record for it
|
||||
if (UInheritableComponentHandler* InheritableComponentHandler = CurrentClass->GetInheritableComponentHandler(true))
|
||||
{
|
||||
#if WITH_EDITOR
|
||||
if (GIsEditor)
|
||||
{
|
||||
UBlueprint* Blueprint = static_cast<UBlueprint*>(CurrentClass->ClassGeneratedBy);
|
||||
Blueprint->InheritableComponentHandler = InheritableComponentHandler;
|
||||
}
|
||||
#endif
|
||||
|
||||
FComponentKey ComponentKey = InheritableComponentHandler->FindKey(ComponentName);
|
||||
|
||||
if (UActorComponent* ComponentTemplate = InheritableComponentHandler->GetOverridenComponentTemplate(ComponentKey))
|
||||
{
|
||||
return ComponentTemplate;
|
||||
}
|
||||
|
||||
USCS_Node* OriginalTemplate = nullptr;
|
||||
for (UBlueprintGeneratedClass* SCSClass = CurrentClass; SCSClass; SCSClass = Cast<UBlueprintGeneratedClass>(SCSClass->GetSuperClass()))
|
||||
{
|
||||
if (USimpleConstructionScript* SCS = SCSClass->SimpleConstructionScript)
|
||||
{
|
||||
OriginalTemplate = SCS->FindSCSNode(ComponentName);
|
||||
if (OriginalTemplate)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OriginalTemplate)
|
||||
{
|
||||
static UClass* HandlerClass = UInheritableComponentHandler::StaticClass();
|
||||
static FArrayProperty* RecordsArray = FindFieldChecked<FArrayProperty>(HandlerClass, ReflectionHelper::Records);
|
||||
|
||||
FScriptArrayHelper_InContainer ArrayHelper(RecordsArray, InheritableComponentHandler);
|
||||
int32 NewIndex = ArrayHelper.AddValue();
|
||||
FComponentOverrideRecord* NewRecord = reinterpret_cast<FComponentOverrideRecord*>(ArrayHelper.GetRawPtr(NewIndex));
|
||||
|
||||
CreateNewRecord(InheritableComponentHandler, FComponentKey(OriginalTemplate), NewRecord);
|
||||
return NewRecord->ComponentTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentClass = Cast<UBlueprintGeneratedClass>(CurrentClass->GetSuperClass());
|
||||
}
|
||||
|
||||
UE_LOG(LogUnrealSharp, Error, TEXT("Component %s not found in actor %s. Should not happen to DefaultComponents"), *ComponentName.ToString(), *Actor->GetName());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FBox UCSActorExtensions::GetComponentsBoundingBox(const AActor* Actor, bool bNonColliding, bool bIncludeFromChildActors)
|
||||
{
|
||||
return Actor->GetComponentsBoundingBox(bNonColliding, bIncludeFromChildActors);
|
||||
}
|
||||
|
||||
void UCSActorExtensions::CreateNewRecord(const UInheritableComponentHandler* InheritableComponentHandler, const FComponentKey& Key, FComponentOverrideRecord* NewRecord)
|
||||
{
|
||||
UActorComponent* BestArchetype = FindBestArchetype(InheritableComponentHandler->GetOuter(), Key);
|
||||
FName NewComponentTemplateName = BestArchetype->GetFName();
|
||||
|
||||
if (USCS_Node* SCSNode = Key.FindSCSNode())
|
||||
{
|
||||
const USCS_Node* DefaultSceneRootNode = SCSNode->GetSCS()->GetDefaultSceneRootNode();
|
||||
if (SCSNode == DefaultSceneRootNode && BestArchetype == DefaultSceneRootNode->ComponentTemplate)
|
||||
{
|
||||
NewComponentTemplateName = *(ReflectionHelper::RootPrefix + BestArchetype->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
UObject* Outer = InheritableComponentHandler->GetOuter();
|
||||
constexpr EObjectFlags Flags = RF_ArchetypeObject | RF_Public | RF_InheritableComponentTemplate;
|
||||
UActorComponent* NewComponentTemplate = NewObject<UActorComponent>(Outer, BestArchetype->GetClass(), NewComponentTemplateName, Flags, BestArchetype);
|
||||
|
||||
NewRecord->ComponentKey = Key;
|
||||
NewRecord->ComponentClass = NewComponentTemplate->GetClass();
|
||||
NewRecord->ComponentTemplate = NewComponentTemplate;
|
||||
}
|
||||
|
||||
UActorComponent* UCSActorExtensions::FindBestArchetype(UObject* Outer, FComponentKey Key, FName TemplateName)
|
||||
{
|
||||
UActorComponent* ClosestArchetype = nullptr;
|
||||
UBlueprintGeneratedClass* MainClass = Cast<UBlueprintGeneratedClass>(Outer);
|
||||
|
||||
if (MainClass && Key.GetComponentOwner() && MainClass != Key.GetComponentOwner())
|
||||
{
|
||||
while (!ClosestArchetype && MainClass)
|
||||
{
|
||||
if (MainClass->InheritableComponentHandler)
|
||||
{
|
||||
ClosestArchetype = MainClass->InheritableComponentHandler->GetOverridenComponentTemplate(Key);
|
||||
}
|
||||
|
||||
MainClass = Cast<UBlueprintGeneratedClass>(MainClass->GetSuperClass());
|
||||
}
|
||||
|
||||
if (!ClosestArchetype)
|
||||
{
|
||||
ClosestArchetype = Key.GetOriginalTemplate(TemplateName);
|
||||
}
|
||||
}
|
||||
|
||||
return ClosestArchetype;
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSActorExtensions.generated.h"
|
||||
|
||||
struct FComponentOverrideRecord;
|
||||
struct FComponentKey;
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSActorExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void AddReplicatedSubObject(AActor* Actor, UObject* SubObject, ELifetimeCondition NetCondition);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void RemoveReplicatedSubObject(AActor* Actor, UObject* SubObject);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsReplicatedSubObjectRegistered(AActor* Actor, UObject* SubObject);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static UActorComponent* GetComponentTemplate(const AActor* Actor, FName ComponentName);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FBox GetComponentsBoundingBox(const AActor* Actor, bool bNonColliding = false, bool bIncludeFromChildActors = false);
|
||||
|
||||
public:
|
||||
static void CreateNewRecord(const UInheritableComponentHandler* InheritableComponentHandler, const FComponentKey& Key, FComponentOverrideRecord* NewRecord);
|
||||
static UActorComponent* FindBestArchetype(UObject* Outer, FComponentKey Key, FName TemplateName = NAME_None);
|
||||
};
|
||||
@ -0,0 +1,23 @@
|
||||
#include "CSDataTableExtensions.h"
|
||||
|
||||
#if WITH_EDITOR
|
||||
FString UCSDataTableExtensions::GetTableAsJSON(const UDataTable* DataTable)
|
||||
{
|
||||
if (!IsValid(DataTable))
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
return DataTable->GetTableAsJSON();
|
||||
}
|
||||
|
||||
FString UCSDataTableExtensions::GetTableAsCSV(const UDataTable* DataTable)
|
||||
{
|
||||
if (!IsValid(DataTable))
|
||||
{
|
||||
return FString();
|
||||
}
|
||||
|
||||
return DataTable->GetTableAsCSV();
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSDataTableExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSDataTableExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
#if WITH_EDITOR
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FString GetTableAsJSON(const UDataTable* DataTable);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FString GetTableAsCSV(const UDataTable* DataTable);
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -0,0 +1,120 @@
|
||||
#include "CSGameplayTagContainerExtensions.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::HasTag(const FGameplayTagContainer& Container, const FGameplayTag& Tag)
|
||||
{
|
||||
return Container.HasTag(Tag);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::HasTagExact(const FGameplayTagContainer& Container, const FGameplayTag& Tag)
|
||||
{
|
||||
return Container.HasTagExact(Tag);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::HasAny(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Container.HasAny(Tags);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::HasAnyExact(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Container.HasAnyExact(Tags);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::HasAll(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Container.HasAll(Tags);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::HasAllExact(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Container.HasAllExact(Tags);
|
||||
}
|
||||
|
||||
int32 UCSGameplayTagContainerExtensions::Num(const FGameplayTagContainer& Container)
|
||||
{
|
||||
return Container.Num();
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::IsValid(const FGameplayTagContainer& Container)
|
||||
{
|
||||
return Container.IsValid();
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::IsEmpty(const FGameplayTagContainer& Container)
|
||||
{
|
||||
return Container.IsEmpty();
|
||||
}
|
||||
|
||||
FGameplayTagContainer UCSGameplayTagContainerExtensions::Filter(const FGameplayTagContainer& Container,
|
||||
const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Container.Filter(Tags);
|
||||
}
|
||||
|
||||
FGameplayTagContainer UCSGameplayTagContainerExtensions::FilterExact(const FGameplayTagContainer& Container,
|
||||
const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Container.FilterExact(Tags);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagContainerExtensions::MatchesQuery(const FGameplayTagContainer& Container, const FGameplayTagQuery& Query)
|
||||
{
|
||||
return Container.MatchesQuery(Query);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::AppendTags(FGameplayTagContainer& Container, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
Container.AppendTags(Tags);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::AppendMatchingTags(FGameplayTagContainer& Container, const FGameplayTagContainer& OtherA,
|
||||
const FGameplayTagContainer& OtherB)
|
||||
{
|
||||
Container.AppendMatchingTags(OtherA, OtherB);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::AddTag(FGameplayTagContainer& Container, const FGameplayTag& Tag)
|
||||
{
|
||||
Container.AddTag(Tag);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::AddTagFast(FGameplayTagContainer& Container, const FGameplayTag& Tag)
|
||||
{
|
||||
Container.AddTagFast(Tag);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::AddLeafTag(FGameplayTagContainer& Container, const FGameplayTag& Tag)
|
||||
{
|
||||
Container.AddLeafTag(Tag);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::RemoveTag(FGameplayTagContainer& Container, const FGameplayTag& Tag)
|
||||
{
|
||||
Container.RemoveTag(Tag);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::RemoveTags(FGameplayTagContainer& Container, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
Container.RemoveTags(Tags);
|
||||
}
|
||||
|
||||
void UCSGameplayTagContainerExtensions::Reset(FGameplayTagContainer& Container)
|
||||
{
|
||||
Container.Reset();
|
||||
}
|
||||
|
||||
FGameplayTag UCSGameplayTagContainerExtensions::First(const FGameplayTagContainer& Container)
|
||||
{
|
||||
return Container.First();
|
||||
}
|
||||
|
||||
FGameplayTag UCSGameplayTagContainerExtensions::Last(const FGameplayTagContainer& Container)
|
||||
{
|
||||
return Container.Last();
|
||||
}
|
||||
|
||||
FString UCSGameplayTagContainerExtensions::ToString(const FGameplayTagContainer& Container)
|
||||
{
|
||||
return Container.ToString();
|
||||
}
|
||||
@ -0,0 +1,217 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSGameplayTagContainerExtensions.generated.h"
|
||||
|
||||
struct FGameplayTag;
|
||||
struct FGameplayTagContainer;
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSGameplayTagContainerExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Determine if TagToCheck is present in this container, also checking against parent tags
|
||||
* {"A.1"}.HasTag("A") will return True, {"A"}.HasTag("A.1") will return False
|
||||
* If TagToCheck is not Valid it will always return False
|
||||
*
|
||||
* @return True if TagToCheck is in this container, false if it is not
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool HasTag(const FGameplayTagContainer& Container, const FGameplayTag& Tag);
|
||||
|
||||
/**
|
||||
* Determine if TagToCheck is explicitly present in this container, only allowing exact matches
|
||||
* {"A.1"}.HasTagExact("A") will return False
|
||||
* If TagToCheck is not Valid it will always return False
|
||||
*
|
||||
* @return True if TagToCheck is in this container, false if it is not
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool HasTagExact(const FGameplayTagContainer& Container, const FGameplayTag& Tag);
|
||||
|
||||
/**
|
||||
* Checks if this container contains ANY of the tags in the specified container, also checks against parent tags
|
||||
* {"A.1"}.HasAny({"A","B"}) will return True, {"A"}.HasAny({"A.1","B"}) will return False
|
||||
* If ContainerToCheck is empty/invalid it will always return False
|
||||
*
|
||||
* @return True if this container has ANY of the tags of in ContainerToCheck
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool HasAny(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Checks if this container contains ANY of the tags in the specified container, only allowing exact matches
|
||||
* {"A.1"}.HasAny({"A","B"}) will return False
|
||||
* If ContainerToCheck is empty/invalid it will always return False
|
||||
*
|
||||
* @return True if this container has ANY of the tags of in ContainerToCheck
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool HasAnyExact(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Checks if this container contains ALL of the tags in the specified container, also checks against parent tags
|
||||
* {"A.1","B.1"}.HasAll({"A","B"}) will return True, {"A","B"}.HasAll({"A.1","B.1"}) will return False
|
||||
* If ContainerToCheck is empty/invalid it will always return True, because there were no failed checks
|
||||
*
|
||||
* @return True if this container has ALL of the tags of in ContainerToCheck, including if ContainerToCheck is empty
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool HasAll(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Checks if this container contains ALL of the tags in the specified container, only allowing exact matches
|
||||
* {"A.1","B.1"}.HasAll({"A","B"}) will return False
|
||||
* If ContainerToCheck is empty/invalid it will always return True, because there were no failed checks
|
||||
*
|
||||
* @return True if this container has ALL of the tags of in ContainerToCheck, including if ContainerToCheck is empty
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool HasAllExact(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/** Returns the number of explicitly added tags */
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static int32 Num(const FGameplayTagContainer& Container);
|
||||
|
||||
/** Returns whether the container has any valid tags */
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsValid(const FGameplayTagContainer& Container);
|
||||
|
||||
/** Returns true if container is empty */
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsEmpty(const FGameplayTagContainer& Container);
|
||||
|
||||
/**
|
||||
* Returns a filtered version of this container, returns all tags that match against any of the tags in OtherContainer, expanding parents
|
||||
*
|
||||
* @param OtherContainer The Container to filter against
|
||||
*
|
||||
* @return A FGameplayTagContainer containing the filtered tags
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static FGameplayTagContainer Filter(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Returns a filtered version of this container, returns all tags that match exactly one in OtherContainer
|
||||
*
|
||||
* @param OtherContainer The Container to filter against
|
||||
*
|
||||
* @return A FGameplayTagContainer containing the filtered tags
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static FGameplayTagContainer FilterExact(const FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Checks if this container matches the given query.
|
||||
*
|
||||
* @param Query Query we are checking against
|
||||
*
|
||||
* @return True if this container matches the query, false otherwise.
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool MatchesQuery(const FGameplayTagContainer& Container, const FGameplayTagQuery& Query);
|
||||
|
||||
/**
|
||||
* Adds all the tags from one container to this container
|
||||
* NOTE: From set theory, this effectively is the union of the container this is called on with Other.
|
||||
*
|
||||
* @param Other TagContainer that has the tags you want to add to this container
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void AppendTags(UPARAM(ref) FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Adds all the tags that match between the two specified containers to this container. WARNING: This matches any
|
||||
* parent tag in A, not just exact matches! So while this should be the union of the container this is called on with
|
||||
* the intersection of OtherA and OtherB, it's not exactly that. Since OtherB matches against its parents, any tag
|
||||
* in OtherA which has a parent match with a parent of OtherB will count. For example, if OtherA has Color.Green
|
||||
* and OtherB has Color.Red, that will count as a match due to the Color parent match!
|
||||
* If you want an exact match, you need to call A.FilterExact(B) (above) to get the intersection of A with B.
|
||||
* If you need the disjunctive union (the union of two sets minus their intersection), use AppendTags to create
|
||||
* Union, FilterExact to create Intersection, and then call Union.RemoveTags(Intersection).
|
||||
*
|
||||
* @param OtherA TagContainer that has the matching tags you want to add to this container, these tags have their parents expanded
|
||||
* @param OtherB TagContainer used to check for matching tags. If the tag matches on any parent, it counts as a match.
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void AppendMatchingTags(UPARAM(ref) FGameplayTagContainer& Container, const FGameplayTagContainer& OtherA, const FGameplayTagContainer& OtherB);
|
||||
|
||||
/**
|
||||
* Add the specified tag to the container
|
||||
*
|
||||
* @param TagToAdd Tag to add to the container
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void AddTag(UPARAM(ref) FGameplayTagContainer& Container, const FGameplayTag& Tag);
|
||||
|
||||
/**
|
||||
* Add the specified tag to the container without checking for uniqueness
|
||||
*
|
||||
* @param TagToAdd Tag to add to the container
|
||||
*
|
||||
* Useful when building container from another data struct (TMap for example)
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void AddTagFast(UPARAM(ref) FGameplayTagContainer& Container, const FGameplayTag& Tag);
|
||||
|
||||
/**
|
||||
* Adds a tag to the container and removes any direct parents, wont add if child already exists
|
||||
*
|
||||
* @param Tag The tag to try and add to this container
|
||||
*
|
||||
* @return True if tag was added
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void AddLeafTag(UPARAM(ref) FGameplayTagContainer& Container, const FGameplayTag& Tag);
|
||||
|
||||
/**
|
||||
* Tag to remove from the container
|
||||
*
|
||||
* @param TagToRemove Tag to remove from the container
|
||||
* @param bDeferParentTags Skip calling FillParentTags for performance (must be handled by calling code)
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void RemoveTag(UPARAM(ref) FGameplayTagContainer& Container, const FGameplayTag& Tag);
|
||||
|
||||
/**
|
||||
* Removes all tags in TagsToRemove from this container
|
||||
*
|
||||
* @param TagsToRemove Tags to remove from the container
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void RemoveTags(UPARAM(ref) FGameplayTagContainer& Container, const FGameplayTagContainer& Tags);
|
||||
|
||||
/** Remove all tags from the container. Will maintain slack by default */
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void Reset(UPARAM(ref) FGameplayTagContainer& Container);
|
||||
|
||||
/**
|
||||
* Returns the first tag in the container
|
||||
*
|
||||
* @return The first tag in the container
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
static FGameplayTag First(const FGameplayTagContainer& Container);
|
||||
|
||||
/**
|
||||
* Returns the last tag in the container
|
||||
*
|
||||
* @return The last tag in the container
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
static FGameplayTag Last(const FGameplayTagContainer& Container);
|
||||
|
||||
/**
|
||||
* Returns a string representation of the container
|
||||
*
|
||||
* @return A string representation of the container
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
static FString ToString(const FGameplayTagContainer& Container);
|
||||
|
||||
};
|
||||
@ -0,0 +1,47 @@
|
||||
#include "CSGameplayTagExtensions.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
|
||||
bool UCSGameplayTagExtensions::MatchesTag(const FGameplayTag& Tag, const FGameplayTag& Other)
|
||||
{
|
||||
return Tag.MatchesTag(Other);
|
||||
}
|
||||
|
||||
int32 UCSGameplayTagExtensions::MatchesTagDepth(const FGameplayTag& Tag, const FGameplayTag& Other)
|
||||
{
|
||||
return Tag.MatchesTagDepth(Other);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagExtensions::MatchesAny(const FGameplayTag& Tag, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Tag.MatchesAny(Tags);
|
||||
}
|
||||
|
||||
bool UCSGameplayTagExtensions::MatchesAnyExact(const FGameplayTag& Tag, const FGameplayTagContainer& Tags)
|
||||
{
|
||||
return Tag.MatchesAnyExact(Tags);
|
||||
}
|
||||
|
||||
FGameplayTag UCSGameplayTagExtensions::RequestGameplayTag(const FName TagName)
|
||||
{
|
||||
return FGameplayTag::RequestGameplayTag(TagName);
|
||||
}
|
||||
|
||||
FName UCSGameplayTagExtensions::GetTagLeafName(const FGameplayTag Tag)
|
||||
{
|
||||
return Tag.GetTagLeafName();
|
||||
}
|
||||
|
||||
FGameplayTag UCSGameplayTagExtensions::RequestDirectParent(const FGameplayTag Tag)
|
||||
{
|
||||
return Tag.RequestDirectParent();
|
||||
}
|
||||
|
||||
FGameplayTagContainer UCSGameplayTagExtensions::GetGameplayTagParents(const FGameplayTag Tag)
|
||||
{
|
||||
return Tag.GetGameplayTagParents();
|
||||
}
|
||||
|
||||
FGameplayTagContainer UCSGameplayTagExtensions::GetSingleTagContainer(const FGameplayTag Tag)
|
||||
{
|
||||
return Tag.GetSingleTagContainer();
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameplayTagContainer.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSGameplayTagExtensions.generated.h"
|
||||
|
||||
struct FGameplayTag;
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSGameplayTagExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Determine if this tag matches TagToCheck, expanding our parent tags
|
||||
* "A.1".MatchesTag("A") will return True, "A".MatchesTag("A.1") will return False
|
||||
* If TagToCheck is not Valid it will always return False
|
||||
*
|
||||
* @return True if this tag matches TagToCheck
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool MatchesTag(const FGameplayTag& Tag, const FGameplayTag& Other);
|
||||
|
||||
/**
|
||||
* Check to see how closely two FGameplayTags match. Higher values indicate more matching terms in the tags.
|
||||
*
|
||||
* @param TagToCheck Tag to match against
|
||||
*
|
||||
* @return The depth of the match, higher means they are closer to an exact match
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static int32 MatchesTagDepth(const FGameplayTag& Tag, const FGameplayTag& Other);
|
||||
|
||||
/**
|
||||
* Checks if this tag matches ANY of the tags in the specified container, also checks against our parent tags
|
||||
* "A.1".MatchesAny({"A","B"}) will return True, "A".MatchesAny({"A.1","B"}) will return False
|
||||
* If ContainerToCheck is empty/invalid it will always return False
|
||||
*
|
||||
* @return True if this tag matches ANY of the tags of in ContainerToCheck
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool MatchesAny(const FGameplayTag& Tag, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Checks if this tag matches ANY of the tags in the specified container, only allowing exact matches
|
||||
* "A.1".MatchesAny({"A","B"}) will return False
|
||||
* If ContainerToCheck is empty/invalid it will always return False
|
||||
*
|
||||
* @return True if this tag matches ANY of the tags of in ContainerToCheck exactly
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static bool MatchesAnyExact(const FGameplayTag& Tag, const FGameplayTagContainer& Tags);
|
||||
|
||||
/**
|
||||
* Gets the FGameplayTag that corresponds to the TagName
|
||||
*
|
||||
* @param TagName The Name of the tag to search for
|
||||
* @param ErrorIfNotfound: ensure() that tag exists.
|
||||
* @return Will return the corresponding FGameplayTag or an empty one if not found.
|
||||
*/
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FGameplayTag RequestGameplayTag(const FName TagName);
|
||||
|
||||
/**
|
||||
* Parses the tag name and returns the name of the leaf.
|
||||
* For example, calling this on x.y.z would return the z component.
|
||||
*
|
||||
* @param Tag The gameplay tag to call on
|
||||
* @return The leaf tag for the passed tag
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static FName GetTagLeafName(const FGameplayTag Tag);
|
||||
|
||||
/**
|
||||
* Returns direct parent GameplayTag of this GameplayTag, calling on x.y will return x
|
||||
* @param Tag The gameplay tag to call on
|
||||
* @return The tags direct parent
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static FGameplayTag RequestDirectParent(const FGameplayTag Tag);
|
||||
|
||||
/**
|
||||
* Returns a new tag container that includes this tag and all parent tags as explicitly added tags. For example,
|
||||
* calling this on x.y.z would return a tag container with x.y.z, x.y, and x
|
||||
*
|
||||
* @param Tag The gameplay tag to call on
|
||||
* @return The collection of all tag parents
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static FGameplayTagContainer GetGameplayTagParents(const FGameplayTag Tag);
|
||||
|
||||
/**
|
||||
* Returns a GameplayTagContainer containing only this tag.
|
||||
*
|
||||
* @param Tag The gameplay tag to call on
|
||||
* @return A GameplayTagContainer containing only this tag.
|
||||
*/
|
||||
UFUNCTION(meta=(ExtensionMethod, ScriptMethod))
|
||||
static FGameplayTagContainer GetSingleTagContainer(const FGameplayTag Tag);
|
||||
|
||||
};
|
||||
@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSInputEventExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSInputEventExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRepeat(const FInputEvent& KeyEvent) { return KeyEvent.IsRepeat(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsShiftDown(const FInputEvent& KeyEvent) { return KeyEvent.IsShiftDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftShiftDown(const FInputEvent& KeyEvent) { return KeyEvent.IsLeftShiftDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightShiftDown(const FInputEvent& KeyEvent) { return KeyEvent.IsRightShiftDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsControlDown(const FInputEvent& KeyEvent) { return KeyEvent.IsControlDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftControlDown(const FInputEvent& KeyEvent) { return KeyEvent.IsLeftControlDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightControlDown(const FInputEvent& KeyEvent) { return KeyEvent.IsRightControlDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsAltDown(const FInputEvent& KeyEvent) { return KeyEvent.IsAltDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftAltDown(const FInputEvent& KeyEvent) { return KeyEvent.IsLeftAltDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightAltDown(const FInputEvent& KeyEvent) { return KeyEvent.IsRightAltDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsCommandDown(const FInputEvent& KeyEvent) { return KeyEvent.IsCommandDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftCommandDown(const FInputEvent& KeyEvent) { return KeyEvent.IsLeftCommandDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightCommandDown(const FInputEvent& KeyEvent) { return KeyEvent.IsRightCommandDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool AreCapsLocked(const FInputEvent& KeyEvent) { return KeyEvent.AreCapsLocked(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static uint32 GetUserIndex(const FInputEvent& KeyEvent) { return KeyEvent.GetUserIndex(); }
|
||||
};
|
||||
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSKeyEventExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSKeyEventExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FKey GetKey(const FKeyEvent& KeyEvent) { return KeyEvent.GetKey(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static uint32 GetCharacter(const FKeyEvent& KeyEvent) { return KeyEvent.GetCharacter(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static uint32 GetKeyCode(const FKeyEvent& KeyEvent) { return KeyEvent.GetKeyCode(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FText ToText(const FKeyEvent& KeyEvent) { return KeyEvent.ToText(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsKeyEvent(const FKeyEvent& KeyEvent) { return KeyEvent.IsKeyEvent(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRepeat(const FKeyEvent& KeyEvent) { return KeyEvent.IsRepeat(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsShiftDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsShiftDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftShiftDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsLeftShiftDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightShiftDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsRightShiftDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsControlDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsControlDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftControlDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsLeftControlDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightControlDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsRightControlDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsAltDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsAltDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftAltDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsLeftAltDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightAltDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsRightAltDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsCommandDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsCommandDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsLeftCommandDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsLeftCommandDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsRightCommandDown(const FKeyEvent& KeyEvent) { return KeyEvent.IsRightCommandDown(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool AreCapsLocked(const FKeyEvent& KeyEvent) { return KeyEvent.AreCapsLocked(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static uint32 GetUserIndex(const FKeyEvent& KeyEvent) { return KeyEvent.GetUserIndex(); }
|
||||
};
|
||||
@ -0,0 +1,71 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSKeyExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSKeyExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsValid(const FKey& Key) { return Key.IsValid(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsModifierKey(const FKey& Key) { return Key.IsModifierKey(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsGamepadKey(const FKey& Key) { return Key.IsGamepadKey(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsTouch(const FKey& Key) { return Key.IsTouch(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsMouseButton(const FKey& Key) { return Key.IsMouseButton(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsButtonAxis(const FKey& Key) { return Key.IsButtonAxis(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsAxis1D(const FKey& Key) { return Key.IsAxis1D(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsAxis2D(const FKey& Key) { return Key.IsAxis2D(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsAxis3D(const FKey& Key) { return Key.IsAxis3D(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsDigital(const FKey& Key) { return Key.IsDigital(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsAnalog(const FKey& Key) { return Key.IsAnalog(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsBindableInBlueprints(const FKey& Key) { return Key.IsBindableInBlueprints(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool ShouldUpdateAxisWithoutSamples(const FKey& Key) { return Key.ShouldUpdateAxisWithoutSamples(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsBindableToActions(const FKey& Key) { return Key.IsBindableToActions(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsDeprecated(const FKey& Key) { return Key.IsDeprecated(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsGesture(const FKey& Key) { return Key.IsGesture(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FText GetDisplayName(const FKey& Key, bool bLongDisplayName = true) { return Key.GetDisplayName(bLongDisplayName); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FString ToString(const FKey& Key) { return Key.ToString(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FName GetMenuCategory(const FKey& Key) { return Key.GetMenuCategory(); }
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static FKey GetPairedAxisKey(const FKey& Key) { return Key.GetPairedAxisKey(); }
|
||||
};
|
||||
@ -0,0 +1,42 @@
|
||||
#include "CSMovementComponentExtensions.h"
|
||||
#include "GameFramework/MovementComponent.h"
|
||||
|
||||
float UCSMovementComponentExtensions::SlideAlongSurface(UMovementComponent* MovementComponent, const FVector& Delta, float Time, const FVector& Normal, UPARAM(ref) FHitResult& Hit, bool bHandleImpact)
|
||||
{
|
||||
return MovementComponent->SlideAlongSurface(Delta, Time, Normal, Hit, bHandleImpact);
|
||||
}
|
||||
|
||||
FVector UCSMovementComponentExtensions::ComputeSlideVector(UMovementComponent* MovementComponent, const FVector& Delta, const float Time, const FVector& Normal, const FHitResult& Hit)
|
||||
{
|
||||
return MovementComponent->ComputeSlideVector(Delta, Time, Normal, Hit);
|
||||
}
|
||||
|
||||
void UCSMovementComponentExtensions::TwoWallAdjust(UMovementComponent* MovementComponent, UPARAM(ref) FVector& Delta, const FHitResult& Hit, const FVector& OldHitNormal)
|
||||
{
|
||||
MovementComponent->TwoWallAdjust(Delta, Hit, OldHitNormal);
|
||||
}
|
||||
|
||||
bool UCSMovementComponentExtensions::SafeMoveUpdatedComponentQuat(UMovementComponent* MovementComponent, const FVector& Delta, const FQuat& NewRotation, bool bSweep, FHitResult& OutHit, ETeleportType Teleport)
|
||||
{
|
||||
return MovementComponent->SafeMoveUpdatedComponent(Delta, NewRotation, bSweep, OutHit, Teleport);
|
||||
}
|
||||
|
||||
bool UCSMovementComponentExtensions::SafeMoveUpdatedComponentRotator(UMovementComponent* MovementComponent, const FVector& Delta, const FRotator& NewRotation, bool bSweep, FHitResult& OutHit, ETeleportType Teleport)
|
||||
{
|
||||
return MovementComponent->SafeMoveUpdatedComponent(Delta, NewRotation, bSweep, OutHit, Teleport);
|
||||
}
|
||||
|
||||
bool UCSMovementComponentExtensions::ResolvePenetrationQuat(UMovementComponent* MovementComponent, const FVector& Adjustment, const FHitResult& Hit, const FQuat& NewRotation)
|
||||
{
|
||||
return MovementComponent->ResolvePenetration(Adjustment, Hit, NewRotation);
|
||||
}
|
||||
|
||||
bool UCSMovementComponentExtensions::ResolvePenetrationRotator(UMovementComponent* MovementComponent, const FVector& Adjustment, const FHitResult& Hit, const FRotator& NewRotation)
|
||||
{
|
||||
return MovementComponent->ResolvePenetration(Adjustment, Hit, NewRotation);
|
||||
}
|
||||
|
||||
void UCSMovementComponentExtensions::UpdateComponentVelocity(UMovementComponent* MovementComponent)
|
||||
{
|
||||
MovementComponent->UpdateComponentVelocity();
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSMovementComponentExtensions.generated.h"
|
||||
|
||||
class UMovementComponent;
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSMovementComponentExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Slide smoothly along a surface, and slide away from multiple impacts using TwoWallAdjust if necessary. Calls HandleImpact for each surface hit, if requested.
|
||||
* Uses SafeMoveUpdatedComponent() for movement, and ComputeSlideVector() to determine the slide direction.
|
||||
* @param Delta: Attempted movement vector.
|
||||
* @param Time: Percent of Delta to apply (between 0 and 1). Usually equal to the remaining time after a collision: (1.0 - Hit.Time).
|
||||
* @param Normal: Normal opposing movement, along which we will slide.
|
||||
* @param Hit: [In] HitResult of the attempted move that resulted in the impact triggering the slide. [Out] HitResult of last attempted move.
|
||||
* @param bHandleImpact: Whether to call HandleImpact on each hit.
|
||||
* @return The percentage of requested distance (Delta * Percent) actually applied (between 0 and 1). 0 if no movement occurred, non-zero if movement occurred.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static float SlideAlongSurface(UMovementComponent* MovementComponent, const FVector& Delta, float Time, const FVector& Normal, UPARAM(ref) FHitResult& Hit, bool bHandleImpact = false);
|
||||
|
||||
/**
|
||||
* Compute a vector to slide along a surface, given an attempted move, time, and normal.
|
||||
* @param Delta: Attempted move.
|
||||
* @param Time: Amount of move to apply (between 0 and 1).
|
||||
* @param Normal: Normal opposed to movement. Not necessarily equal to Hit.Normal.
|
||||
* @param Hit: HitResult of the move that resulted in the slide.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static FVector ComputeSlideVector(UMovementComponent* MovementComponent, const FVector& Delta, const float Time, const FVector& Normal, const FHitResult& Hit);
|
||||
|
||||
/**
|
||||
* Compute a movement direction when contacting two surfaces.
|
||||
* @param Delta: [In] Amount of move attempted before impact. [Out] Computed adjustment based on impacts.
|
||||
* @param Hit: Impact from last attempted move
|
||||
* @param OldHitNormal: Normal of impact before last attempted move
|
||||
* @return Result in Delta that is the direction to move when contacting two surfaces.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static void TwoWallAdjust(UMovementComponent* MovementComponent, UPARAM(ref) FVector& Delta, const FHitResult& Hit, const FVector& OldHitNormal);
|
||||
|
||||
/**
|
||||
* Calls MoveUpdatedComponent(), handling initial penetrations by calling ResolvePenetration().
|
||||
* If this adjustment succeeds, the original movement will be attempted again.
|
||||
* @note The overload taking rotation as an FQuat is slightly faster than the version using FRotator (which will be converted to an FQuat).
|
||||
* @note The 'Teleport' flag is currently always treated as 'None' (not teleporting) when used in an active FScopedMovementUpdate.
|
||||
* @return result of the final MoveUpdatedComponent() call.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static bool SafeMoveUpdatedComponentQuat(UMovementComponent* MovementComponent, const FVector& Delta, const FQuat& NewRotation, bool bSweep, UPARAM(ref) FHitResult& OutHit, ETeleportType Teleport = ETeleportType::None);
|
||||
|
||||
/**
|
||||
* Calls MoveUpdatedComponent(), handling initial penetrations by calling ResolvePenetration().
|
||||
* If this adjustment succeeds, the original movement will be attempted again.
|
||||
* @note The overload taking rotation as an FQuat is slightly faster than the version using FRotator (which will be converted to an FQuat).
|
||||
* @note The 'Teleport' flag is currently always treated as 'None' (not teleporting) when used in an active FScopedMovementUpdate.
|
||||
* @return result of the final MoveUpdatedComponent() call.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static bool SafeMoveUpdatedComponentRotator(UMovementComponent* MovementComponent, const FVector& Delta, const FRotator& NewRotation, bool bSweep, UPARAM(ref) FHitResult& OutHit, ETeleportType Teleport = ETeleportType::None);
|
||||
|
||||
/**
|
||||
* Try to move out of penetration in an object after a failed move. This function should respect the plane constraint if applicable.
|
||||
* @note This simply calls the virtual ResolvePenetrationImpl() which can be overridden to implement custom behavior.
|
||||
* @note The overload taking rotation as an FQuat is slightly faster than the version using FRotator (which will be converted to an FQuat)..
|
||||
* @param Adjustment The requested adjustment, usually from GetPenetrationAdjustment()
|
||||
* @param Hit The result of the failed move
|
||||
* @return True if the adjustment was successful and the original move should be retried, or false if no repeated attempt should be made.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static bool ResolvePenetrationQuat(UMovementComponent* MovementComponent, const FVector& Adjustment, const FHitResult& Hit, const FQuat& NewRotation);
|
||||
|
||||
/**
|
||||
* Try to move out of penetration in an object after a failed move. This function should respect the plane constraint if applicable.
|
||||
* @note This simply calls the virtual ResolvePenetrationImpl() which can be overridden to implement custom behavior.
|
||||
* @note The overload taking rotation as an FQuat is slightly faster than the version using FRotator (which will be converted to an FQuat)..
|
||||
* @param Adjustment The requested adjustment, usually from GetPenetrationAdjustment()
|
||||
* @param Hit The result of the failed move
|
||||
* @return True if the adjustment was successful and the original move should be retried, or false if no repeated attempt should be made.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static bool ResolvePenetrationRotator(UMovementComponent* MovementComponent, const FVector& Adjustment, const FHitResult& Hit, const FRotator& NewRotation);
|
||||
|
||||
/** Update ComponentVelocity of UpdatedComponent. This needs to be called by derived classes at the end of an update whenever Velocity has changed. */
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static void UpdateComponentVelocity(UMovementComponent* MovementComponent);
|
||||
|
||||
};
|
||||
@ -0,0 +1,52 @@
|
||||
#include "CSObjectExtensions.h"
|
||||
|
||||
AWorldSettings* UCSObjectExtensions::GetWorldSettings(const UObject* Object)
|
||||
{
|
||||
if (!IsValid(Object) || !Object->GetWorld())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Object->GetWorld()->GetWorldSettings();
|
||||
}
|
||||
|
||||
void UCSObjectExtensions::MarkAsGarbage(UObject* Object)
|
||||
{
|
||||
if (!IsValid(Object))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Object->MarkAsGarbage();
|
||||
}
|
||||
|
||||
bool UCSObjectExtensions::IsTemplate(const UObject* Object)
|
||||
{
|
||||
if (!IsValid(Object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Object->IsTemplate();
|
||||
}
|
||||
|
||||
UClass* UCSObjectExtensions::K2_GetClass(const UObject* Object)
|
||||
{
|
||||
if (!IsValid(Object))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Object->GetClass();
|
||||
}
|
||||
|
||||
UObject* UCSObjectExtensions::GetOuter(const UObject* Object)
|
||||
{
|
||||
if (!IsValid(Object))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Object->GetOuter();
|
||||
}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSObjectExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSObjectExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static AWorldSettings* GetWorldSettings(const UObject* Object);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void MarkAsGarbage(UObject* Object);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static bool IsTemplate(const UObject* Object);
|
||||
|
||||
UFUNCTION(meta = (ScriptMethod))
|
||||
static UClass* K2_GetClass(const UObject* Object);
|
||||
|
||||
UFUNCTION(meta = (ScriptMethod))
|
||||
static UObject* GetOuter(const UObject* Object);
|
||||
};
|
||||
@ -0,0 +1,16 @@
|
||||
#include "CSPackageNameExtensions.h"
|
||||
|
||||
void UCSPackageNameExtensions::RegisterMountPoint(const FString& RootPath, const FString& ContentPath)
|
||||
{
|
||||
FPackageName::RegisterMountPoint(RootPath, ContentPath);
|
||||
}
|
||||
|
||||
void UCSPackageNameExtensions::UnRegisterMountPoint(const FString& RootPath, const FString& ContentPath)
|
||||
{
|
||||
FPackageName::UnRegisterMountPoint(RootPath, ContentPath);
|
||||
}
|
||||
|
||||
bool UCSPackageNameExtensions::MountPointExists(const FString& RootPath)
|
||||
{
|
||||
return FPackageName::MountPointExists(RootPath);
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSPackageNameExtensions.generated.h"
|
||||
|
||||
class UMovementComponent;
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSPackageNameExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* This will insert a mount point at the head of the search chain (so it can overlap an existing mount point and win).
|
||||
*
|
||||
* @param RootPath Logical Root Path.
|
||||
* @param ContentPath Content Path on disk.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static void RegisterMountPoint(const FString& RootPath, const FString& ContentPath);
|
||||
|
||||
/**
|
||||
* This will remove a previously inserted mount point.
|
||||
*
|
||||
* @param RootPath Logical Root Path.
|
||||
* @param ContentPath Content Path on disk.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static void UnRegisterMountPoint(const FString& RootPath, const FString& ContentPath);
|
||||
|
||||
/**
|
||||
* Returns whether the specific logical root path is a valid mount point.
|
||||
*/
|
||||
UFUNCTION(meta = (ExtensionMethod, ScriptMethod))
|
||||
static bool MountPointExists(const FString& RootPath);
|
||||
};
|
||||
@ -0,0 +1,11 @@
|
||||
#include "CSQuatExtensions.h"
|
||||
|
||||
void UCSQuatExtensions::ToQuaternion(FQuat& Quaternion, const FRotator& Rotator)
|
||||
{
|
||||
Quaternion = Rotator.Quaternion();
|
||||
}
|
||||
|
||||
void UCSQuatExtensions::ToRotator(FRotator& Rotator, const FQuat& Quaternion)
|
||||
{
|
||||
Rotator = Quaternion.Rotator();
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSQuatExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSQuatExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void ToQuaternion(FQuat& Quaternion, const FRotator& Rotator);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void ToRotator(FRotator& Rotator, const FQuat& Quaternion);
|
||||
};
|
||||
@ -0,0 +1,9 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "CSSoftObjectPathExtensions.h"
|
||||
|
||||
UObject* UCSSoftObjectPathExtensions::ResolveObject(const FSoftObjectPath& SoftObjectPath)
|
||||
{
|
||||
return SoftObjectPath.ResolveObject();
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSSoftObjectPathExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSSoftObjectPathExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static UObject* ResolveObject(const FSoftObjectPath& SoftObjectPath);
|
||||
};
|
||||
@ -0,0 +1,9 @@
|
||||
#include "CSSystemExtensions.h"
|
||||
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
void UCSSystemExtensions::PrintStringInternal(UObject* WorldContextObject, const FString& InString, bool bPrintToScreen,
|
||||
bool bPrintToLog, FLinearColor TextColor, float Duration, const FName Key)
|
||||
{
|
||||
UKismetSystemLibrary::PrintString(WorldContextObject, InString, bPrintToScreen, bPrintToLog, TextColor, Duration, Key);
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSSystemExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSSystemExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void PrintStringInternal(UObject* WorldContextObject, const FString& InString, bool bPrintToScreen, bool bPrintToLog,
|
||||
FLinearColor TextColor,
|
||||
float Duration,
|
||||
const FName Key);
|
||||
};
|
||||
@ -0,0 +1,52 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "CSUserWidgetExtensions.h"
|
||||
#include "GameFramework/PlayerState.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "Blueprint/WidgetBlueprintLibrary.h"
|
||||
|
||||
APlayerController* UCSUserWidgetExtensions::GetOwningPlayerController(UUserWidget* UserWidget)
|
||||
{
|
||||
if (!IsValid(UserWidget))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return UserWidget->GetOwningPlayer();
|
||||
}
|
||||
|
||||
void UCSUserWidgetExtensions::SetOwningPlayerController(UUserWidget* UserWidget, APlayerController* PlayerController)
|
||||
{
|
||||
if (!IsValid(UserWidget))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UserWidget->SetOwningPlayer(PlayerController);
|
||||
}
|
||||
|
||||
APlayerState* UCSUserWidgetExtensions::GetOwningPlayerState(UUserWidget* UserWidget)
|
||||
{
|
||||
if (!IsValid(UserWidget))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return UserWidget->GetOwningPlayerState<APlayerState>();
|
||||
}
|
||||
|
||||
ULocalPlayer* UCSUserWidgetExtensions::GetOwningLocalPlayer(UUserWidget* UserWidget)
|
||||
{
|
||||
if (!IsValid(UserWidget))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return UserWidget->GetOwningLocalPlayer();
|
||||
}
|
||||
|
||||
UUserWidget* UCSUserWidgetExtensions::CreateWidget(UObject* WorldContextObject, const TSubclassOf<UUserWidget>& UserWidgetClass, APlayerController* OwningController)
|
||||
{
|
||||
UUserWidget* UserWidget = UWidgetBlueprintLibrary::Create(WorldContextObject, UserWidgetClass, OwningController);
|
||||
return UserWidget;
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "CSUserWidgetExtensions.generated.h"
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSUserWidgetExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static APlayerController* GetOwningPlayerController(UUserWidget* UserWidget);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static void SetOwningPlayerController(UUserWidget* UserWidget, APlayerController* PlayerController);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static APlayerState* GetOwningPlayerState(UUserWidget* UserWidget);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod))
|
||||
static ULocalPlayer* GetOwningLocalPlayer(UUserWidget* UserWidget);
|
||||
|
||||
UFUNCTION(meta=(ScriptMethod, UserWidgetClass = "/Script/UMG.UserWidget", DeterminesOutputType = "UserWidgetClass"))
|
||||
static UUserWidget* CreateWidget(UObject* WorldContextObject, const TSubclassOf<UUserWidget>& UserWidgetClass, APlayerController* OwningController);
|
||||
};
|
||||
@ -0,0 +1,70 @@
|
||||
#include "CSWorldExtensions.h"
|
||||
#include "UnrealSharpCore.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
|
||||
AActor* UCSWorldExtensions::SpawnActor(const UObject* WorldContextObject, const TSubclassOf<AActor>& Class, const FTransform& Transform, const FCSSpawnActorParameters& InSpawnParameters)
|
||||
{
|
||||
return SpawnActor_Internal(WorldContextObject, Class, Transform, InSpawnParameters, false);
|
||||
}
|
||||
|
||||
AActor* UCSWorldExtensions::SpawnActorDeferred(const UObject* WorldContextObject, const TSubclassOf<AActor>& Class, const FTransform& Transform, const FCSSpawnActorParameters& SpawnParameters)
|
||||
{
|
||||
return SpawnActor_Internal(WorldContextObject, Class, Transform, SpawnParameters, true);
|
||||
}
|
||||
|
||||
void UCSWorldExtensions::ExecuteConstruction(AActor* Actor, const FTransform& Transform)
|
||||
{
|
||||
Actor->ExecuteConstruction(Transform, nullptr, nullptr, true);
|
||||
}
|
||||
|
||||
void UCSWorldExtensions::PostActorConstruction(AActor* Actor)
|
||||
{
|
||||
Actor->PostActorConstruction();
|
||||
Actor->PostLoad();
|
||||
}
|
||||
|
||||
FURL UCSWorldExtensions::WorldURL(const UObject* WorldContextObject)
|
||||
{
|
||||
if (!IsValid(WorldContextObject))
|
||||
{
|
||||
UE_LOG(LogUnrealSharp, Error, TEXT("Invalid world context object"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||
|
||||
if (!IsValid(World))
|
||||
{
|
||||
UE_LOG(LogUnrealSharp, Error, TEXT("Failed to get world from context object"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return World->URL;
|
||||
}
|
||||
|
||||
AActor* UCSWorldExtensions::SpawnActor_Internal(const UObject* WorldContextObject, const TSubclassOf<AActor>& Class, const FTransform& Transform, const FCSSpawnActorParameters& SpawnParameters, bool bDeferConstruction)
|
||||
{
|
||||
if (!IsValid(WorldContextObject) || !IsValid(Class))
|
||||
{
|
||||
UE_LOG(LogUnrealSharp, Error, TEXT("Invalid world context object or class"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull);
|
||||
|
||||
if (!IsValid(World))
|
||||
{
|
||||
UE_LOG(LogUnrealSharp, Error, TEXT("Failed to get world from context object"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FActorSpawnParameters SpawnParams;
|
||||
SpawnParams.Instigator = SpawnParameters.Instigator;
|
||||
SpawnParams.Owner = SpawnParameters.Owner;
|
||||
SpawnParams.Template = SpawnParameters.Template;
|
||||
SpawnParams.SpawnCollisionHandlingOverride = SpawnParameters.SpawnMethod;
|
||||
SpawnParams.bDeferConstruction = bDeferConstruction;
|
||||
|
||||
return World->SpawnActor(Class, &Transform, SpawnParams);
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "CSWorldExtensions.generated.h"
|
||||
|
||||
USTRUCT()
|
||||
struct FCSSpawnActorParameters
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<AActor> Owner = nullptr;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<APawn> Instigator = nullptr;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<AActor> Template = nullptr;
|
||||
|
||||
UPROPERTY()
|
||||
ESpawnActorCollisionHandlingMethod SpawnMethod = ESpawnActorCollisionHandlingMethod::Undefined;
|
||||
};
|
||||
|
||||
UCLASS(meta = (InternalType))
|
||||
class UCSWorldExtensions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UFUNCTION(meta = (ScriptMethod))
|
||||
static AActor* SpawnActor(const UObject* WorldContextObject, const TSubclassOf<AActor>& Class, const FTransform& Transform, const FCSSpawnActorParameters& SpawnParameters);
|
||||
|
||||
UFUNCTION(meta = (ScriptMethod))
|
||||
static AActor* SpawnActorDeferred(const UObject* WorldContextObject, const TSubclassOf<AActor>& Class, const FTransform& Transform, const FCSSpawnActorParameters& SpawnParameters);
|
||||
|
||||
UFUNCTION(meta = (ScriptMethod))
|
||||
static void ExecuteConstruction(AActor* Actor, const FTransform& Transform);
|
||||
|
||||
UFUNCTION(meta = (ScriptMethod))
|
||||
static void PostActorConstruction(AActor* Actor);
|
||||
|
||||
UFUNCTION(meta = (ScriptMethod))
|
||||
static FURL WorldURL(const UObject* WorldContextObject);
|
||||
private:
|
||||
static AActor* SpawnActor_Internal(const UObject* WorldContextObject, const TSubclassOf<AActor>& Class, const FTransform& Transform, const FCSSpawnActorParameters& SpawnParameters, bool bDeferConstruction);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user