Migration
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "0.1",
|
||||
"FriendlyName": "CompositeEquipmentSystem",
|
||||
"Description": "Equipment system to attach elements to a character skeletal mesh",
|
||||
"Category": "Gameplay",
|
||||
"CreatedBy": "Amasson",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": true,
|
||||
"IsBetaVersion": true,
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": false,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "CompositeEquipmentSystem",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
],
|
||||
"Plugins": [
|
||||
{
|
||||
"Name": "Niagara",
|
||||
"Enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
BIN
Plugins/CompositeEquipmentSystem/Resources/Icon128.png
LFS
Normal file
BIN
Plugins/CompositeEquipmentSystem/Resources/Icon128.png
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,54 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class CompositeEquipmentSystem : ModuleRules
|
||||
{
|
||||
public CompositeEquipmentSystem(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"Niagara",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Components/CompositeEquipmentComponent.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "NiagaraFunctionLibrary.h"
|
||||
#include "NiagaraComponent.h"
|
||||
|
||||
UCompositeEquipmentComponent::UCompositeEquipmentComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::InitializeWithLeaderPose(USkeletalMeshComponent* NewLeaderPose)
|
||||
{
|
||||
LeaderPoseComponent = NewLeaderPose;
|
||||
PoseOwner = IsValid(LeaderPoseComponent) ? LeaderPoseComponent->GetOwner() : nullptr;
|
||||
|
||||
UpdateCompositesObjects();
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::AddCompositeName(FName CompositeName)
|
||||
{
|
||||
CompositeNames.Add(CompositeName);
|
||||
UpdateCompositesObjects();
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::RemoveCompositeName(FName CompositeName)
|
||||
{
|
||||
CompositeNames.Remove(CompositeName);
|
||||
UpdateCompositesObjects();
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::SetCompositeNames(const TSet<FName>& NewCompositeNames)
|
||||
{
|
||||
CompositeNames = NewCompositeNames;
|
||||
UpdateCompositesObjects();
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::AddCompositeCustom(const FEquipmentComposite& Composite, FName KeyName)
|
||||
{
|
||||
if (CompositeNames.Remove(KeyName))
|
||||
DestroyRemovedComposites();
|
||||
|
||||
CompositeNames.Add(KeyName);
|
||||
|
||||
CreateCompositeWithKey(Composite, KeyName);
|
||||
|
||||
UpdateCompositesObjects();
|
||||
}
|
||||
|
||||
|
||||
/** Private */
|
||||
|
||||
void UCompositeEquipmentComponent::UpdateCompositesObjects()
|
||||
{
|
||||
DestroyRemovedComposites();
|
||||
|
||||
CreateAddedComposites();
|
||||
|
||||
OnEquipedCompositesUpdated.Broadcast(this);
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::DestroyRemovedComposites()
|
||||
{
|
||||
TArray<FName> KeysToRemove;
|
||||
|
||||
for (TPair<FName, FEquipmentCompositeGeneratedObjects>& NameAndGeneratedObjects : GeneratedObjectsForCompositeNames)
|
||||
{
|
||||
const FName& CompositeName(NameAndGeneratedObjects.Key);
|
||||
FEquipmentCompositeGeneratedObjects& GeneratedObjects(NameAndGeneratedObjects.Value);
|
||||
|
||||
bool bShouldRemoveKey = !CompositeNames.Contains(CompositeName);
|
||||
|
||||
if (bShouldRemoveKey)
|
||||
{
|
||||
GeneratedObjects.Destroy();
|
||||
KeysToRemove.Add(CompositeName);
|
||||
}
|
||||
}
|
||||
|
||||
for (const FName& Key : KeysToRemove)
|
||||
{
|
||||
GeneratedObjectsForCompositeNames.Remove(Key);
|
||||
}
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateAddedComposites()
|
||||
{
|
||||
for (const FName& CompositeName : CompositeNames)
|
||||
{
|
||||
if (!GeneratedObjectsForCompositeNames.Contains(CompositeName))
|
||||
CreateCompositeFromTable(CompositeName);
|
||||
}
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateCompositeFromTable(const FName& CompositeName)
|
||||
{
|
||||
if (IsValid(EquipmentTable))
|
||||
{
|
||||
FEquipmentComposite* CompositeRow = EquipmentTable->FindRow<FEquipmentComposite>(CompositeName, "Fetch Equipment Data");
|
||||
if (CompositeRow)
|
||||
{
|
||||
CreateCompositeWithKey(*CompositeRow, CompositeName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* In case of invalid name, we still create an empty object in our
|
||||
* GeneratedObjectsForCompositeNames array to prevent future lookup
|
||||
* that would waste performances
|
||||
*/
|
||||
CreateCompositeWithKey(FEquipmentComposite(), CompositeName);
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateCompositeWithKey(const FEquipmentComposite& Composite, const FName& CompositeKey)
|
||||
{
|
||||
FEquipmentCompositeGeneratedObjects ComponentsArray;
|
||||
CreateCompositeObjects(Composite, ComponentsArray);
|
||||
GeneratedObjectsForCompositeNames.Add(CompositeKey, ComponentsArray);
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateCompositeObjects(const FEquipmentComposite& Composite, FEquipmentCompositeGeneratedObjects& GeneratedObjects)
|
||||
{
|
||||
if (!(IsValid(LeaderPoseComponent) && PoseOwner.IsValid()))
|
||||
return;
|
||||
|
||||
CreateStaticMeshes(Composite.StaticMeshes, GeneratedObjects);
|
||||
CreateSkeletalMeshes(Composite.SkeletalMeshes, GeneratedObjects);
|
||||
CreateSpecialEffects(Composite.SpecialEffects, GeneratedObjects);
|
||||
CreateChildActors(Composite.ChildActors, GeneratedObjects);
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateStaticMeshes(const TArray<FEquipableStaticMesh>& EquipableMeshes, FEquipmentCompositeGeneratedObjects& GeneratedObjects)
|
||||
{
|
||||
for (const FEquipableStaticMesh& Equipable : EquipableMeshes)
|
||||
{
|
||||
UStaticMeshComponent* MeshComponent = CreateAttachedComponent_Unsafe<UStaticMeshComponent>(Equipable);
|
||||
|
||||
if (IsValid(MeshComponent))
|
||||
{
|
||||
MeshComponent->SetStaticMesh(Equipable.StaticMesh);
|
||||
|
||||
for (int32 i = 0; i < Equipable.OverrideMaterials.Num(); i++)
|
||||
MeshComponent->SetMaterial(i, Equipable.OverrideMaterials[i]);
|
||||
|
||||
|
||||
GeneratedObjects.AddComponent(MeshComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateSkeletalMeshes(const TArray<FEquipableSkeletalMesh>& EquipableMeshes, FEquipmentCompositeGeneratedObjects& GeneratedObjects)
|
||||
{
|
||||
AActor* Owner = LeaderPoseComponent->GetOwner();
|
||||
if (!IsValid(Owner)) return;
|
||||
|
||||
for (const FEquipableSkeletalMesh& Equipable : EquipableMeshes)
|
||||
{
|
||||
USkeletalMeshComponent* SkeletalComponent = CreateAttachedComponent_Unsafe<USkeletalMeshComponent>(Equipable);
|
||||
|
||||
if (IsValid(SkeletalComponent))
|
||||
{
|
||||
SkeletalComponent->SetSkeletalMesh(Equipable.SkeletalMesh);
|
||||
|
||||
for (int32 i = 0; i < Equipable.OverrideMaterials.Num(); i++)
|
||||
SkeletalComponent->SetMaterial(i, Equipable.OverrideMaterials[i]);
|
||||
|
||||
for (const FName& BoneName : Equipable.HiddenBones)
|
||||
SkeletalComponent->HideBoneByName(BoneName, EPhysBodyOp::PBO_None);
|
||||
|
||||
if (Equipable.bUseLeaderPose)
|
||||
SkeletalComponent->SetLeaderPoseComponent(LeaderPoseComponent);
|
||||
|
||||
if (IsValid(Equipable.AnimInstanceClass))
|
||||
SkeletalComponent->SetAnimInstanceClass(Equipable.AnimInstanceClass);
|
||||
|
||||
|
||||
GeneratedObjects.AddComponent(SkeletalComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateSpecialEffects(const TArray<FEquipableSpecialEffect>& EquipableEffects, FEquipmentCompositeGeneratedObjects& GeneratedObjects)
|
||||
{
|
||||
for (const FEquipableSpecialEffect& Equipable : EquipableEffects)
|
||||
{
|
||||
if (IsValid(Equipable.CascadeEffect))
|
||||
{
|
||||
UParticleSystemComponent* ParticleComponent = UGameplayStatics::SpawnEmitterAttached(
|
||||
Equipable.CascadeEffect,
|
||||
LeaderPoseComponent,
|
||||
Equipable.SocketName,
|
||||
Equipable.RelativeTransform.GetLocation(),
|
||||
Equipable.RelativeTransform.GetRotation().Rotator(),
|
||||
EAttachLocation::Type::KeepRelativeOffset
|
||||
);
|
||||
|
||||
GeneratedObjects.AddComponent(ParticleComponent);
|
||||
}
|
||||
|
||||
if (IsValid(Equipable.NiagaraEffect))
|
||||
{
|
||||
UNiagaraComponent* NiagaraComponent = UNiagaraFunctionLibrary::SpawnSystemAttached(
|
||||
Equipable.NiagaraEffect,
|
||||
LeaderPoseComponent,
|
||||
Equipable.SocketName,
|
||||
Equipable.RelativeTransform.GetLocation(),
|
||||
Equipable.RelativeTransform.GetRotation().Rotator(),
|
||||
EAttachLocation::Type::KeepRelativeOffset,
|
||||
true
|
||||
);
|
||||
|
||||
GeneratedObjects.AddComponent(NiagaraComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCompositeEquipmentComponent::CreateChildActors(const TArray<FEquipableChildActor>& EquipableActors, FEquipmentCompositeGeneratedObjects& GeneratedObjects)
|
||||
{
|
||||
AActor* Owner = LeaderPoseComponent->GetOwner();
|
||||
if (!IsValid(Owner)) return;
|
||||
|
||||
for (const FEquipableChildActor& Equipable : EquipableActors)
|
||||
{
|
||||
UChildActorComponent* ChildActorComponent = CreateAttachedComponent_Unsafe<UChildActorComponent>(Equipable);
|
||||
|
||||
if (IsValid(ChildActorComponent))
|
||||
{
|
||||
ChildActorComponent->SetChildActorClass(Equipable.ActorClass);
|
||||
|
||||
|
||||
GeneratedObjects.AddComponent(ChildActorComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "CompositeEquipmentSystem.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FCompositeEquipmentSystemModule"
|
||||
|
||||
void FCompositeEquipmentSystemModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
}
|
||||
|
||||
void FCompositeEquipmentSystemModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FCompositeEquipmentSystemModule, CompositeEquipmentSystem)
|
||||
@@ -0,0 +1,18 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Structures/CompositeEquipmentSystemStructs.h"
|
||||
|
||||
|
||||
void FEquipmentCompositeGeneratedObjects::AddComponent(UActorComponent* NewComponent)
|
||||
{
|
||||
Components.Add(NewComponent);
|
||||
}
|
||||
|
||||
void FEquipmentCompositeGeneratedObjects::Destroy()
|
||||
{
|
||||
for (UActorComponent* Component : Components)
|
||||
{
|
||||
Component->DestroyComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "Structures/CompositeEquipmentSystemStructs.h"
|
||||
#include "CompositeEquipmentComponent.generated.h"
|
||||
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnEquipedCompositesUpdatedSignature, UCompositeEquipmentComponent*, MeshEquipmentComponent);
|
||||
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class COMPOSITEEQUIPMENTSYSTEM_API UCompositeEquipmentComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UCompositeEquipmentComponent();
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnEquipedCompositesUpdatedSignature OnEquipedCompositesUpdated;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Leader Pose")
|
||||
void InitializeWithLeaderPose(USkeletalMeshComponent* NewLeaderPose);
|
||||
|
||||
FORCEINLINE USkeletalMeshComponent* GetLeaderPoseComponent() const { return LeaderPoseComponent; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Equiped Composites")
|
||||
void AddCompositeName(FName CompositeName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Equiped Composites")
|
||||
void RemoveCompositeName(FName CompositeName);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Equiped Composites")
|
||||
void SetCompositeNames(const TSet<FName>& NewCompositeNames);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Equiped Composites")
|
||||
void AddCompositeCustom(const FEquipmentComposite& Composite, FName KeyName);
|
||||
|
||||
protected:
|
||||
|
||||
/** Table of EquipmentComposite */
|
||||
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Equipment Data", meta = (RequiredAssetDataTags = "RowStructure=/Script/CompositeEquipmentSystem.EquipmentComposite"))
|
||||
TObjectPtr<UDataTable> EquipmentTable;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Equiped Composites", meta = (AllowPrivateAccess = true))
|
||||
TSet<FName> CompositeNames;
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "Leader Pose", meta = (AllowPrivateAccess = true))
|
||||
TObjectPtr<USkeletalMeshComponent> LeaderPoseComponent;
|
||||
|
||||
UPROPERTY()
|
||||
TWeakObjectPtr<AActor> PoseOwner;
|
||||
|
||||
UPROPERTY()
|
||||
TMap<FName, FEquipmentCompositeGeneratedObjects> GeneratedObjectsForCompositeNames;
|
||||
|
||||
protected:
|
||||
|
||||
void UpdateCompositesObjects();
|
||||
|
||||
void DestroyRemovedComposites();
|
||||
void CreateAddedComposites();
|
||||
|
||||
void CreateCompositeFromTable(const FName& CompositeName);
|
||||
void CreateCompositeWithKey(const FEquipmentComposite& Composite, const FName& CompositeKey);
|
||||
|
||||
void CreateCompositeObjects(const FEquipmentComposite& Composite, FEquipmentCompositeGeneratedObjects& GeneratedObjects);
|
||||
|
||||
void CreateStaticMeshes(const TArray<FEquipableStaticMesh>& EquipableMeshes, FEquipmentCompositeGeneratedObjects& GeneratedObjects);
|
||||
void CreateSkeletalMeshes(const TArray<FEquipableSkeletalMesh>& EquipableMeshes, FEquipmentCompositeGeneratedObjects& GeneratedObjects);
|
||||
void CreateSpecialEffects(const TArray<FEquipableSpecialEffect>& EquipableEffects, FEquipmentCompositeGeneratedObjects& GeneratedObjects);
|
||||
void CreateChildActors(const TArray<FEquipableChildActor>& EquipableActors, FEquipmentCompositeGeneratedObjects& GeneratedObjects);
|
||||
|
||||
template<class TComponent>
|
||||
TComponent* CreateAttachedComponent_Unsafe(const FEquipableAttached& Equipable)
|
||||
{
|
||||
static_assert(std::is_base_of<USceneComponent, TComponent>::value, "TComponent must be a subclass of USceneComponent.");
|
||||
|
||||
UActorComponent* CreatedComponent = PoseOwner->AddComponentByClass(
|
||||
TComponent::StaticClass(),
|
||||
true,
|
||||
Equipable.RelativeTransform,
|
||||
false
|
||||
);
|
||||
|
||||
if (!IsValid(CreatedComponent))
|
||||
return nullptr;
|
||||
|
||||
if (TComponent* SceneComponent = Cast<TComponent>(CreatedComponent))
|
||||
{
|
||||
SceneComponent->AttachToComponent(
|
||||
LeaderPoseComponent,
|
||||
FAttachmentTransformRules::KeepRelativeTransform,
|
||||
Equipable.SocketName
|
||||
);
|
||||
return SceneComponent;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FCompositeEquipmentSystemModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DataTable.h"
|
||||
#include "CompositeEquipmentSystemStructs.generated.h"
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct COMPOSITEEQUIPMENTSYSTEM_API FEquipableAttached
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Position")
|
||||
FTransform RelativeTransform;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Position")
|
||||
FName SocketName;
|
||||
|
||||
};
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct COMPOSITEEQUIPMENTSYSTEM_API FEquipableStaticMesh : public FEquipableAttached
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Mesh")
|
||||
TObjectPtr<UStaticMesh> StaticMesh;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Mesh")
|
||||
TArray<UMaterialInterface*> OverrideMaterials;
|
||||
|
||||
};
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct COMPOSITEEQUIPMENTSYSTEM_API FEquipableSkeletalMesh : public FEquipableAttached
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Mesh")
|
||||
TObjectPtr<USkeletalMesh> SkeletalMesh;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Mesh")
|
||||
TArray<UMaterialInterface*> OverrideMaterials;
|
||||
|
||||
/** Incompatible with UseLeaderPose */
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Mesh")
|
||||
TArray<FName> HiddenBones;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Animation")
|
||||
bool bUseLeaderPose = true;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Animation")
|
||||
TSubclassOf<UAnimInstance> AnimInstanceClass;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class UNiagaraSystem;
|
||||
class UParticleSystem;
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct COMPOSITEEQUIPMENTSYSTEM_API FEquipableSpecialEffect : public FEquipableAttached
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VFX")
|
||||
TObjectPtr<UNiagaraSystem> NiagaraEffect;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "VFX")
|
||||
TObjectPtr<UParticleSystem> CascadeEffect;
|
||||
|
||||
};
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct COMPOSITEEQUIPMENTSYSTEM_API FEquipableChildActor : public FEquipableAttached
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Actor")
|
||||
TSubclassOf<AActor> ActorClass;
|
||||
|
||||
};
|
||||
|
||||
|
||||
USTRUCT(BlueprintType, Blueprintable)
|
||||
struct COMPOSITEEQUIPMENTSYSTEM_API FEquipmentComposite : public FTableRowBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Composites")
|
||||
TArray<FEquipableStaticMesh> StaticMeshes;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Composites")
|
||||
TArray<FEquipableSkeletalMesh> SkeletalMeshes;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Composites")
|
||||
TArray<FEquipableSpecialEffect> SpecialEffects;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Composites")
|
||||
TArray<FEquipableChildActor> ChildActors;
|
||||
};
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FEquipmentCompositeGeneratedObjects
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY()
|
||||
TArray<UActorComponent*> Components;
|
||||
|
||||
void AddComponent(UActorComponent* NewComponent);
|
||||
|
||||
void Destroy();
|
||||
};
|
||||
BIN
Plugins/InteractionSystem/Content/Tests/TestMap_InteractionSystem.umap
LFS
Normal file
BIN
Plugins/InteractionSystem/Content/Tests/TestMap_InteractionSystem.umap
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Plugins/InteractionSystem/Content/UI/WBP_AInteractionSystemWidget.uasset
LFS
Normal file
BIN
Plugins/InteractionSystem/Content/UI/WBP_AInteractionSystemWidget.uasset
LFS
Normal file
Binary file not shown.
24
Plugins/InteractionSystem/InteractionSystem.uplugin
Normal file
24
Plugins/InteractionSystem/InteractionSystem.uplugin
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "0.1",
|
||||
"FriendlyName": "InteractionSystem",
|
||||
"Description": "Triggerable interaction system",
|
||||
"Category": "Gameplay",
|
||||
"CreatedBy": "Amasson",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": true,
|
||||
"IsBetaVersion": true,
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": false,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "InteractionSystem",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Plugins/InteractionSystem/Resources/Icon128.png
LFS
Normal file
BIN
Plugins/InteractionSystem/Resources/Icon128.png
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,53 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class InteractionSystem : ModuleRules
|
||||
{
|
||||
public InteractionSystem(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Components/InteractionControllerComponent.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
|
||||
|
||||
UInteractionControllerComponent::UInteractionControllerComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
OwningPlayerController = Cast<APlayerController>(GetOwner());
|
||||
|
||||
if (!IsValid(OwningPlayerController))
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("UInteractionControllerComponent is not owned by a valid APlayerController"));
|
||||
}
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
UpdateHover();
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::TriggerHoveredObject()
|
||||
{
|
||||
if (IsValid(HoveredObject))
|
||||
{
|
||||
bHoveredObjectPressed = true;
|
||||
APawn* TriggeringPawn = nullptr;
|
||||
if (IsValid(OwningPlayerController))
|
||||
TriggeringPawn = OwningPlayerController->GetPawn();
|
||||
|
||||
Super::ExecuteTrigger(HoveredObject, OwningPlayerController, TriggeringPawn, FName("PlayerInteraction"), this);
|
||||
}
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::ReleaseTriggerHoveredObject()
|
||||
{
|
||||
bHoveredObjectPressed = false;
|
||||
if (IsValid(HoveredObject))
|
||||
{
|
||||
APawn* TriggeringPawn = nullptr;
|
||||
if (IsValid(OwningPlayerController))
|
||||
TriggeringPawn = OwningPlayerController->GetPawn();
|
||||
|
||||
Super::ExecuteReleaseTrigger(HoveredObject, OwningPlayerController, TriggeringPawn, FName("PlayerInteraction"), this);
|
||||
}
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::Activate(bool bReset)
|
||||
{
|
||||
Super::Activate(bReset);
|
||||
|
||||
if (bReset)
|
||||
CursorHit = FHitResult();
|
||||
SetComponentTickEnabled(true);
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::Deactivate()
|
||||
{
|
||||
Super::Deactivate();
|
||||
|
||||
if (IsValid(HoveredObject))
|
||||
UnhoverObject_Unsafe();
|
||||
SetComponentTickEnabled(false);
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::UpdateHover()
|
||||
{
|
||||
if (!IsValid(OwningPlayerController))
|
||||
return;
|
||||
|
||||
OwningPlayerController->GetHitResultUnderCursor(CursorChannel, false, CursorHit);
|
||||
|
||||
UObject* NewHitObject = GetHoverableObjectFromCursorHit();
|
||||
|
||||
if (IsValid(HoveredObject))
|
||||
{
|
||||
bool bCurrentHoverIsStillValid = IWorldHoverable::Execute_CanBeHovered(HoveredObject, OwningPlayerController, CursorHit);
|
||||
|
||||
bool bShouldUnhover = (!bCurrentHoverIsStillValid) || (NewHitObject != HoveredObject);
|
||||
if (bShouldUnhover)
|
||||
UnhoverObject_Unsafe();
|
||||
}
|
||||
|
||||
if (!HoveredObject && IsValid(NewHitObject))
|
||||
{
|
||||
HoverObject(NewHitObject);
|
||||
}
|
||||
}
|
||||
|
||||
UObject* UInteractionControllerComponent::GetHoverableObjectFromCursorHit()
|
||||
{
|
||||
UPrimitiveComponent* HitComponent = CursorHit.GetComponent();
|
||||
if (IsValid(HitComponent) && HitComponent->Implements<UWorldHoverable>())
|
||||
{
|
||||
if (IWorldHoverable::Execute_CanBeHovered(HitComponent, OwningPlayerController, CursorHit))
|
||||
return HitComponent;
|
||||
}
|
||||
AActor* HitActor = CursorHit.GetActor();
|
||||
if (IsValid(HitActor) && HitActor->Implements<UWorldHoverable>())
|
||||
{
|
||||
if (IWorldHoverable::Execute_CanBeHovered(HitActor, OwningPlayerController, CursorHit))
|
||||
return HitActor;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::UnhoverObject_Unsafe()
|
||||
{
|
||||
if (bHoveredObjectPressed)
|
||||
ReleaseTriggerHoveredObject();
|
||||
|
||||
IWorldHoverable::Execute_HoveredEnd(HoveredObject, OwningPlayerController);
|
||||
|
||||
OnHoverObjectEnd.Broadcast(this, HoveredObject);
|
||||
|
||||
HoveredObject = nullptr;
|
||||
}
|
||||
|
||||
void UInteractionControllerComponent::HoverObject(UObject* NewHoverObject)
|
||||
{
|
||||
HoveredObject = NewHoverObject;
|
||||
|
||||
IWorldHoverable::Execute_HoveredBegin(HoveredObject, OwningPlayerController, CursorHit);
|
||||
|
||||
OnHoverObjectBegin.Broadcast(this, HoveredObject);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Components/ObjectTriggererComponent.h"
|
||||
#include "Interfaces/Triggerable.h"
|
||||
#include "GameFramework/GameStateBase.h"
|
||||
|
||||
UObjectTriggererComponent::UObjectTriggererComponent()
|
||||
{
|
||||
PrimaryComponentTick.bCanEverTick = false;
|
||||
|
||||
SetIsReplicatedByDefault(true);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
GlobalObjectTriggerer = GetGlobalObjectTriggererComponent();
|
||||
}
|
||||
|
||||
|
||||
void UObjectTriggererComponent::ExecuteTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
if (IsValid(TriggerableObject) && TriggerableObject->Implements<UTriggerable>())
|
||||
{
|
||||
ETriggerMode TriggerMode = ITriggerable::Execute_GetTriggerMode(TriggerableObject);
|
||||
switch (TriggerMode)
|
||||
{
|
||||
case ETriggerMode::TM_Server:
|
||||
Server_ExecuteTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
break;
|
||||
case ETriggerMode::TM_Client:
|
||||
Client_ExecuteTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
break;
|
||||
case ETriggerMode::TM_Multicast:
|
||||
Server_MulticastExecuteTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::ExecuteReleaseTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
if (IsValid(TriggerableObject) && TriggerableObject->Implements<UTriggerable>())
|
||||
{
|
||||
ETriggerMode TriggerMode = ITriggerable::Execute_GetTriggerMode(TriggerableObject);
|
||||
switch (TriggerMode)
|
||||
{
|
||||
case ETriggerMode::TM_Server:
|
||||
Server_ExecuteReleaseTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
break;
|
||||
case ETriggerMode::TM_Client:
|
||||
Client_ExecuteReleaseTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
break;
|
||||
case ETriggerMode::TM_Multicast:
|
||||
Server_MulticastExecuteReleaseTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UObjectTriggererComponent::Server_ExecuteTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
ITriggerable::Execute_Trigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::Client_ExecuteTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
ITriggerable::Execute_Trigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::Server_MulticastExecuteTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
UObjectTriggererComponent* Triggerer = GlobalObjectTriggerer;
|
||||
if (!IsValid(Triggerer))
|
||||
Triggerer = this;
|
||||
Triggerer->NetMulticast_ExecuteTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::NetMulticast_ExecuteTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
ITriggerable::Execute_Trigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::Server_ExecuteReleaseTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
ITriggerable::Execute_ReleaseTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::Client_ExecuteReleaseTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
ITriggerable::Execute_ReleaseTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::Server_MulticastExecuteReleaseTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
UObjectTriggererComponent* Triggerer = GlobalObjectTriggerer;
|
||||
if (!IsValid(Triggerer))
|
||||
Triggerer = this;
|
||||
Triggerer->NetMulticast_ExecuteReleaseTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
void UObjectTriggererComponent::NetMulticast_ExecuteReleaseTrigger_Implementation(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
ITriggerable::Execute_ReleaseTrigger(TriggerableObject, TriggeringController, TriggeringPawn, Tag, Payload);
|
||||
}
|
||||
|
||||
UObjectTriggererComponent* UObjectTriggererComponent::GetGlobalObjectTriggererComponent() const
|
||||
{
|
||||
AGameStateBase* GameState = GetWorld()->GetGameState();
|
||||
UObjectTriggererComponent *GlobalTrigger = GameState->GetComponentByClass<UObjectTriggererComponent>();
|
||||
|
||||
if (!IsValid(GlobalTrigger))
|
||||
UE_LOG(LogTemp, Warning, TEXT("No UObjectTriggererComponent in GameState... Multicast triggers won't be executed by everyone"));
|
||||
|
||||
return GlobalTrigger;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Components/Shapes/BoxInteractionComponent.h"
|
||||
|
||||
/** Trigger */
|
||||
|
||||
void UBoxInteractionComponent::Trigger_Implementation(AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
if (IsValid(TriggeringActor) && TriggeringActor->Implements<UTriggerable>())
|
||||
{
|
||||
ITriggerable::Execute_Trigger(TriggeringActor, TriggeringController, TriggeringPawn, this->TriggeringTag, this->TriggeringPayload);
|
||||
}
|
||||
}
|
||||
|
||||
void UBoxInteractionComponent::ReleaseTrigger_Implementation(AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload)
|
||||
{
|
||||
if (IsValid(TriggeringActor) && TriggeringActor->Implements<UTriggerable>())
|
||||
{
|
||||
ITriggerable::Execute_ReleaseTrigger(TriggeringActor, TriggeringController, TriggeringPawn, this->TriggeringTag, this->TriggeringPayload);
|
||||
}
|
||||
}
|
||||
|
||||
ETriggerMode UBoxInteractionComponent::GetTriggerMode_Implementation() const
|
||||
{
|
||||
if (IsValid(TriggeringActor) && TriggeringActor->Implements<UTriggerable>())
|
||||
{
|
||||
return ITriggerable::Execute_GetTriggerMode(TriggeringActor);
|
||||
}
|
||||
return ETriggerMode::TM_Client;
|
||||
}
|
||||
|
||||
|
||||
/** Hovering */
|
||||
|
||||
void UBoxInteractionComponent::GetWorldHoverableInfos_Implementation(FWorldHoverableInfos& Infos)
|
||||
{
|
||||
Infos.Location = GetComponentTransform().TransformPosition(InfoLocationOffset);
|
||||
Infos.Text = InfoText;
|
||||
Infos.bScreenSpace = false;
|
||||
}
|
||||
|
||||
bool UBoxInteractionComponent::CanBeHovered_Implementation(AController* Controller, const FHitResult& TraceHit)
|
||||
{
|
||||
if (MaxRange >= 0)
|
||||
return TraceHit.Distance < MaxRange;
|
||||
return true;
|
||||
}
|
||||
|
||||
void UBoxInteractionComponent::HoveredBegin_Implementation(AController* Controller, const FHitResult& TraceHit)
|
||||
{
|
||||
OnHoverBegin.Broadcast(this, TraceHit);
|
||||
}
|
||||
|
||||
void UBoxInteractionComponent::HoveredEnd_Implementation(AController* Controller)
|
||||
{
|
||||
OnHoverEnd.Broadcast(this);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "InteractionSystem.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FInteractionSystemModule"
|
||||
|
||||
void FInteractionSystemModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
}
|
||||
|
||||
void FInteractionSystemModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FInteractionSystemModule, InteractionSystem)
|
||||
@@ -0,0 +1,11 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "InteractionSystemLibrary.h"
|
||||
|
||||
void UInteractionSystemLibrary::DefaultsActorWorldHoverableInfos(AActor* Actor, FText TooltipText, FWorldHoverableInfos& Infos)
|
||||
{
|
||||
Infos.Location = IsValid(Actor) ? Actor->GetActorLocation() : FVector();
|
||||
Infos.Text = TooltipText;
|
||||
Infos.bScreenSpace = false;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Interfaces/Triggerable.h"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Interfaces/WorldHoverable.h"
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ObjectTriggererComponent.h"
|
||||
#include "Interfaces/WorldHoverable.h"
|
||||
#include "Interfaces/Triggerable.h"
|
||||
#include "InteractionControllerComponent.generated.h"
|
||||
|
||||
class APlayerController;
|
||||
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnHoverObjectChangedSignature, UInteractionControllerComponent*, InteractionComponent, UObject*, WorldHoverable);
|
||||
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class INTERACTIONSYSTEM_API UInteractionControllerComponent : public UObjectTriggererComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UInteractionControllerComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Hover")
|
||||
FOnHoverObjectChangedSignature OnHoverObjectBegin;
|
||||
|
||||
UPROPERTY(BlueprintAssignable, Category = "Hover")
|
||||
FOnHoverObjectChangedSignature OnHoverObjectEnd;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Hover")
|
||||
FORCEINLINE UObject* GetHoveredObject() const { return HoveredObject; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Hover")
|
||||
FORCEINLINE AActor* GetHoveredActor() const { return IsValid(HoveredObject) ? Cast<AActor>(HoveredObject) : nullptr; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Hover")
|
||||
FORCEINLINE UActorComponent* GetHoveredComponent() const { return IsValid(HoveredObject) ? Cast<UActorComponent>(HoveredObject) : nullptr; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Cursor")
|
||||
const FHitResult& GetCursorHit() const { return CursorHit; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Trigger")
|
||||
void TriggerHoveredObject();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Trigger")
|
||||
void ReleaseTriggerHoveredObject();
|
||||
|
||||
virtual void Activate(bool bReset = false) override;
|
||||
virtual void Deactivate() override;
|
||||
|
||||
protected:
|
||||
|
||||
void UpdateHover();
|
||||
|
||||
UObject* GetHoverableObjectFromCursorHit();
|
||||
void UnhoverObject_Unsafe();
|
||||
void HoverObject(UObject* NewHoverObject);
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<APlayerController> OwningPlayerController;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Cursor", meta = (AllowPrivateAccess = true))
|
||||
TEnumAsByte<ECollisionChannel> CursorChannel;
|
||||
|
||||
UPROPERTY()
|
||||
FHitResult CursorHit;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UObject> HoveredObject;
|
||||
|
||||
// UPROPERTY(EditAnywhere, Category = "Cursor", meta = (AllowPrivateAccess = true))
|
||||
// TObjectPtr<UInputAction> InteractionInput;
|
||||
|
||||
bool bHoveredObjectPressed = false;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "ObjectTriggererComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class INTERACTIONSYSTEM_API UObjectTriggererComponent : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UObjectTriggererComponent();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Trigger")
|
||||
void ExecuteTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Trigger")
|
||||
void ExecuteReleaseTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
protected:
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_ExecuteTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(Client, Reliable)
|
||||
void Client_ExecuteTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_MulticastExecuteTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(NetMulticast, Reliable)
|
||||
void NetMulticast_ExecuteTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_ExecuteReleaseTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(Client, Reliable)
|
||||
void Client_ExecuteReleaseTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void Server_MulticastExecuteReleaseTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(NetMulticast, Reliable)
|
||||
void NetMulticast_ExecuteReleaseTrigger(UObject* TriggerableObject, AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
|
||||
UObjectTriggererComponent* GetGlobalObjectTriggererComponent() const;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UObjectTriggererComponent> GlobalObjectTriggerer;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/BoxComponent.h"
|
||||
#include "Interfaces/WorldHoverable.h"
|
||||
#include "Interfaces/Triggerable.h"
|
||||
#include "BoxInteractionComponent.generated.h"
|
||||
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnInteractionHoverBeginSignature, UBoxInteractionComponent*, BoxInteraction, FHitResult, CursorHit);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnInteractionHoverEndSignature, UBoxInteractionComponent*, BoxInteraction);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
UCLASS( Blueprintable, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
|
||||
class INTERACTIONSYSTEM_API UBoxInteractionComponent : public UBoxComponent, public IWorldHoverable, public ITriggerable
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnInteractionHoverBeginSignature OnHoverBegin;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnInteractionHoverEndSignature OnHoverEnd;
|
||||
|
||||
/** Trigger */
|
||||
|
||||
virtual void Trigger_Implementation(AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload) override;
|
||||
virtual void ReleaseTrigger_Implementation(AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload) override;
|
||||
virtual ETriggerMode GetTriggerMode_Implementation() const override;
|
||||
|
||||
|
||||
/** Hovering */
|
||||
|
||||
virtual void GetWorldHoverableInfos_Implementation(FWorldHoverableInfos& Infos) override;
|
||||
virtual bool CanBeHovered_Implementation(AController* Controller, const FHitResult& TraceHit) override;
|
||||
virtual void HoveredBegin_Implementation(AController* Controller, const FHitResult& TraceHit) override;
|
||||
virtual void HoveredEnd_Implementation(AController* Controller) override;
|
||||
|
||||
|
||||
/** Trigger Properties */
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
|
||||
TObjectPtr<AActor> TriggeringActor;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
|
||||
FName TriggeringTag;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
|
||||
TObjectPtr<UObject> TriggeringPayload;
|
||||
|
||||
|
||||
/** Hovering Properties */
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
|
||||
float MaxRange = -1;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
|
||||
FVector InfoLocationOffset;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
|
||||
FText InfoText;
|
||||
|
||||
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FInteractionSystemModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "Interfaces/WorldHoverable.h"
|
||||
#include "InteractionSystemLibrary.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class INTERACTIONSYSTEM_API UInteractionSystemLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "WorldTooltip", meta = (DefaultToSelf = "Actor"))
|
||||
static void DefaultsActorWorldHoverableInfos(AActor* Actor, FText TooltipText, FWorldHoverableInfos& Infos);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "Triggerable.generated.h"
|
||||
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ETriggerMode : uint8
|
||||
{
|
||||
TM_Multicast UMETA(DisplayName="Multicast"),
|
||||
TM_Server UMETA(DisplayName="Server"),
|
||||
TM_Client UMETA(DisplayName="Client"),
|
||||
};
|
||||
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE(MinimalAPI)
|
||||
class UTriggerable : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class INTERACTIONSYSTEM_API ITriggerable
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Triggerable")
|
||||
void Trigger(AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Triggerable")
|
||||
void ReleaseTrigger(AController* TriggeringController, APawn* TriggeringPawn, FName Tag, UObject* Payload);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Triggerable")
|
||||
ETriggerMode GetTriggerMode() const;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/Interface.h"
|
||||
#include "WorldHoverable.generated.h"
|
||||
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct INTERACTIONSYSTEM_API FWorldHoverableInfos
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FVector Location = FVector::ZeroVector;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
FText Text;
|
||||
|
||||
/** Is Location in Screen Space or World Space */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool bScreenSpace = false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// This class does not need to be modified.
|
||||
UINTERFACE(MinimalAPI)
|
||||
class UWorldHoverable : public UInterface
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class INTERACTIONSYSTEM_API IWorldHoverable
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// Add interface functions to this class. This is the class that will be inherited to implement this interface.
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "WorldTooltip")
|
||||
void GetWorldHoverableInfos(FWorldHoverableInfos& Infos);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "WorldTooltip")
|
||||
bool CanBeHovered(AController* Controller, const FHitResult& TraceHit);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "WorldTooltip")
|
||||
void HoveredBegin(AController* Controller, const FHitResult& TraceHit);
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "WorldTooltip")
|
||||
void HoveredEnd(AController* Controller);
|
||||
|
||||
};
|
||||
BIN
Plugins/LibAmasson/Content/Blueprints/BFL_GenericFunctionsExtension.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Blueprints/BFL_GenericFunctionsExtension.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Blueprints/BPL_ActorMacros.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Blueprints/BPL_ActorMacros.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Blueprints/BPL_GenericMacrosExtension.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Blueprints/BPL_GenericMacrosExtension.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Blueprints/BPL_UserWidgetMacros.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Blueprints/BPL_UserWidgetMacros.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Blueprints/BP_OnlineSessionManager.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Blueprints/BP_OnlineSessionManager.uasset
LFS
Normal file
Binary file not shown.
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Materials/Functions/MF_CircleMask.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Materials/Functions/MF_CircleMask.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Materials/Functions/MF_Juliabrot.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Materials/Functions/MF_Juliabrot.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Materials/Functions/MF_RadialMask.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Materials/Functions/MF_RadialMask.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Materials/Masters/MI_WidgetMask_Circle.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Materials/Masters/MI_WidgetMask_Circle.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Materials/Masters/M_CircleRadialProgress.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Materials/Masters/M_CircleRadialProgress.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Materials/Masters/M_WidgetCircleMask.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Materials/Masters/M_WidgetCircleMask.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Materials/Masters/M_WidgetTextureMask.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Materials/Masters/M_WidgetTextureMask.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Tests/TestMap_LibAmasson.umap
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Tests/TestMap_LibAmasson.umap
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Tests/TestMap_LibAmasson_GameMode.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Tests/TestMap_LibAmasson_GameMode.uasset
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/SegmentPicker/S_SegmentPickerElement.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/SegmentPicker/S_SegmentPickerElement.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/SegmentPicker/Widget_SegmentButton.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/SegmentPicker/Widget_SegmentButton.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/SegmentPicker/Widget_SegmentPicker.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/SegmentPicker/Widget_SegmentPicker.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/Widget_CircularRadialProgress.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/Widget_CircularRadialProgress.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/Widget_DraggableButton.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/Widget_DraggableButton.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/Widget_Image.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/Widget_Image.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/Widget_Spacer.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/Widget_Spacer.uasset
LFS
Normal file
Binary file not shown.
BIN
Plugins/LibAmasson/Content/Widgets/Widget_Text.uasset
LFS
Normal file
BIN
Plugins/LibAmasson/Content/Widgets/Widget_Text.uasset
LFS
Normal file
Binary file not shown.
30
Plugins/LibAmasson/LibAmasson.uplugin
Normal file
30
Plugins/LibAmasson/LibAmasson.uplugin
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "LibAmasson",
|
||||
"Description": "My plugin of frequently implemented functions",
|
||||
"Category": "Blueprints",
|
||||
"CreatedBy": "Amasson",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": true,
|
||||
"IsBetaVersion": false,
|
||||
"IsExperimentalVersion": false,
|
||||
"Installed": false,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "LibAmasson",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
],
|
||||
"Plugins": [
|
||||
{
|
||||
"Name": "OnlineSubsystemUtils",
|
||||
"Enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Plugins/LibAmasson/Resources/Icon128.png
LFS
Normal file
BIN
Plugins/LibAmasson/Resources/Icon128.png
LFS
Normal file
Binary file not shown.
55
Plugins/LibAmasson/Source/LibAmasson/LibAmasson.Build.cs
Normal file
55
Plugins/LibAmasson/Source/LibAmasson/LibAmasson.Build.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class LibAmasson : ModuleRules
|
||||
{
|
||||
public LibAmasson(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"UMG",
|
||||
"OnlineSubsystemUtils",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Animation/CharacterMovementAnimInstance.h"
|
||||
#include "Kismet/KismetMathLibrary.h"
|
||||
#include "GameFramework/CharacterMovementComponent.h"
|
||||
|
||||
void UCharacterMovementAnimInstance::NativeInitializeAnimation()
|
||||
{
|
||||
Super::NativeInitializeAnimation();
|
||||
|
||||
if (APawn* Owner = TryGetPawnOwner()) {
|
||||
CharacterMovementComponent = Owner->GetComponentByClass<UCharacterMovementComponent>();
|
||||
_PreviousYaw = Owner->GetActorRotation().Yaw;
|
||||
}
|
||||
}
|
||||
|
||||
void UCharacterMovementAnimInstance::NativeUpdateAnimation(float DeltaTime)
|
||||
{
|
||||
Super::NativeUpdateAnimation(DeltaTime);
|
||||
|
||||
if (APawn* Owner = TryGetPawnOwner())
|
||||
{
|
||||
FRotator Rotation = Owner->GetActorRotation();
|
||||
TurnVelocity = (Rotation.Yaw - _PreviousYaw) / DeltaTime;
|
||||
|
||||
if (CharacterMovementComponent)
|
||||
{
|
||||
bFalling = CharacterMovementComponent->IsFalling();
|
||||
bCrouching = CharacterMovementComponent->IsCrouching();
|
||||
bSwimming = CharacterMovementComponent->IsSwimming();
|
||||
|
||||
LocalVelocity = Rotation.UnrotateVector(CharacterMovementComponent->Velocity);
|
||||
LocalVelocityAngle = LocalVelocity.IsNearlyZero() ? 0 : FMath::RadiansToDegrees(FMath::Atan2(LocalVelocity.Y, LocalVelocity.X));
|
||||
|
||||
}
|
||||
|
||||
_PreviousYaw = Rotation.Yaw;
|
||||
}
|
||||
}
|
||||
|
||||
bool UCharacterMovementAnimInstance::IsPawnMoving() const
|
||||
{
|
||||
return LocalVelocity.SquaredLength() > 10;
|
||||
}
|
||||
|
||||
bool UCharacterMovementAnimInstance::IsJumpingUp() const
|
||||
{
|
||||
return LocalVelocity.Z > 0 && bFalling;
|
||||
}
|
||||
|
||||
bool UCharacterMovementAnimInstance::IsFallingDown() const
|
||||
{
|
||||
return LocalVelocity.Z <= 0 && bFalling;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Components/NetInterpToMovementComponent.h"
|
||||
|
||||
|
||||
UNetInterpToMovementComponent::UNetInterpToMovementComponent()
|
||||
{
|
||||
SetIsReplicatedByDefault(true);
|
||||
}
|
||||
|
||||
UNetInterpToMovementComponent::~UNetInterpToMovementComponent()
|
||||
{
|
||||
if (GetOwner() && GetOwner()->GetWorld())
|
||||
GetOwner()->GetWorldTimerManager().ClearTimer(TimerHandle_BroadcastMovement);
|
||||
}
|
||||
|
||||
void UNetInterpToMovementComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
if (AActor* Owner = GetOwner())
|
||||
{
|
||||
if (Owner->HasAuthority())
|
||||
{
|
||||
if (Owner->GetWorld())
|
||||
{
|
||||
Owner->GetWorldTimerManager().SetTimer(TimerHandle_BroadcastMovement, this, &ThisClass::BroadcastMovement, 5.0f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UNetInterpToMovementComponent::BroadcastMovement()
|
||||
{
|
||||
if (GetOwner())
|
||||
NetMulticast_UpdateMovement(GetOwner()->GetActorLocation(), CurrentTime, CurrentDirection, bIsWaiting, bStopped);
|
||||
}
|
||||
|
||||
void UNetInterpToMovementComponent::NetMulticast_UpdateMovement_Implementation(const FVector& Location, float InCurrentTime, float InCurrentDirection, bool bInIsWaiting, bool bInStopped)
|
||||
{
|
||||
FVector Diff = GetOwner()->GetActorLocation() - Location;
|
||||
UE_LOG(LogTemp, Warning, TEXT("Location Difference: %s"), *Diff.ToString());
|
||||
|
||||
if (!Diff.IsNearlyZero())
|
||||
UE_LOG(LogTemp, Warning, TEXT("Location Difference: %s"), *Diff.ToString());
|
||||
|
||||
if (GetOwner())
|
||||
GetOwner()->SetActorLocation(Location);
|
||||
CurrentTime = InCurrentTime;
|
||||
CurrentDirection = InCurrentDirection;
|
||||
bIsWaiting = bInIsWaiting;
|
||||
bStopped = bInStopped;
|
||||
}
|
||||
20
Plugins/LibAmasson/Source/LibAmasson/Private/LibAmasson.cpp
Normal file
20
Plugins/LibAmasson/Source/LibAmasson/Private/LibAmasson.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "LibAmasson.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FLibAmassonModule"
|
||||
|
||||
void FLibAmassonModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
}
|
||||
|
||||
void FLibAmassonModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FLibAmassonModule, LibAmasson)
|
||||
105
Plugins/LibAmasson/Source/LibAmasson/Private/MathLibrary.cpp
Normal file
105
Plugins/LibAmasson/Source/LibAmasson/Private/MathLibrary.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "MathLibrary.h"
|
||||
#include "Kismet/KismetMathLibrary.h"
|
||||
|
||||
|
||||
void UMathLibrary::GetTraceForward(USceneComponent* Component, double Distance, FVector& StartPoint, FVector& EndPoint)
|
||||
{
|
||||
FVector Location = Component->GetComponentLocation();
|
||||
FVector Forward = Component->GetForwardVector();
|
||||
|
||||
StartPoint = Location;
|
||||
EndPoint = Location + Forward * Distance;
|
||||
}
|
||||
|
||||
void UMathLibrary::TraceClampDistance(const FVector& StartPoint, const FVector& EndPoint,
|
||||
double MinDistance, double MaxDistance,
|
||||
FVector& NewStartPoint, FVector& NewEndPoint)
|
||||
{
|
||||
FVector StartToEnd = EndPoint - StartPoint;
|
||||
StartToEnd = UKismetMathLibrary::ClampVectorSize(StartToEnd, MinDistance, MaxDistance);
|
||||
NewStartPoint = StartPoint;
|
||||
NewEndPoint = StartPoint + StartToEnd;
|
||||
}
|
||||
|
||||
FVector UMathLibrary::AddLengthToVector(FVector Vector, double Length)
|
||||
{
|
||||
FVector NewVector = Vector;
|
||||
NewVector.Normalize();
|
||||
return Vector + NewVector * Length;
|
||||
}
|
||||
|
||||
FVector UMathLibrary::SetLengthToVector(FVector Vector, double Length)
|
||||
{
|
||||
FVector NewVector = Vector;
|
||||
NewVector.Normalize();
|
||||
return NewVector * Length;
|
||||
}
|
||||
|
||||
TArray<FVector> UMathLibrary::TransformPoints(const TArray<FVector>& Points, const FTransform& Transform)
|
||||
{
|
||||
TArray<FVector> NewPoints = Points;
|
||||
for (FVector& NewPoint : NewPoints)
|
||||
{
|
||||
NewPoint = Transform.TransformPosition(NewPoint);
|
||||
}
|
||||
return NewPoints;
|
||||
}
|
||||
|
||||
TArray<FTransform> UMathLibrary::TransformTransforms(const TArray<FTransform>& Transforms, const FTransform& Transform)
|
||||
{
|
||||
TArray<FTransform> NewTransforms = Transforms;
|
||||
for (FTransform& NewTransform : NewTransforms)
|
||||
{
|
||||
NewTransform = NewTransform * Transform;
|
||||
}
|
||||
return NewTransforms;
|
||||
}
|
||||
|
||||
void UMathLibrary::ArcPoints(float ArcAngle, int32 Count, float Distance, TArray<FVector>& Points)
|
||||
{
|
||||
if (Count <= 0)
|
||||
return;
|
||||
|
||||
const float StepAngle = ArcAngle / (Count - 1);
|
||||
FVector Direction = Count == 1 ?
|
||||
FVector(1, 0, 0) :
|
||||
FVector(1, 0, 0).RotateAngleAxis(-ArcAngle / 2.0f, FVector::UpVector);
|
||||
|
||||
for (int32 i = 0; i < Count; i++)
|
||||
{
|
||||
const FVector Location = Direction * Distance;
|
||||
|
||||
Points.Add(Location);
|
||||
|
||||
Direction = Direction.RotateAngleAxis(StepAngle, FVector::UpVector);
|
||||
}
|
||||
}
|
||||
|
||||
void UMathLibrary::ArcTransforms(float ArcAngle, int32 Count, float Distance, TArray<FTransform>& Transforms)
|
||||
{
|
||||
if (Count <= 0)
|
||||
return;
|
||||
|
||||
if (Count == 1)
|
||||
{
|
||||
Transforms.Add(FTransform(FVector(Distance, 0.0f, 0.0f)));
|
||||
return;
|
||||
}
|
||||
|
||||
float StepAngle = ArcAngle / static_cast<float>(Count - 1);
|
||||
FRotator DirectionRotator;
|
||||
|
||||
for (int32 i = 0; i < Count; i++)
|
||||
{
|
||||
const FRotator Rotation(0.0f, -(ArcAngle / 2.0f) + i * StepAngle, 0.0f);
|
||||
const FQuat QuatRotation = Rotation.Quaternion();
|
||||
|
||||
const FVector Location = QuatRotation.GetForwardVector() * Distance;
|
||||
|
||||
const FTransform Transform = FTransform(QuatRotation, Location);
|
||||
Transforms.Add(Transform);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Sorting/ObjectSortPredicate.h"
|
||||
|
||||
|
||||
bool UObjectSortPredicate::Compare(UObject* Left, UObject* Right) const
|
||||
{
|
||||
if (CanScorify())
|
||||
return ScorifyElement(Left) < ScorifyElement(Right);
|
||||
|
||||
return BP_Compare(Left, Right);
|
||||
}
|
||||
|
||||
float UObjectSortPredicate::ScorifyElement(UObject* Element) const
|
||||
{
|
||||
return BP_ScorifyElement(Element);
|
||||
}
|
||||
|
||||
TArray<TPair<UObject*, float>> UObjectSortPredicate::ScorifyArray(const TArray<UObject*>& Array) const
|
||||
{
|
||||
checkf(CanScorify(), TEXT("ScorifyArray used on predicate that cannot scorify"));
|
||||
|
||||
TArray<TPair<UObject*, float>> ScorifiedElements;
|
||||
|
||||
for (UObject* Element : Array)
|
||||
{
|
||||
TPair<UObject*, float> ScorifiedElement;
|
||||
ScorifiedElement.Key = Element;
|
||||
ScorifiedElement.Value = ScorifyElement(Element);
|
||||
ScorifiedElements.Add(ScorifiedElement);
|
||||
}
|
||||
return ScorifiedElements;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Sorting/Predicates/DistanceSortPredicate.h"
|
||||
|
||||
|
||||
UDistanceSortPredicate::UDistanceSortPredicate()
|
||||
{
|
||||
bCanScorify = true;
|
||||
}
|
||||
|
||||
float UDistanceSortPredicate::ScorifyElement(UObject* Element) const
|
||||
{
|
||||
FVector Location;
|
||||
|
||||
if (IsValid(Element))
|
||||
{
|
||||
if (AActor* AsActor = Cast<AActor>(Element))
|
||||
Location = AsActor->GetActorLocation();
|
||||
else if (USceneComponent* AsSceneComponent = Cast<USceneComponent>(Element))
|
||||
Location = AsSceneComponent->GetComponentLocation();
|
||||
}
|
||||
else
|
||||
Location = FVector::ZeroVector;
|
||||
|
||||
return (Location - ComparisonPoint).SquaredLength();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Sorting/Predicates/NameSortPredicate.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
|
||||
UNameSortPredicate::UNameSortPredicate()
|
||||
{
|
||||
bCanScorify = false;
|
||||
}
|
||||
|
||||
bool UNameSortPredicate::Compare(UObject* Left, UObject* Right) const
|
||||
{
|
||||
const FString LeftName = UKismetSystemLibrary::GetDisplayName(Left);
|
||||
const FString RightName = UKismetSystemLibrary::GetDisplayName(Right);
|
||||
|
||||
return LeftName <= RightName;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "Sorting/SortingFunctionLibrary.h"
|
||||
|
||||
void USortingFunctionLibrary::SortInPlace(TArray<UObject*>& Array, TSubclassOf<UObjectSortPredicate> PredicateClass)
|
||||
{
|
||||
if (!IsValid(PredicateClass))
|
||||
return;
|
||||
|
||||
UObjectSortPredicate *Predicate = NewObject<UObjectSortPredicate>(GetTransientPackage(), PredicateClass);
|
||||
SortInPlaceUsingPredicate(Array, Predicate);
|
||||
}
|
||||
|
||||
void USortingFunctionLibrary::SortInPlaceUsingPredicate(TArray<UObject*>& Array, UObjectSortPredicate* Predicate)
|
||||
{
|
||||
if (!IsValid(Predicate))
|
||||
return;
|
||||
|
||||
const bool bAscending = Predicate->bSortAscending;
|
||||
if (Predicate->CanScorify())
|
||||
{
|
||||
TArray<TPair<UObject*, float>> ScorifiedArray = Predicate->ScorifyArray(Array);
|
||||
|
||||
ScorifiedArray.Sort([bAscending](TPair<UObject*, float> Left, TPair<UObject*, float> Right) {
|
||||
return bAscending ? Left.Value <= Right.Value : Right.Value <= Left.Value;
|
||||
});
|
||||
|
||||
for (int i = 0; i < ScorifiedArray.Num(); i++)
|
||||
{
|
||||
Array[i] = ScorifiedArray[i].Key;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Array.Sort([Predicate, bAscending](UObject& Left, UObject& Right) {
|
||||
return bAscending ? Predicate->Compare(&Left, &Right) : Predicate->Compare(&Right, &Left);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool USortingFunctionLibrary::IsArraySorted(const TArray<UObject*>& Array, TSubclassOf<UObjectSortPredicate> PredicateClass)
|
||||
{
|
||||
UObjectSortPredicate *Predicate = NewObject<UObjectSortPredicate>(GetTransientPackage(), PredicateClass);
|
||||
return IsArraySortedUsingPredicate(Array, Predicate);
|
||||
}
|
||||
|
||||
bool USortingFunctionLibrary::IsArraySortedUsingPredicate(const TArray<UObject*>& Array, UObjectSortPredicate* Predicate)
|
||||
{
|
||||
// Array of 0 or 1 element is always sorted
|
||||
if (Array.Num() <= 1)
|
||||
return true;
|
||||
|
||||
if (Predicate->CanScorify())
|
||||
{
|
||||
float PreviousElementScore = Predicate->ScorifyElement(Array[0]);
|
||||
for (int32 i = 1; i < Array.Num(); i++)
|
||||
{
|
||||
const float ElementScore = Predicate->ScorifyElement(Array[i]);
|
||||
|
||||
const bool bSorted = Predicate->bSortAscending ?
|
||||
PreviousElementScore <= ElementScore :
|
||||
ElementScore <= PreviousElementScore;
|
||||
|
||||
if (!bSorted)
|
||||
return false;
|
||||
|
||||
PreviousElementScore = ElementScore;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32 i = 1; i < Array.Num(); i++)
|
||||
{
|
||||
const bool bSorted = Predicate->bSortAscending ?
|
||||
Predicate->Compare(Array[i - 1], Array[i]) :
|
||||
Predicate->Compare(Array[i], Array[i - 1]);
|
||||
|
||||
if (!bSorted)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Sort range */
|
||||
|
||||
TArray<UObject*> USortingFunctionLibrary::GetNMin(const TArray<UObject*>& Array, int32 N, TSubclassOf<UObjectSortPredicate> PredicateClass)
|
||||
{
|
||||
UObjectSortPredicate *Predicate = NewObject<UObjectSortPredicate>(GetTransientPackage(), PredicateClass);
|
||||
|
||||
return GetNMinUsingPredicate(Array, N, Predicate);
|
||||
}
|
||||
|
||||
TArray<UObject*> USortingFunctionLibrary::GetNMinUsingPredicate(const TArray<UObject*>& Array, int32 N, UObjectSortPredicate* Predicate)
|
||||
{
|
||||
TArray<UObject*> SortedArray(Array);
|
||||
|
||||
SortInPlaceUsingPredicate(SortedArray, Predicate);
|
||||
|
||||
if (SortedArray.Num() > N)
|
||||
SortedArray.SetNum(N, true);
|
||||
|
||||
return SortedArray;
|
||||
}
|
||||
|
||||
TArray<UObject*> USortingFunctionLibrary::GetNMax(const TArray<UObject*>& Array, int32 N, TSubclassOf<UObjectSortPredicate> PredicateClass)
|
||||
{
|
||||
UObjectSortPredicate *Predicate = NewObject<UObjectSortPredicate>(GetTransientPackage(), PredicateClass);
|
||||
|
||||
return GetNMaxUsingPredicate(Array, N, Predicate);
|
||||
}
|
||||
|
||||
TArray<UObject*> USortingFunctionLibrary::GetNMaxUsingPredicate(const TArray<UObject*>& Array, int32 N, UObjectSortPredicate* Predicate)
|
||||
{
|
||||
TArray<UObject*> SortedArray(Array);
|
||||
|
||||
SortInPlaceUsingPredicate(SortedArray, Predicate);
|
||||
|
||||
for (int32 i = 0; N + i - 1 < SortedArray.Num(); i++)
|
||||
{
|
||||
SortedArray[i] = SortedArray[N + i - 1];
|
||||
}
|
||||
|
||||
if (SortedArray.Num() > N)
|
||||
SortedArray.SetNum(N, true);
|
||||
|
||||
return SortedArray;
|
||||
}
|
||||
|
||||
|
||||
/** Cast */
|
||||
|
||||
TArray<UObject*>& USortingFunctionLibrary::CastArray(TArray<UObject*>& ObjectArray, TSubclassOf<UObject> NewClass, bool bSafe)
|
||||
{
|
||||
if (!bSafe)
|
||||
return ObjectArray;
|
||||
|
||||
for (UObject*& ElementPtr : ObjectArray)
|
||||
{
|
||||
if (IsValid(ElementPtr) && !ElementPtr->IsA(NewClass))
|
||||
ElementPtr = nullptr;
|
||||
}
|
||||
|
||||
return ObjectArray;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "UI/ControllableUserWidget.h"
|
||||
#include "Blueprint/WidgetTree.h"
|
||||
#include "UI/WidgetControllerComponent.h"
|
||||
#include "UI/WidgetController.h"
|
||||
|
||||
|
||||
UWidgetControllerComponent* UControllableUserWidget::GetComponentFromControllerByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass) const
|
||||
{
|
||||
if (!WidgetController) return nullptr;
|
||||
|
||||
return WidgetController->GetComponentByClass(ComponentClass);
|
||||
}
|
||||
|
||||
void UControllableUserWidget::SetWidgetController(UWidgetController* NewWidgetController)
|
||||
{
|
||||
WidgetController = NewWidgetController;
|
||||
WidgetControllerSet(WidgetController);
|
||||
|
||||
PropagateWidgetController(this);
|
||||
}
|
||||
|
||||
bool UControllableUserWidget::AcceptWidgetController(UWidgetController* InWidgetController) const
|
||||
{
|
||||
// We accept invalid objects as widget controllers
|
||||
if (!InWidgetController || !InWidgetController->GetClass())
|
||||
return true;
|
||||
|
||||
// If we have no required class, we accept any of them
|
||||
if (AcceptedControllerClasses.IsEmpty())
|
||||
return true;
|
||||
|
||||
if (AcceptedControllerClasses.Contains(InWidgetController->GetClass()))
|
||||
return true;
|
||||
|
||||
for (TSubclassOf<UWidgetController> AcceptedControllerClass : AcceptedControllerClasses)
|
||||
{
|
||||
if (InWidgetController->GetClass()->IsChildOf(AcceptedControllerClass))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UControllableUserWidget::PropagateWidgetController(UWidget* Parent)
|
||||
{
|
||||
TArray<UWidget*> AllWidgets;
|
||||
WidgetTree->GetAllWidgets(AllWidgets);
|
||||
for (UWidget* Widget : AllWidgets)
|
||||
{
|
||||
if (!IsValid(Widget)) continue;
|
||||
|
||||
if (UControllableUserWidget* ControlledWidget = Cast<UControllableUserWidget>(Widget))
|
||||
{
|
||||
if (ControlledWidget->TakeControllerFromParent && ControlledWidget->AcceptWidgetController(WidgetController))
|
||||
{
|
||||
ControlledWidget->SetWidgetController(WidgetController);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TArray<UWidget*> ChildWidgets;
|
||||
// UWidgetTree::GetChildWidgets(Parent, ChildWidgets);
|
||||
|
||||
// for (UWidget* ChildWidget : ChildWidgets)
|
||||
// {
|
||||
// if (UControllableUserWidget* ControlledWidget = Cast<UControllableUserWidget>(ChildWidget))
|
||||
// {
|
||||
// if (ControlledWidget->TakeControllerFromParent)
|
||||
// {
|
||||
// ControlledWidget->SetWidgetController(WidgetController);
|
||||
// PropagateWidgetController(ChildWidget);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// PropagateWidgetController(ChildWidget);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "UI/WidgetController.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "GameFramework/PlayerState.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "UI/WidgetControllerComponent.h"
|
||||
|
||||
|
||||
UWidgetController::UWidgetController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UWidgetController* UWidgetController::MakeWidgetController(UObject* Outer, TSubclassOf<UWidgetController> WidgetControllerClass, AActor* ObservedActor)
|
||||
{
|
||||
if (!IsValid(WidgetControllerClass))
|
||||
return nullptr;
|
||||
|
||||
UWidgetController* NewWidgetController = NewObject<UWidgetController>(Outer, WidgetControllerClass);
|
||||
|
||||
if (!IsValid(NewWidgetController))
|
||||
return nullptr;
|
||||
|
||||
NewWidgetController->Construct();
|
||||
NewWidgetController->BP_Construct();
|
||||
|
||||
if (IsValid(ObservedActor))
|
||||
NewWidgetController->SetObservedActor(ObservedActor, true);
|
||||
|
||||
return NewWidgetController;
|
||||
}
|
||||
|
||||
void UWidgetController::SetObservedController(AController* InController)
|
||||
{
|
||||
if (!IsValid(InController)) return;
|
||||
|
||||
Controller = InController;
|
||||
if (APlayerController* AsPC = Cast<APlayerController>(InController))
|
||||
PlayerState = AsPC->GetPlayerState<APlayerState>();
|
||||
else
|
||||
PlayerState = nullptr;
|
||||
Pawn = InController->GetPawn();
|
||||
Actor = InController;
|
||||
|
||||
FinishSetObserved();
|
||||
}
|
||||
|
||||
void UWidgetController::SetObservedPlayerState(APlayerState* InPlayerState)
|
||||
{
|
||||
if (!IsValid(InPlayerState)) return;
|
||||
|
||||
Controller = InPlayerState->GetPlayerController();
|
||||
PlayerState = InPlayerState;
|
||||
Pawn = InPlayerState->GetPawn();
|
||||
Actor = InPlayerState;
|
||||
|
||||
FinishSetObserved();
|
||||
}
|
||||
|
||||
void UWidgetController::SetObservedPawn(APawn* InPawn)
|
||||
{
|
||||
if (!IsValid(InPawn)) return;
|
||||
|
||||
Controller = InPawn->GetController();
|
||||
if (APlayerController* AsPC = Cast<APlayerController>(Controller))
|
||||
PlayerState = AsPC->GetPlayerState<APlayerState>();
|
||||
else
|
||||
PlayerState = nullptr;
|
||||
Pawn = InPawn;
|
||||
Actor = InPawn;
|
||||
|
||||
FinishSetObserved();
|
||||
}
|
||||
|
||||
void UWidgetController::SetObservedActor(AActor* InActor, bool bTryCast)
|
||||
{
|
||||
if (!IsValid(InActor)) return;
|
||||
|
||||
if (bTryCast)
|
||||
{
|
||||
if (AController* AsPC = Cast<AController>(InActor))
|
||||
{
|
||||
return SetObservedController(AsPC);
|
||||
}
|
||||
else if (APlayerState* AsPS = Cast<APlayerState>(InActor))
|
||||
{
|
||||
return SetObservedPlayerState(AsPS);
|
||||
}
|
||||
else if (APawn* AsPawn = Cast<APawn>(InActor))
|
||||
{
|
||||
return SetObservedPawn(AsPawn);
|
||||
}
|
||||
}
|
||||
|
||||
Controller = nullptr;
|
||||
PlayerState = nullptr;
|
||||
Pawn = nullptr;
|
||||
Actor = InActor;
|
||||
|
||||
FinishSetObserved();
|
||||
}
|
||||
|
||||
void UWidgetController::BroadcastValues()
|
||||
{
|
||||
for (UWidgetControllerComponent* Component : Components)
|
||||
{
|
||||
Component->BroadcastValues();
|
||||
}
|
||||
BP_BroadcastValues();
|
||||
}
|
||||
|
||||
void UWidgetController::BindCallbacksToDependencies()
|
||||
{
|
||||
for (UWidgetControllerComponent* Component : Components)
|
||||
{
|
||||
Component->BindCallbacksToDependencies();
|
||||
}
|
||||
}
|
||||
|
||||
UWidgetControllerComponent* UWidgetController::GetComponentByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass) const
|
||||
{
|
||||
for (UWidgetControllerComponent* Component : Components)
|
||||
{
|
||||
if (Component->IsA(ComponentClass))
|
||||
{
|
||||
return Component;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UWidgetControllerComponent* UWidgetController::GetComponentByClassAndName(TSubclassOf<UWidgetControllerComponent> ComponentClass, FName ComponentName) const
|
||||
{
|
||||
for (UWidgetControllerComponent* Component : Components)
|
||||
{
|
||||
if (Component->IsA(ComponentClass) && Component->GetFName() == ComponentName)
|
||||
{
|
||||
return Component;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TArray<UWidgetControllerComponent*> UWidgetController::GetComponentsByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass) const
|
||||
{
|
||||
TArray<UWidgetControllerComponent*> ComponentsList;
|
||||
for (UWidgetControllerComponent* Component : Components)
|
||||
{
|
||||
if (Component->IsA(ComponentClass))
|
||||
{
|
||||
ComponentsList.Add(Component);
|
||||
}
|
||||
}
|
||||
return ComponentsList;
|
||||
}
|
||||
|
||||
UWidgetControllerComponent* UWidgetController::AddComponentByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass, FName ComponentName)
|
||||
{
|
||||
UWidgetControllerComponent* NewComponent = NewObject<UWidgetControllerComponent>(this, ComponentClass, ComponentName);
|
||||
Components.Add(NewComponent);
|
||||
return NewComponent;
|
||||
}
|
||||
|
||||
void UWidgetController::FinishSetObserved()
|
||||
{
|
||||
ObservedActorSet();
|
||||
BP_ObservedActorSet();
|
||||
|
||||
BindCallbacksToDependencies();
|
||||
BP_BindCallbacksToDependencies();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "UI/WidgetControllerComponent.h"
|
||||
|
||||
void UWidgetControllerComponent::BroadcastValues()
|
||||
{
|
||||
BP_BroadcastValues();
|
||||
}
|
||||
|
||||
void UWidgetControllerComponent::BindCallbacksToDependencies()
|
||||
{
|
||||
BP_BindCallbacksToDependencies();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Amasson
|
||||
|
||||
|
||||
#include "UI/WidgetControllerComponents/GameManagementWcc.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
|
||||
void UGameManagementWcc::Initialize(UObject* InWorldContextObject)
|
||||
{
|
||||
WorldContextObject = InWorldContextObject;
|
||||
}
|
||||
|
||||
|
||||
/** GameplayStatics */
|
||||
|
||||
void UGameManagementWcc::OpenLevel(FName LevelName, bool bAbsolute, FString Options)
|
||||
{
|
||||
UGameplayStatics::OpenLevel(WorldContextObject, LevelName, bAbsolute, Options);
|
||||
}
|
||||
|
||||
void UGameManagementWcc::OpenLevelBySoftObjectPtr(const TSoftObjectPtr<UWorld> Level, bool bAbsolute, FString Options)
|
||||
{
|
||||
UGameplayStatics::OpenLevelBySoftObjectPtr(WorldContextObject, Level, bAbsolute, Options);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Animation/AnimInstance.h"
|
||||
#include "CharacterMovementAnimInstance.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class LIBAMASSON_API UCharacterMovementAnimInstance : public UAnimInstance
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
virtual void NativeInitializeAnimation() override;
|
||||
virtual void NativeUpdateAnimation(float DeltaTime) override;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = Movement)
|
||||
class UCharacterMovementComponent* CharacterMovementComponent;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
FVector LocalVelocity;
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = Movement)
|
||||
bool IsPawnMoving() const;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
float LocalVelocityAngle = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
float TurnVelocity = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
bool bFalling = false;
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = Movement)
|
||||
bool IsJumpingUp() const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta = (BlueprintThreadSafe), Category = Movement)
|
||||
bool IsFallingDown() const;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
bool bCrouching = false;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = Movement)
|
||||
bool bSwimming = false;
|
||||
|
||||
|
||||
private:
|
||||
float _PreviousYaw = 0;
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/InterpToMovementComponent.h"
|
||||
#include "NetInterpToMovementComponent.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(ClassGroup=Movement, meta=(BlueprintSpawnableComponent),HideCategories=Velocity)
|
||||
class LIBAMASSON_API UNetInterpToMovementComponent : public UInterpToMovementComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UNetInterpToMovementComponent();
|
||||
virtual ~UNetInterpToMovementComponent();
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Network")
|
||||
float MovementUpdatePeriod = 5.0f;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void BeginPlay();
|
||||
|
||||
UPROPERTY()
|
||||
FTimerHandle TimerHandle_BroadcastMovement;
|
||||
|
||||
UFUNCTION()
|
||||
void BroadcastMovement();
|
||||
|
||||
UFUNCTION(NetMulticast, Reliable, Category = "Network")
|
||||
void NetMulticast_UpdateMovement(const FVector& Location, float InCurrentTime, float InCurrentDirection, bool bInIsWaiting, bool bInStopped);
|
||||
|
||||
};
|
||||
15
Plugins/LibAmasson/Source/LibAmasson/Public/LibAmasson.h
Normal file
15
Plugins/LibAmasson/Source/LibAmasson/Public/LibAmasson.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FLibAmassonModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
43
Plugins/LibAmasson/Source/LibAmasson/Public/MathLibrary.h
Normal file
43
Plugins/LibAmasson/Source/LibAmasson/Public/MathLibrary.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "MathLibrary.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class LIBAMASSON_API UMathLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Trace")
|
||||
static void GetTraceForward(USceneComponent* Component, double Distance, FVector& StartPoint, FVector& EndPoint);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Trace")
|
||||
static void TraceClampDistance(const FVector& StartPoint, const FVector& EndPoint, double MinDistance, double MaxDistance, FVector& NewStartPoint, FVector& NewEndPoint);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Vector")
|
||||
static FVector AddLengthToVector(FVector Vector, double Length);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Vector")
|
||||
static FVector SetLengthToVector(FVector Vector, double Length);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Vector")
|
||||
static TArray<FVector> TransformPoints(const TArray<FVector>& Points, const FTransform& Transform);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Vector")
|
||||
static TArray<FTransform> TransformTransforms(const TArray<FTransform>& Transforms, const FTransform& Transform);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Vector")
|
||||
static void ArcPoints(float ArcAngle, int32 Count, float Distance, TArray<FVector>& Points);
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category="Math|Vector")
|
||||
static void ArcTransforms(float ArcAngle, int32 Count, float Distance, TArray<FTransform>& Transforms);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "ObjectSortPredicate.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(Abstract, Blueprintable, BlueprintType)
|
||||
class LIBAMASSON_API UObjectSortPredicate : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
virtual bool Compare(UObject* Left, UObject* Right) const;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, DisplayName = "Compare", Category = "Sorting")
|
||||
bool BP_Compare(UObject* Left, UObject* Right) const;
|
||||
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Sort", meta = (ExposeOnSpawn = true))
|
||||
bool bSortAscending = true;
|
||||
|
||||
/** Scorify */
|
||||
|
||||
FORCEINLINE float CanScorify() const { return bCanScorify; }
|
||||
|
||||
virtual float ScorifyElement(UObject* Element) const;
|
||||
|
||||
/** CanScorify must be activated for this function to be used */
|
||||
UFUNCTION(BlueprintImplementableEvent, DisplayName = "ScorifyElement", Category = "Score")
|
||||
float BP_ScorifyElement(UObject* Element) const;
|
||||
|
||||
TArray<TPair<UObject*, float>> ScorifyArray(const TArray<UObject*>& Array) const;
|
||||
|
||||
protected:
|
||||
|
||||
/** When activated, the sort algorithm will not use the Compare function,
|
||||
* but Instead, will attribute a float value to each elements using the
|
||||
* ScorifyElement function and sort them with this value.
|
||||
* Allowing us to do performance intensive calculations only once per
|
||||
* elements like calculating a distance from a point.
|
||||
*/
|
||||
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Score")
|
||||
bool bCanScorify = false;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Sorting/ObjectSortPredicate.h"
|
||||
#include "DistanceSortPredicate.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(BlueprintType)
|
||||
class LIBAMASSON_API UDistanceSortPredicate : public UObjectSortPredicate
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UDistanceSortPredicate();
|
||||
|
||||
virtual float ScorifyElement(UObject* Element) const override;
|
||||
|
||||
UPROPERTY(BlueprintReadWrite, Category = "Distance", meta = (ExposeOnSpawn = true))
|
||||
FVector ComparisonPoint;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Sorting/ObjectSortPredicate.h"
|
||||
#include "NameSortPredicate.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(BlueprintType)
|
||||
class LIBAMASSON_API UNameSortPredicate : public UObjectSortPredicate
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UNameSortPredicate();
|
||||
|
||||
virtual bool Compare(UObject* Left, UObject* Right) const override;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "Sorting/ObjectSortPredicate.h"
|
||||
#include "SortingFunctionLibrary.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class LIBAMASSON_API USortingFunctionLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static void SortInPlace(UPARAM(Ref) TArray<UObject*>& Array, TSubclassOf<UObjectSortPredicate> PredicateClass);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static void SortInPlaceUsingPredicate(UPARAM(Ref) TArray<UObject*>& Array, UObjectSortPredicate* Predicate);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static bool IsArraySorted(const TArray<UObject*>& Array, TSubclassOf<UObjectSortPredicate> PredicateClass);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static bool IsArraySortedUsingPredicate(const TArray<UObject*>& Array, UObjectSortPredicate* Predicate);
|
||||
|
||||
|
||||
/** Sort range */
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static TArray<UObject*> GetNMin(const TArray<UObject*>& Array, int32 N, TSubclassOf<UObjectSortPredicate> PredicateClass);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static TArray<UObject*> GetNMinUsingPredicate(const TArray<UObject*>& Array, int32 N, UObjectSortPredicate* Predicate);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static TArray<UObject*> GetNMax(const TArray<UObject*>& Array, int32 N, TSubclassOf<UObjectSortPredicate> PredicateClass);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Sort")
|
||||
static TArray<UObject*> GetNMaxUsingPredicate(const TArray<UObject*>& Array, int32 N, UObjectSortPredicate* Predicate);
|
||||
|
||||
|
||||
/** Cast */
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Array", meta = (DeterminesOutputType = "NewClass"))
|
||||
static TArray<UObject*>& CastArray(UPARAM(Ref) TArray<UObject*>& ObjectArray, TSubclassOf<UObject> NewClass, bool bSafe = false);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "ControllableUserWidget.generated.h"
|
||||
|
||||
class UWidgetController;
|
||||
class UWidgetControllerComponent;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class LIBAMASSON_API UControllableUserWidget : public UUserWidget
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Controller|Component", meta = (DeterminesOutputType = "ComponentClass"))
|
||||
UWidgetControllerComponent* GetComponentFromControllerByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Controller")
|
||||
void SetWidgetController(UWidgetController* NewWidgetController);
|
||||
|
||||
protected:
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Controller")
|
||||
void WidgetControllerSet(UWidgetController* NewWidgetController);
|
||||
|
||||
UFUNCTION(Category = "Controller|Propagation")
|
||||
virtual bool AcceptWidgetController(UWidgetController* InWidgetController) const;
|
||||
|
||||
private:
|
||||
|
||||
UFUNCTION()
|
||||
void PropagateWidgetController(UWidget* Parent);
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Controller", meta = (AllowPrivateAccess = true))
|
||||
TObjectPtr<UWidgetController> WidgetController;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Controller|Propagation")
|
||||
bool TakeControllerFromParent = true;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly, Category = "Controller|Propagation")
|
||||
TSet<TSubclassOf<UWidgetController>> AcceptedControllerClasses;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,139 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "UI/WidgetControllerComponent.h"
|
||||
#include "WidgetController.generated.h"
|
||||
|
||||
|
||||
class AController;
|
||||
class APlayerState;
|
||||
class APawn;
|
||||
class ACharacter;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class LIBAMASSON_API UWidgetController : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UWidgetController();
|
||||
|
||||
/** Make and construct a widget controller from the specific class.
|
||||
* If there is an observed actor given, it will cast it to the correct type and
|
||||
* call SetObserved_X with it.
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "WidgetController|Construct", meta = (HidePin = "Outer", DefaultToSelf = "Outer"), meta = (DeterminesOutputType = "WidgetControllerClass"))
|
||||
static UWidgetController* MakeWidgetController(UObject* Outer, TSubclassOf<UWidgetController> WidgetControllerClass, AActor* ObservedActor);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
virtual void SetObservedController(AController* InController);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
virtual void SetObservedPlayerState(APlayerState* InPlayerState);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
virtual void SetObservedPawn(APawn* InPawn);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
virtual void SetObservedActor(AActor* InActor, bool bTryCast = false);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Broadcast")
|
||||
virtual void BroadcastValues();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
FORCEINLINE AController* GetController() const { return Controller; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
FORCEINLINE APlayerState* GetPlayerState() const { return PlayerState; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
FORCEINLINE APawn* GetPawn() const { return Pawn; }
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
AActor* GetObservedActor() const { return Actor; }
|
||||
|
||||
template<class TComponentType>
|
||||
TComponentType* GetComponent()
|
||||
{
|
||||
static_assert(std::is_base_of<UWidgetControllerComponent, TComponentType>::value, "TComponentType must be a subclass of UWidgetControllerComponent.");
|
||||
|
||||
for (UWidgetControllerComponent* Component : Components)
|
||||
{
|
||||
if (TComponentType* CastComponent = Cast<TComponentType>(Component))
|
||||
{
|
||||
return CastComponent;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Component", meta = (DeterminesOutputType = "ComponentClass"))
|
||||
UWidgetControllerComponent* GetComponentByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Component", meta = (DeterminesOutputType = "ComponentClass"))
|
||||
UWidgetControllerComponent* GetComponentByClassAndName(TSubclassOf<UWidgetControllerComponent> ComponentClass, FName ComponentName) const;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Component", meta = (DeterminesOutputType = "ComponentClass"))
|
||||
TArray<UWidgetControllerComponent*> GetComponentsByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass) const;
|
||||
|
||||
template<class TComponentType>
|
||||
TComponentType* AddComponent(FName ComponentName)
|
||||
{
|
||||
static_assert(std::is_base_of<UWidgetControllerComponent, TComponentType>::value, "TComponentType must be a subclass of UWidgetControllerComponent.");
|
||||
|
||||
TComponentType* NewComponent = NewObject<TComponentType>(this, TComponentType::StaticClass(), ComponentName);
|
||||
Components.Add(NewComponent);
|
||||
return NewComponent;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Component", meta = (DeterminesOutputType = "ComponentClass"))
|
||||
UWidgetControllerComponent* AddComponentByClass(TSubclassOf<UWidgetControllerComponent> ComponentClass, FName ComponentName);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
UFUNCTION()
|
||||
virtual void Construct() {}
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Construction", DisplayName = "Construct")
|
||||
void BP_Construct();
|
||||
|
||||
UFUNCTION()
|
||||
virtual void ObservedActorSet() {}
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Observed", DisplayName = "ObservedActorSet")
|
||||
void BP_ObservedActorSet();
|
||||
|
||||
UFUNCTION()
|
||||
virtual void BindCallbacksToDependencies();
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Broadcast", DisplayName = "BindCallbacksToDependencies")
|
||||
void BP_BindCallbacksToDependencies();
|
||||
|
||||
/** Called at the end of controller SetObserved_X */
|
||||
UFUNCTION(BlueprintCallable, Category = "Observed")
|
||||
void FinishSetObserved();
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Broadcast", DisplayName = "BroadcastValues")
|
||||
void BP_BroadcastValues();
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "WidgetController")
|
||||
TObjectPtr<AController> Controller;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "WidgetController")
|
||||
TObjectPtr<APlayerState> PlayerState;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "WidgetController")
|
||||
TObjectPtr<APawn> Pawn;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "WidgetController")
|
||||
TObjectPtr<AActor> Actor;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<TObjectPtr<UWidgetControllerComponent>> Components;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "WidgetControllerComponent.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(Abstract, Blueprintable)
|
||||
class LIBAMASSON_API UWidgetControllerComponent : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Broadcast")
|
||||
virtual void BroadcastValues();
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Broadcast", DisplayName = "BroadcastValues")
|
||||
void BP_BroadcastValues();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
UFUNCTION()
|
||||
virtual void BindCallbacksToDependencies();
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Bind", DisplayName = "BindCallbacksToDependencies")
|
||||
void BP_BindCallbacksToDependencies();
|
||||
|
||||
friend class UWidgetController;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
// Amasson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UI/WidgetControllerComponent.h"
|
||||
#include "GameManagementWcc.generated.h"
|
||||
|
||||
|
||||
class APlayerController;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class LIBAMASSON_API UGameManagementWcc : public UWidgetControllerComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Initialize")
|
||||
void Initialize(UObject* WorldContextObject);
|
||||
|
||||
|
||||
/** GameplayStatics */
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta=(AdvancedDisplay = "2", DisplayName = "Open Level (by Name)"), Category="Game")
|
||||
void OpenLevel(FName LevelName, bool bAbsolute = true, FString Options = FString(TEXT("")));
|
||||
|
||||
UFUNCTION(BlueprintCallable, meta=(AdvancedDisplay = "2", DisplayName = "Open Level (by Object Reference)"), Category="Game")
|
||||
void OpenLevelBySoftObjectPtr(const TSoftObjectPtr<UWorld> Level, bool bAbsolute = true, FString Options = FString(TEXT("")));
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UObject> WorldContextObject;
|
||||
|
||||
};
|
||||
BIN
Plugins/SlotBasedInventorySystem/Content/Tests/TestMap_InventorySystem.umap
LFS
Normal file
BIN
Plugins/SlotBasedInventorySystem/Content/Tests/TestMap_InventorySystem.umap
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user