孟宇 3 months ago
parent
commit
7b454bfe82

+ 1 - 1
Ability/Plugins/EzAbility/Source/EzAbility/EzAbility.Build.cs

@@ -27,7 +27,7 @@ public class EzAbility : ModuleRules
 			{
 				"Core",
 				"StructUtils",
-				"DeveloperSettings",
+				"DeveloperSettings", "NetCore",
 			}
 		);
 			

+ 10 - 0
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbility.cpp

@@ -6,3 +6,13 @@ UEzAbility::UEzAbility(const FObjectInitializer& ObjectInitializer)
 	: Super(ObjectInitializer)
 {
 }
+
+bool UEzAbility::CanAbility()
+{
+	return false;
+}
+
+bool UEzAbility::ShouldReplicate(const FEzAbilityInstance& Instance) const
+{
+	return true;
+}

+ 80 - 4
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityComponent.cpp

@@ -3,6 +3,8 @@
 
 #include "EzAbilityComponent.h"
 
+#include "Net/UnrealNetwork.h"
+
 
 // Sets default values for this component's properties
 UEzAbilityComponent::UEzAbilityComponent()
@@ -24,17 +26,91 @@ void UEzAbilityComponent::BeginPlay()
 	
 }
 
+void UEzAbilityComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
+{
+	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
+
+	FDoRepLifetimeParams Params;
+	Params.bIsPushBased = true;
+
+	Params.Condition = COND_ReplayOrOwner;
+	DOREPLIFETIME_WITH_PARAMS_FAST(UEzAbilityComponent, AbilityInstances, Params);
+}
+
 
 // Called every frame
-void UEzAbilityComponent::TickComponent(float DeltaTime, ELevelTick TickType,
-                                        FActorComponentTickFunction* ThisTickFunction)
+void UEzAbilityComponent::TickComponent(
+	float DeltaTime,
+	ELevelTick TickType,
+	FActorComponentTickFunction* ThisTickFunction)
 {
 	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
 
-	// ...
+	// EAbilityRunStatus Previous	= AbilityContext.GetAbilityRunStatus();
+	// EAbilityRunStatus Current	= AbilityContext.Tick(DeltaTime);
+	//
+	// if(Previous != Current)
+	// {
+	// 	OnAbilityRunStatusChanged.Broadcast(Current);
+	// }
+}
+
+bool UEzAbilityComponent::ActivateAbility(UEzAbility* Ability, AActor* Instigator)
+{
+	if (GetOwnerRole() == ROLE_SimulatedProxy)
+    {
+    	return false;
+    }
+
+	return true;
+}
+
+bool UEzAbilityComponent::CancelAbility()
+{
+	return true;
+}
+
+void UEzAbilityComponent::OnRep_AbilityInstances()
+{
+}
+
+void UEzAbilityComponent::ClientCancelAbility_Implementation()
+{
+}
+
+void UEzAbilityComponent::ServerCancelAbility_Implementation()
+{
+}
+
+bool UEzAbilityComponent::ServerCancelAbility_Validate()
+{
+	return true;
+}
+
+void UEzAbilityComponent::ClientEndAbility_Implementation()
+{
+}
+
+void UEzAbilityComponent::ServerEndAbility_Implementation()
+{
 }
 
-void UEzAbilityComponent::ActiveAbility()
+bool UEzAbilityComponent::ServerEndAbility_Validate()
+{
+	return true;
+}
+
+void UEzAbilityComponent::ServerActivateAbility_Implementation()
+{
+}
+
+bool UEzAbilityComponent::ServerActivateAbility_Validate()
+{
+	return true;
+}
+
+
+void UEzAbilityComponent::ClientActivateAbility_Implementation()
 {
 }
 

+ 21 - 8
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityContext.cpp

@@ -3,11 +3,24 @@
 
 #include "EzAbilityContext.h"
 
-UEzAbilityContext::UEzAbilityContext(const FObjectInitializer& ObjectInitializer)
-	: Super(ObjectInitializer)
-{
-}
-
-UEzAbilityContext::~UEzAbilityContext()
-{
-}
+#include "EzAbilityTypes.h"
+
+// EAbilityRunStatus FEzAbilityContext::Start()
+// {
+// 	return EAbilityRunStatus::Failed;
+// }
+
+// EAbilityRunStatus FEzAbilityContext::Tick(float DeltaTime)
+// {
+// 	return EAbilityRunStatus::Failed;
+// }
+//
+// EAbilityRunStatus FEzAbilityContext::Stop()
+// {
+// 	return EAbilityRunStatus::Failed;
+// }
+//
+// EAbilityRunStatus FEzAbilityContext::GetAbilityRunStatus() const
+// {
+// 	return EAbilityRunStatus::Failed;
+// }

+ 15 - 0
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityInstance.cpp

@@ -0,0 +1,15 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "EzAbilityInstance.h"
+
+#include "EzAbility.h"
+
+bool FEzAbilityInstance::ShouldReplicate() const
+{
+	if(Ability && Ability->ShouldReplicate(*this))
+	{
+		return true;
+	}
+	return false;
+}

+ 0 - 4
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilitySettings.cpp

@@ -15,10 +15,6 @@ bool UEzAbilitySettings::GetVerbose() const
 	return bVerbose;
 }
 
-UClass* UEzAbilitySettings::GetAbilityContentClass() const
-{
-	return AbilityContentClass;
-}
 
 
 

+ 11 - 11
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityTypes.cpp

@@ -9,34 +9,34 @@ const FEzAbilitySliceHandle FEzAbilitySliceHandle::Failed		= FEzAbilitySliceHand
 const FEzAbilitySliceHandle FEzAbilitySliceHandle::Stopped		= FEzAbilitySliceHandle(StoppedIndex);
 const FEzAbilitySliceHandle FEzAbilitySliceHandle::Root			= FEzAbilitySliceHandle(0);
 
-ESliceRunStatus FEzAbilitySliceHandle::ToCompletionStatus() const
+EAbilityRunStatus FEzAbilitySliceHandle::ToCompletionStatus() const
 {
 	if (Index == SucceededIndex)
 	{
-		return ESliceRunStatus::Succeeded;
+		return EAbilityRunStatus::Succeeded;
 	}
 
 	if (Index == FailedIndex)
 	{
-		return ESliceRunStatus::Failed;
+		return EAbilityRunStatus::Failed;
 	}
 
 	if (Index == StoppedIndex)
 	{
-		return ESliceRunStatus::Stopped;
+		return EAbilityRunStatus::Stopped;
 	}
 	
-	return ESliceRunStatus::Unset;
+	return EAbilityRunStatus::Unset;
 }
 
-FEzAbilitySliceHandle FEzAbilitySliceHandle::FromCompletionStatus(const ESliceRunStatus Status)
+FEzAbilitySliceHandle FEzAbilitySliceHandle::FromCompletionStatus(const EAbilityRunStatus Status)
 {
 	switch (Status) {
-	case ESliceRunStatus::Failed:		return Failed;
-	case ESliceRunStatus::Succeeded:	return Succeeded;
-	case ESliceRunStatus::Stopped:		return Stopped;
-	case ESliceRunStatus::Running:
-	case ESliceRunStatus::Unset:		return {};
+	case EAbilityRunStatus::Failed:		return Failed;
+	case EAbilityRunStatus::Succeeded:	return Succeeded;
+	case EAbilityRunStatus::Stopped:		return Stopped;
+	case EAbilityRunStatus::Running:
+	case EAbilityRunStatus::Unset:		return {};
 	}
 	return {};
 }

+ 3 - 0
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbility.h

@@ -7,6 +7,7 @@
 #include "EzAbilityTypes.h"
 #include "EzAbility.generated.h"
 
+struct FEzAbilityInstance;
 
 UCLASS(Blueprintable, hidecategories=(Internal, Thumbnail), meta = (ShowWorldContextPin, DisplayThumbnail = "true"))
 class UEzAbility : public UDataAsset
@@ -15,6 +16,8 @@ class UEzAbility : public UDataAsset
 public:
 	UEzAbility(const FObjectInitializer& ObjectInitializer);
 
+	virtual bool CanAbility();
+	virtual bool ShouldReplicate(const FEzAbilityInstance& Instance) const;
 protected:
 
 	//Slices

+ 43 - 7
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityComponent.h

@@ -3,11 +3,11 @@
 #pragma once
 
 #include "CoreMinimal.h"
-#include "Runtime/Engine/Classes/Components/ActorComponent.h"
+#include "EzAbilityContext.h"
+#include "EzAbilityInstance.h"
+#include "Components/ActorComponent.h"
 #include "EzAbilityComponent.generated.h"
 
-class UEzAbilityContext;
-
 UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
 class EZABILITY_API UEzAbilityComponent : public UActorComponent
 {
@@ -22,13 +22,49 @@ protected:
 	virtual void BeginPlay() override;
 
 public:
-	// Called every frame
+	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
 	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
 
+	
+	UFUNCTION(BlueprintCallable)
+	bool ActivateAbility(UEzAbility* Ability, AActor* Instigator = nullptr);
+
 	UFUNCTION(BlueprintCallable)
-	void ActiveAbility();
+	bool CancelAbility();
+
+
+	
+	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAbilityRunStatusChanged, EAbilityRunStatus, RunStatus);
+	/** Called when the run status of the Ability has changed */
+	UPROPERTY(BlueprintAssignable, Category = "Ability")
+	FAbilityRunStatusChanged OnAbilityRunStatusChanged;
 
 protected:
-	UPROPERTY(Transient)
-	TObjectPtr<UEzAbilityContext>	AbilityContext;
+	UFUNCTION()
+	void OnRep_AbilityInstances();
+
+	UFUNCTION(Server, reliable, WithValidation)
+	void ServerActivateAbility();
+	
+	UFUNCTION(Client, reliable)
+	void ClientActivateAbility();
+
+	UFUNCTION(Server, reliable, WithValidation)
+	void ServerEndAbility();
+	
+	UFUNCTION(Client, reliable)
+	void ClientEndAbility();
+
+	UFUNCTION(Server, reliable, WithValidation)
+	void ServerCancelAbility();
+	
+	UFUNCTION(Client, reliable)
+	void ClientCancelAbility();
+	
+protected:
+	UPROPERTY(BlueprintReadOnly, Transient, Category="Ability")
+	FEzAbilityContext	AbilityContext;
+
+	UPROPERTY(BlueprintReadOnly, Transient, Category="Ability", ReplicatedUsing=OnRep_AbilityInstances)
+	FEzAbilityInstanceContainer	AbilityInstances;
 };

+ 7 - 5
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityContext.h

@@ -11,14 +11,16 @@ class UEzAbilityComponent;
 /**
  * 
  */
-UCLASS()
-class EZABILITY_API UEzAbilityContext : public UObject
+USTRUCT(BlueprintType)
+struct EZABILITY_API FEzAbilityContext
 {
 	GENERATED_BODY()
 public:
-	UEzAbilityContext(const FObjectInitializer& ObjectInitializer);
-	virtual ~UEzAbilityContext();
-	
+	// EAbilityRunStatus Start();
+	// EAbilityRunStatus Tick(float DeltaTime);
+	// EAbilityRunStatus Stop();
+	//
+	// EAbilityRunStatus GetAbilityRunStatus() const;
 protected:
 	UPROPERTY(Transient)
 	TObjectPtr<UEzAbilityComponent>	Component;

+ 78 - 0
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityInstance.h

@@ -0,0 +1,78 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "Net/Serialization/FastArraySerializer.h"
+#include "UObject/Object.h"
+#include "EzAbilityInstance.generated.h"
+
+class UEzAbility;
+class UEzAbilityComponent;
+
+
+USTRUCT(BlueprintType)
+struct EZABILITY_API FEzAbilityInstance : public FFastArraySerializerItem
+{
+	GENERATED_USTRUCT_BODY()
+
+PRAGMA_DISABLE_DEPRECATION_WARNINGS
+	FEzAbilityInstance(const FEzAbilityInstance&) = default;
+	FEzAbilityInstance(FEzAbilityInstance&&) = default;
+	FEzAbilityInstance& operator=(const FEzAbilityInstance&) = default;
+	FEzAbilityInstance& operator=(FEzAbilityInstance&&) = default;
+	~FEzAbilityInstance() = default;
+PRAGMA_ENABLE_DEPRECATION_WARNINGS
+
+	FEzAbilityInstance() : Ability(nullptr) {}
+
+	bool ShouldReplicate() const;
+	
+protected:
+	UPROPERTY()
+	TObjectPtr<UEzAbility>	Ability;
+	
+};
+
+USTRUCT(BlueprintType)
+struct EZABILITY_API FEzAbilityInstanceContainer : public FFastArraySerializer
+{
+	GENERATED_USTRUCT_BODY()
+
+	UPROPERTY()
+	TArray<FEzAbilityInstance> Items;
+
+	UPROPERTY(NotReplicated)
+	TObjectPtr<UEzAbilityComponent> Owner;
+	
+	bool NetDeltaSerialize(FNetDeltaSerializeInfo & DeltaParms)
+	{
+		return FFastArraySerializer::FastArrayDeltaSerialize<FEzAbilityInstance, FEzAbilityInstanceContainer>(Items, DeltaParms, *this);
+	}
+
+	template< typename Type, typename SerializerType >
+	bool ShouldWriteFastArrayItem(const Type& Item, const bool bIsWritingOnClient)
+	{
+		// if we do not want the FGameplayAbilitySpec to replicated return false;
+		if (!Item.ShouldReplicate())
+		{
+			return false;
+		}
+
+		if (bIsWritingOnClient)
+		{
+			return Item.ReplicationID != INDEX_NONE;
+		}
+
+		return true;
+	}
+};
+
+template<>
+struct TStructOpsTypeTraits< FEzAbilityInstanceContainer > : public TStructOpsTypeTraitsBase2< FEzAbilityInstanceContainer >
+{
+	enum
+	{
+		WithNetDeltaSerializer = true,
+	};
+};

+ 1 - 1
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilitySettingInterface.h

@@ -23,5 +23,5 @@ class EZABILITY_API IEzAbilitySettingInterface
 	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
 public:
 	virtual bool	GetVerbose()				const = 0;
-	virtual UClass* GetAbilityContentClass()	const = 0;
+
 };

+ 1 - 3
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilitySettings.h

@@ -20,11 +20,9 @@ public:
 	UEzAbilitySettings(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
 
 	virtual bool	GetVerbose()				const override;
-	virtual UClass* GetAbilityContentClass()	const override;
+
 protected:
 	UPROPERTY(Config, EditAnywhere, Category = Debug, meta = (DisplayName = "Log Verbose Output"))
 	bool bVerbose = false;
 	
-	UPROPERTY(Config, EditAnywhere, Category = Ability)
-	TSubclassOf<UEzAbilityContext>	AbilityContentClass;
 };

+ 3 - 3
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityTypes.h

@@ -7,7 +7,7 @@
 #include "EzAbilityTypes.generated.h"
 
 UENUM(BlueprintType)
-enum class ESliceRunStatus : uint8
+enum class EAbilityRunStatus : uint8
 {
 	Running,
 	Failed,
@@ -71,8 +71,8 @@ struct EZABILITY_API FEzAbilitySliceHandle
 		}
 	}
 
-	ESliceRunStatus ToCompletionStatus() const;
-	static FEzAbilitySliceHandle FromCompletionStatus(const ESliceRunStatus Status);
+	EAbilityRunStatus ToCompletionStatus() const;
+	static FEzAbilitySliceHandle FromCompletionStatus(const EAbilityRunStatus Status);
 	
 	UPROPERTY()
 	uint16 Index = InvalidIndex;

+ 1 - 1
Ability/Source/Ability/AbilityCharacter.cpp

@@ -62,7 +62,7 @@ void AAbilityCharacter::OnAttackPress()
 
 void AAbilityCharacter::OnAttackRelease()
 {
-	AbilityComponent->ActiveAbility();
+	AbilityComponent->ActivateAbility(nullptr);
 }
 
 void AAbilityCharacter::BeginPlay()