| @ -0,0 +1,6 @@ | ||||
| #include "CSBlueprintAsyncActionBase.h" | ||||
|  | ||||
| void UCSBlueprintAsyncActionBase::Activate() | ||||
| { | ||||
| 	ReceiveActivate(); | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| // Fill out your copyright notice in the Description page of Project Settings. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "Kismet/BlueprintAsyncActionBase.h" | ||||
| #include "CSBlueprintAsyncActionBase.generated.h" | ||||
|  | ||||
| UCLASS(Blueprintable, BlueprintType, Abstract) | ||||
| class UNREALSHARPCORE_API UCSBlueprintAsyncActionBase : public UBlueprintAsyncActionBase | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	// UBlueprintAsyncActionBase interface | ||||
| 	virtual void Activate() override; | ||||
| 	//~UBlueprintAsyncActionBase interface | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Activate")) | ||||
| 	void ReceiveActivate(); | ||||
|  | ||||
| }; | ||||
| @ -0,0 +1,24 @@ | ||||
| #include "CSCancellableAsyncAction.h" | ||||
|  | ||||
| void UCSCancellableAsyncAction::Activate() | ||||
| { | ||||
| 	ReceiveActivate(); | ||||
| 	 | ||||
| #if WITH_EDITOR | ||||
|     FEditorDelegates::PrePIEEnded.AddWeakLambda(this, [this](bool) | ||||
|     { | ||||
|         Cancel(); | ||||
|         FEditorDelegates::PrePIEEnded.RemoveAll(this); | ||||
|     }); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void UCSCancellableAsyncAction::Cancel() | ||||
| { | ||||
| 	if (HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject) || !IsValid(this) || IsUnreachable()) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	ReceiveCancel(); | ||||
| } | ||||
| @ -0,0 +1,29 @@ | ||||
| // Fill out your copyright notice in the Description page of Project Settings. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "Engine/CancellableAsyncAction.h" | ||||
| #include "CSCancellableAsyncAction.generated.h" | ||||
|  | ||||
| UCLASS(Blueprintable, BlueprintType, Abstract) | ||||
| class UNREALSHARPCORE_API UCSCancellableAsyncAction : public UCancellableAsyncAction | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	// Start UCancellableAsyncAction Functions | ||||
| 	virtual void Activate() override; | ||||
| 	virtual void Cancel() override; | ||||
| 	// End UCancellableAsyncAction Functions | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Activate")) | ||||
| 	void ReceiveActivate(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Cancel")) | ||||
| 	void ReceiveCancel(); | ||||
|  | ||||
| }; | ||||
| @ -0,0 +1,6 @@ | ||||
| #include "CSPrimaryDataAsset.h" | ||||
|  | ||||
| FPrimaryAssetId UCSPrimaryDataAsset::GetPrimaryAssetId() const | ||||
| { | ||||
| 	return FPrimaryAssetId(AssetName, GetFName()); | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "Engine/DataAsset.h" | ||||
| #include "CSPrimaryDataAsset.generated.h" | ||||
|  | ||||
| UCLASS() | ||||
| class UNREALSHARPCORE_API UCSPrimaryDataAsset : public UPrimaryDataAsset | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	// UPrimaryDataAsset interface implementation | ||||
| 	virtual FPrimaryAssetId GetPrimaryAssetId() const override; | ||||
| 	// End of implementation | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	// The name of the asset which AssetManager will use to identify this asset | ||||
| 	UPROPERTY(BlueprintReadWrite) | ||||
| 	FName AssetName; | ||||
| 	 | ||||
| }; | ||||
| @ -0,0 +1 @@ | ||||
| #include "CSDeveloperSettings.h" | ||||
| @ -0,0 +1,16 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "Engine/DeveloperSettings.h" | ||||
| #include "CSDeveloperSettings.generated.h" | ||||
|  | ||||
| UCLASS(Abstract) | ||||
| class UCSDeveloperSettings : public UDeveloperSettings | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
| #if WITH_EDITOR | ||||
| 	// UDeveloperSettings interface | ||||
| 	virtual bool SupportsAutoRegistration() const override { return false; } | ||||
| 	// End of UDeveloperSettings interface | ||||
| #endif | ||||
| }; | ||||
| @ -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); | ||||
| }; | ||||
|  | ||||
| @ -0,0 +1,74 @@ | ||||
| #include "CSReplicatedObject.h" | ||||
| #include "Engine/BlueprintGeneratedClass.h" | ||||
| #include "Runtime/Launch/Resources/Version.h" | ||||
| #include "UObject/Package.h" | ||||
| #include "Engine/NetDriver.h" | ||||
| #include "Engine/Engine.h" | ||||
|  | ||||
| UWorld* UCSReplicatedObject::GetWorld() const | ||||
| { | ||||
| 	if (GetOuter() == nullptr) | ||||
| 	{ | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 		 | ||||
| 	if (Cast<UPackage>(GetOuter()) != nullptr) | ||||
| 	{ | ||||
| 		return Cast<UWorld>(GetOuter()->GetOuter()); | ||||
| 	} | ||||
| 		 | ||||
| 	return GetOwningActor()->GetWorld(); | ||||
| } | ||||
|  | ||||
| void UCSReplicatedObject::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const | ||||
| { | ||||
| 	Super::GetLifetimeReplicatedProps(OutLifetimeProps); | ||||
| 	 | ||||
| 	if (UBlueprintGeneratedClass* BPCClass = Cast<UBlueprintGeneratedClass>(GetClass())) | ||||
| 	{ | ||||
| 		BPCClass->GetLifetimeBlueprintReplicationList(OutLifetimeProps); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool UCSReplicatedObject::IsSupportedForNetworking() const | ||||
| { | ||||
| 	return ReplicationState == ECSReplicationState::Replicates; | ||||
| } | ||||
|  | ||||
| int32 UCSReplicatedObject::GetFunctionCallspace(UFunction* Function, FFrame* Stack) | ||||
| { | ||||
| 	if (HasAnyFlags(RF_ClassDefaultObject) || !IsSupportedForNetworking()) | ||||
| 	{ | ||||
| 		return GEngine->GetGlobalFunctionCallspace(Function, this, Stack); | ||||
| 	} | ||||
| 	 | ||||
| 	return GetOuter()->GetFunctionCallspace(Function, Stack); | ||||
| } | ||||
|  | ||||
| bool UCSReplicatedObject::CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack) | ||||
| { | ||||
| 	AActor* Owner = GetOwningActor(); | ||||
| 	UNetDriver* NetDriver = Owner->GetNetDriver(); | ||||
| 	if (!IsValid(NetDriver)) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 	 | ||||
| 	NetDriver->ProcessRemoteFunction(Owner, Function, Parms, OutParms, Stack, this); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| AActor* UCSReplicatedObject::GetOwningActor() const | ||||
| { | ||||
| 	return GetTypedOuter<AActor>(); | ||||
| } | ||||
|  | ||||
| void UCSReplicatedObject::DestroyObject() | ||||
| { | ||||
| 	if (!IsValid(this)) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	MarkAsGarbage(); | ||||
| } | ||||
| @ -0,0 +1,48 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "UObject/Object.h" | ||||
| #include "CSReplicatedObject.generated.h" | ||||
|  | ||||
| UENUM(BlueprintType) | ||||
| enum ECSReplicationState | ||||
| { | ||||
| 	// This UObject is considered for replication. | ||||
| 	Replicates, | ||||
| 	// This UObject is not considered for replication. | ||||
| 	DoNotReplicate, | ||||
| }; | ||||
|  | ||||
| /**  | ||||
|  * This class provides support for replicated UObjects in C# | ||||
|  */ | ||||
| UCLASS(Blueprintable, BlueprintType, DisplayName = "Replicated UObject", Abstract) | ||||
| class UCSReplicatedObject : public UObject | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	// UObject interface implementation | ||||
| 	virtual UWorld* GetWorld() const override; | ||||
| 	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override; | ||||
| 	virtual bool IsSupportedForNetworking() const override; | ||||
| 	virtual int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack) override; | ||||
| 	virtual bool CallRemoteFunction(UFunction* Function, void* Parms, struct FOutParmRec* OutParms, FFrame* Stack) override; | ||||
| 	// End of implementation | ||||
|  | ||||
| 	// Will mark this UObject as garbage and will eventually get cleaned by the garbage collector. | ||||
| 	// Should only execute this on the server. | ||||
| 	UFUNCTION(meta = (ScriptMethod)) | ||||
| 	void DestroyObject(); | ||||
|  | ||||
| 	// Gets the Actor that "owns" this Replicated UObject. | ||||
| 	UFUNCTION(meta = (ScriptMethod)) | ||||
| 	AActor* GetOwningActor() const; | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	// Is this UObject replicated? | ||||
| 	UPROPERTY(EditAnywhere) | ||||
| 	TEnumAsByte<ECSReplicationState> ReplicationState = ECSReplicationState::Replicates; | ||||
| }; | ||||
| @ -0,0 +1,6 @@ | ||||
| #include "CSEngineSubsystem.h" | ||||
|  | ||||
| bool UCSEngineSubsystem::K2_ShouldCreateSubsystem_Implementation() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
| @ -0,0 +1,90 @@ | ||||
| // Fill out your copyright notice in the Description page of Project Settings. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "SubsystemCollectionBaseRef.h" | ||||
| #include "Subsystems/EngineSubsystem.h" | ||||
| #include "CSEngineSubsystem.generated.h" | ||||
|  | ||||
| UCLASS(Blueprintable, BlueprintType, Abstract) | ||||
| class UCSEngineSubsystem : public UEngineSubsystem, public FTickableGameObject | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| 	// USubsystem Begin | ||||
|  | ||||
| 	virtual void Initialize(FSubsystemCollectionBase& Collection) override | ||||
| 	{ | ||||
| 		Super::Initialize(Collection); | ||||
| 		K2_Initialize(Collection); | ||||
| 	} | ||||
|  | ||||
| 	virtual void Deinitialize() override | ||||
| 	{ | ||||
| 		Super::Deinitialize(); | ||||
| 		K2_Deinitialize(); | ||||
| 	} | ||||
|  | ||||
| 	virtual bool ShouldCreateSubsystem(UObject* Outer) const override | ||||
| 	{ | ||||
| 		if (!Super::ShouldCreateSubsystem(Outer)) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		return K2_ShouldCreateSubsystem(); | ||||
| 	} | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| 	// FTickableGameObject Begin | ||||
|  | ||||
| 	virtual void Tick(float DeltaTime) override | ||||
| 	{ | ||||
| 		K2_Tick(DeltaTime); | ||||
| 	} | ||||
|  | ||||
| 	virtual ETickableTickType GetTickableTickType() const override | ||||
| 	{ | ||||
| 		return ETickableTickType::Conditional; | ||||
| 	} | ||||
|  | ||||
| 	virtual bool IsTickable() const override | ||||
| 	{ | ||||
| 		return bIsTickable; | ||||
| 	} | ||||
|  | ||||
| 	virtual TStatId GetStatId() const override | ||||
| 	{ | ||||
| 		RETURN_QUICK_DECLARE_CYCLE_STAT(UCSEngineSubsystem, STATGROUP_Tickables); | ||||
| 	} | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, Category = "Managed Subsystems") | ||||
| 	bool bIsTickable; | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, Category = "Managed Subsystems") | ||||
| 	void SetIsTickable(bool bInIsTickable) | ||||
| 	{ | ||||
| 		bIsTickable = bInIsTickable; | ||||
| 	} | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	UFUNCTION(BlueprintNativeEvent, meta = (ScriptName = "ShouldCreateSubsystem"), Category = "Managed Subsystems") | ||||
| 	bool K2_ShouldCreateSubsystem() const; | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Initialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Initialize(FSubsystemCollectionBaseRef Collection); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Deinitialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Deinitialize(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Tick"), Category = "Managed Subsystems") | ||||
| 	void K2_Tick(float DeltaTime); | ||||
|  | ||||
| }; | ||||
| @ -0,0 +1,6 @@ | ||||
| #include "CSGameInstanceSubsystem.h" | ||||
|  | ||||
| bool UCSGameInstanceSubsystem::K2_ShouldCreateSubsystem_Implementation() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
| @ -0,0 +1,95 @@ | ||||
| // Fill out your copyright notice in the Description page of Project Settings. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "SubsystemCollectionBaseRef.h" | ||||
| #include "Subsystems/GameInstanceSubsystem.h" | ||||
| #include "CSGameInstanceSubsystem.generated.h" | ||||
|  | ||||
| UCLASS(Blueprintable, BlueprintType, Abstract) | ||||
| class UCSGameInstanceSubsystem : public UGameInstanceSubsystem, public FTickableGameObject | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| 	// USubsystem Begin | ||||
|  | ||||
| 	virtual void Initialize(FSubsystemCollectionBase& Collection) override | ||||
| 	{ | ||||
| 		Super::Initialize(Collection); | ||||
| 		K2_Initialize(Collection); | ||||
| 	} | ||||
|  | ||||
| 	virtual void Deinitialize() override | ||||
| 	{ | ||||
| 		Super::Deinitialize(); | ||||
| 		K2_Deinitialize(); | ||||
| 	} | ||||
|  | ||||
| 	virtual bool ShouldCreateSubsystem(UObject* Outer) const override | ||||
| 	{ | ||||
| 		if (!Super::ShouldCreateSubsystem(Outer)) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		return K2_ShouldCreateSubsystem(); | ||||
| 	} | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| 	// FTickableGameObject Begin | ||||
|  | ||||
| 	virtual void Tick(float DeltaTime) override | ||||
| 	{ | ||||
| 		K2_Tick(DeltaTime); | ||||
| 	} | ||||
|  | ||||
| 	virtual ETickableTickType GetTickableTickType() const override | ||||
| 	{ | ||||
| 		return ETickableTickType::Conditional; | ||||
| 	} | ||||
|  | ||||
| 	virtual bool IsTickable() const override | ||||
| 	{ | ||||
| 		return bIsTickable; | ||||
| 	} | ||||
|  | ||||
| 	virtual TStatId GetStatId() const override | ||||
| 	{ | ||||
| 		RETURN_QUICK_DECLARE_CYCLE_STAT(UCSGameInstanceSubsystem, STATGROUP_Tickables); | ||||
| 	} | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, Category = "Managed Subsystems") | ||||
| 	bool bIsTickable; | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, Category = "Managed Subsystems") | ||||
| 	void SetIsTickable(bool bInIsTickable) | ||||
| 	{ | ||||
| 		bIsTickable = bInIsTickable; | ||||
| 	} | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, meta = (ScriptName = "GetGameInstance"), DisplayName = "Get Game Instance", Category = "Managed Subsystems") | ||||
| 	UGameInstance* K2_GetGameInstance() const | ||||
| 	{ | ||||
| 		return GetGameInstance(); | ||||
| 	}; | ||||
|  | ||||
| 	UFUNCTION(BlueprintNativeEvent, meta = (ScriptName = "ShouldCreateSubsystem"), Category = "Managed Subsystems") | ||||
| 	bool K2_ShouldCreateSubsystem() const; | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Initialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Initialize(FSubsystemCollectionBaseRef Collection); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Deinitialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Deinitialize(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Tick"), Category = "Managed Subsystems") | ||||
| 	void K2_Tick(float DeltaTime); | ||||
| }; | ||||
| @ -0,0 +1,11 @@ | ||||
| #include "CSLocalPlayerSubsystem.h" | ||||
|  | ||||
| bool UCSLocalPlayerSubsystem::K2_ShouldCreateSubsystem_Implementation() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| ULocalPlayer* UCSLocalPlayerSubsystem::K2_GetLocalPlayer() const | ||||
| { | ||||
| 	return GetLocalPlayer(); | ||||
| } | ||||
| @ -0,0 +1,103 @@ | ||||
| // Fill out your copyright notice in the Description page of Project Settings. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "SubsystemCollectionBaseRef.h" | ||||
| #include "Subsystems/LocalPlayerSubsystem.h" | ||||
| #include "CSLocalPlayerSubsystem.generated.h" | ||||
|  | ||||
| UCLASS(Blueprintable, BlueprintType, Abstract) | ||||
| class UCSLocalPlayerSubsystem : public ULocalPlayerSubsystem, public FTickableGameObject | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| 	// USubsystem Begin | ||||
|  | ||||
| 	virtual void Initialize(FSubsystemCollectionBase& Collection) override | ||||
| 	{ | ||||
| 		Super::Initialize(Collection); | ||||
| 		K2_Initialize(Collection); | ||||
| 	} | ||||
|  | ||||
| 	virtual void Deinitialize() override | ||||
| 	{ | ||||
| 		Super::Deinitialize(); | ||||
| 		K2_Deinitialize(); | ||||
| 	} | ||||
|  | ||||
| 	virtual bool ShouldCreateSubsystem(UObject* Outer) const override | ||||
| 	{ | ||||
| 		if (!Super::ShouldCreateSubsystem(Outer)) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		return K2_ShouldCreateSubsystem(); | ||||
| 	} | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| 	// ULocalPlayerSubsystem | ||||
| 	virtual void PlayerControllerChanged(APlayerController* NewPlayerController) override | ||||
| 	{ | ||||
| 		Super::PlayerControllerChanged(NewPlayerController); | ||||
| 		K2_PlayerControllerChanged(NewPlayerController); | ||||
| 	} | ||||
| 	// End | ||||
|  | ||||
| 	// FTickableGameObject Begin | ||||
|  | ||||
| 	virtual void Tick(float DeltaTime) override | ||||
| 	{ | ||||
| 		K2_Tick(DeltaTime); | ||||
| 	} | ||||
|  | ||||
| 	virtual ETickableTickType GetTickableTickType() const override | ||||
| 	{ | ||||
| 		return ETickableTickType::Conditional; | ||||
| 	} | ||||
|  | ||||
| 	virtual bool IsTickable() const override | ||||
| 	{ | ||||
| 		return bIsTickable; | ||||
| 	} | ||||
|  | ||||
| 	virtual TStatId GetStatId() const override | ||||
| 	{ | ||||
| 		RETURN_QUICK_DECLARE_CYCLE_STAT(UCSLocalPlayerSubsystem, STATGROUP_Tickables); | ||||
| 	} | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| public: | ||||
|  | ||||
| 	UPROPERTY(EditAnywhere, Category = "Managed Subsystems") | ||||
| 	bool bIsTickable; | ||||
|  | ||||
| 	UFUNCTION(BlueprintCallable, Category = "Managed Subsystems") | ||||
| 	void SetIsTickable(bool bInIsTickable) | ||||
| 	{ | ||||
| 		bIsTickable = bInIsTickable; | ||||
| 	} | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "PlayerControllerChanged"), Category = "Managed Subsystems") | ||||
| 	bool K2_PlayerControllerChanged(APlayerController* NewPlayerController) const; | ||||
|  | ||||
| 	UFUNCTION(BlueprintNativeEvent, meta = (ScriptName = "ShouldCreateSubsystem"), Category = "Managed Subsystems") | ||||
| 	bool K2_ShouldCreateSubsystem() const; | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Initialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Initialize(FSubsystemCollectionBaseRef Collection); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Deinitialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Deinitialize(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Tick"), Category = "Managed Subsystems") | ||||
| 	void K2_Tick(float DeltaTime); | ||||
|  | ||||
| 	UFUNCTION(meta = (ScriptMethod)) | ||||
| 	ULocalPlayer* K2_GetLocalPlayer() const; | ||||
| }; | ||||
| @ -0,0 +1,33 @@ | ||||
| #include "CSWorldSubsystem.h" | ||||
| #include "SubsystemUtils.h" | ||||
|  | ||||
| bool UCSWorldSubsystem::K2_ShouldCreateSubsystem_Implementation() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void UCSWorldSubsystem::BeginDestroy() | ||||
| { | ||||
| #if UE_VERSION >= 5 | ||||
| #if WITH_EDITOR | ||||
| 	// Edge case in reinstancing world subsystems. Can't call Super as it leads to an ensure, but we do the same thing. | ||||
| 	if (CSSubsystemUtils::IsReinstancingClass(GetClass())) | ||||
| 	{ | ||||
| 		SetTickableTickType(ETickableTickType::Never); | ||||
| 		UObject::BeginDestroy(); | ||||
| 		return; | ||||
| 	} | ||||
| #endif | ||||
| #endif | ||||
| 	Super::BeginDestroy(); | ||||
| } | ||||
|  | ||||
| bool UCSWorldSubsystem::GetIsInitialized() const | ||||
| { | ||||
| 	return IsInitialized(); | ||||
| } | ||||
|  | ||||
| bool UCSWorldSubsystem::K2_DoesSupportWorldType_Implementation(const ECSWorldType WorldType) const | ||||
| { | ||||
|     return true; | ||||
| } | ||||
| @ -0,0 +1,167 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #if ENGINE_MINOR_VERSION >= 5 | ||||
| #include "Streaming/StreamingWorldSubsystemInterface.h" | ||||
| #endif | ||||
| #include "SubsystemCollectionBaseRef.h" | ||||
| #include "Subsystems/WorldSubsystem.h" | ||||
| #include "CSWorldSubsystem.generated.h" | ||||
|  | ||||
| UENUM(BlueprintType) | ||||
| enum class ECSWorldType : uint8 | ||||
| { | ||||
|     /** An untyped world, in most cases this will be the vestigial worlds of streamed in sub-levels */ | ||||
|     None = EWorldType::None, | ||||
|  | ||||
|     /** The game world */ | ||||
|     Game = EWorldType::Game, | ||||
|  | ||||
|     /** A world being edited in the editor */ | ||||
|     Editor = EWorldType::Editor, | ||||
|  | ||||
|     /** A Play In Editor world */ | ||||
|     PIE = EWorldType::PIE, | ||||
|  | ||||
|     /** A preview world for an editor tool */ | ||||
|     EditorPreview = EWorldType::EditorPreview, | ||||
|  | ||||
|     /** A preview world for a game */ | ||||
|     GamePreview = EWorldType::GamePreview, | ||||
|  | ||||
|     /** A minimal RPC world for a game */ | ||||
|     GameRPC = EWorldType::GameRPC, | ||||
|  | ||||
|     /** An editor world that was loaded but not currently being edited in the level editor */ | ||||
|     Inactive = EWorldType::Inactive, | ||||
| }; | ||||
|  | ||||
|  | ||||
| UCLASS(Blueprintable, BlueprintType, Abstract) | ||||
| class UCSWorldSubsystem : public UTickableWorldSubsystem | ||||
| #if ENGINE_MINOR_VERSION >= 5 | ||||
| 	, public IStreamingWorldSubsystemInterface | ||||
| #endif | ||||
| { | ||||
| 	GENERATED_BODY() | ||||
|  | ||||
| 	// USubsystem Begin | ||||
|  | ||||
| 	virtual void Initialize(FSubsystemCollectionBase& Collection) override | ||||
| 	{ | ||||
| 		Super::Initialize(Collection); | ||||
| 		K2_Initialize(Collection); | ||||
| 	} | ||||
|  | ||||
| 	virtual void Deinitialize() override | ||||
| 	{ | ||||
| 		if (IsInitialized()) | ||||
| 		{ | ||||
| 			Super::Deinitialize(); | ||||
| 			K2_Deinitialize(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	virtual bool ShouldCreateSubsystem(UObject* Outer) const override | ||||
| 	{ | ||||
| 		if (!Super::ShouldCreateSubsystem(Outer)) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		return K2_ShouldCreateSubsystem(); | ||||
| 	} | ||||
|  | ||||
|     virtual bool DoesSupportWorldType(const EWorldType::Type WorldType) const override | ||||
| 	{ | ||||
| 	    if (!Super::DoesSupportWorldType(WorldType)) | ||||
| 	    { | ||||
| 	        return false; | ||||
| 	    } | ||||
|  | ||||
| 	    return K2_DoesSupportWorldType(static_cast<ECSWorldType>(WorldType)); | ||||
| 	} | ||||
|  | ||||
| 	virtual void BeginDestroy() override; | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| 	// UWorldSubsystem begin | ||||
| 	virtual void PostInitialize() override | ||||
| 	{ | ||||
| 		Super::PostInitialize(); | ||||
| 		K2_PostInitialize(); | ||||
| 	} | ||||
|  | ||||
| 	virtual void OnWorldBeginPlay(UWorld& InWorld) override | ||||
| 	{ | ||||
| 		Super::OnWorldBeginPlay(InWorld); | ||||
| 		K2_OnWorldBeginPlay(); | ||||
| 	} | ||||
|  | ||||
| 	virtual void OnWorldComponentsUpdated(UWorld& World) override | ||||
| 	{ | ||||
| 		Super::OnWorldComponentsUpdated(World); | ||||
| 		K2_OnWorldComponentsUpdated(); | ||||
| 	} | ||||
|  | ||||
| #if ENGINE_MINOR_VERSION >= 5 | ||||
| 	virtual void OnUpdateStreamingState() override | ||||
| 	{ | ||||
|         K2_UpdateStreamingState(); | ||||
| 	} | ||||
| #else | ||||
| 	virtual void UpdateStreamingState() override | ||||
| 	{ | ||||
| 		Super::UpdateStreamingState(); | ||||
| 		K2_UpdateStreamingState(); | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	virtual TStatId GetStatId() const override | ||||
| 	{ | ||||
| 		RETURN_QUICK_DECLARE_CYCLE_STAT(UCSWorldSubsystem, STATGROUP_Tickables); | ||||
| 	} | ||||
|  | ||||
| 	virtual void Tick(float DeltaTime) override | ||||
| 	{ | ||||
| 		Super::Tick(DeltaTime); | ||||
| 		K2_Tick(DeltaTime); | ||||
| 	} | ||||
|  | ||||
| 	// End | ||||
|  | ||||
| 	/** Returns true if Initialize has been called but Deinitialize has not */ | ||||
| 	UFUNCTION(meta = (ScriptMethod)) | ||||
| 	bool GetIsInitialized() const; | ||||
|  | ||||
| protected: | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "PostInitialize"), Category = "Managed Subsystems") | ||||
| 	void K2_PostInitialize(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Tick"), Category = "Managed Subsystems") | ||||
| 	void K2_Tick(float DeltaTime); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "OnWorldBeginPlay"), Category = "Managed Subsystems") | ||||
| 	void K2_OnWorldBeginPlay(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "OnWorldComponentsUpdated"), Category = "Managed Subsystems") | ||||
| 	void K2_OnWorldComponentsUpdated(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "UpdateStreamingState"), Category = "Managed Subsystems") | ||||
| 	void K2_UpdateStreamingState(); | ||||
|  | ||||
| 	UFUNCTION(BlueprintNativeEvent, meta = (ScriptName = "ShouldCreateSubsystem"), Category = "Managed Subsystems") | ||||
| 	bool K2_ShouldCreateSubsystem() const; | ||||
|  | ||||
|     UFUNCTION(BlueprintNativeEvent, meta = (ScriptName = "DoesSupportWorldType"), Category = "Managed Subsystems") | ||||
|     bool K2_DoesSupportWorldType(const ECSWorldType WorldType) const; | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Initialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Initialize(FSubsystemCollectionBaseRef Collection); | ||||
|  | ||||
| 	UFUNCTION(BlueprintImplementableEvent, meta = (ScriptName = "Deinitialize"), Category = "Managed Subsystems") | ||||
| 	void K2_Deinitialize(); | ||||
|  | ||||
| }; | ||||
| @ -0,0 +1,18 @@ | ||||
| // Fill out your copyright notice in the Description page of Project Settings. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "CoreMinimal.h" | ||||
| #include "SubsystemCollectionBaseRef.generated.h" | ||||
|  | ||||
| USTRUCT(BlueprintType) | ||||
| struct FSubsystemCollectionBaseRef | ||||
| { | ||||
|     GENERATED_BODY() | ||||
|  | ||||
|     FSubsystemCollectionBaseRef() = default; | ||||
|     explicit(false) FSubsystemCollectionBaseRef(FSubsystemCollectionBase &Base) : Base(&Base) {} | ||||
|  | ||||
| private: | ||||
|     FSubsystemCollectionBase *Base; | ||||
| }; | ||||
| @ -0,0 +1,7 @@ | ||||
| #include "SubsystemUtils.h" | ||||
|  | ||||
| bool CSSubsystemUtils::IsReinstancingClass(const UClass* Class) | ||||
| { | ||||
| 	FString ClassName = Class->GetName(); | ||||
| 	return ClassName.StartsWith(TEXT("REINST_")); | ||||
| } | ||||
| @ -0,0 +1,6 @@ | ||||
| #pragma once | ||||
|  | ||||
| namespace CSSubsystemUtils | ||||
| { | ||||
| 	UNREALSHARPCORE_API bool IsReinstancingClass(const UClass* Class); | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user