孟宇 5 mesiacov pred
rodič
commit
f1d92a7946

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

@@ -9,6 +9,12 @@ UEzAbility::UEzAbility(const FObjectInitializer& ObjectInitializer)
 {
 }
 
+bool UEzAbility::IsReadyToRun() const
+{
+	// Valid tree must have at least one state and valid instance data.
+	return States.Num() > 0 && bIsLinked && PropertyBindings.IsValid();
+}
+
 bool UEzAbility::CanActivateAbility(FEzAbilityContext& Context, FText& OutText) const
 {
 	return K2_CanActivateAbility(Context, OutText);

+ 18 - 9
Ability/Plugins/EzAbility/Source/EzAbility/Private/EzAbilityContext.cpp

@@ -67,9 +67,15 @@
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 ///Ability Context
 
-FEzAbilityContext::FEzAbilityContext(UObject& InOwner, const UEzAbility& InAbility,
-	FEzAbilityInstanceData& InInstanceData, const FOnCollectEzAbilityExternalData& CollectExternalDataCallback)
+FEzAbilityContext::FEzAbilityContext(
+	UObject& InOwner,
+	const UEzAbility& InAbility,
+	FEzAbilityInstanceData& InInstanceData,
+	const FOnCollectEzAbilityExternalData& InCollectExternalDataCallback)
+		: InstanceData(InInstanceData), Ability(InAbility), Owner(&InOwner), CollectExternalDataDelegate(InCollectExternalDataCallback)
 {
+	InstanceDataStorage = &InstanceData.GetMutableStorage();
+	check(InstanceDataStorage);
 }
 
 FEzAbilityContext::~FEzAbilityContext()
@@ -78,9 +84,10 @@ FEzAbilityContext::~FEzAbilityContext()
 
 void FEzAbilityContext::InitContext(UEzAbilityComponent* Component)
 {
-	AbilityComponent = Component;
-	OwnerActor		 = Component->GetOwner();
-
+	AbilityComponent	= Component;
+	Owner				= Component->GetOwner();
+	OwnerActor			= Component->GetOwner();
+	
 	AActor* TestActor = OwnerActor.Get();
 
 	while (TestActor != nullptr)
@@ -137,7 +144,7 @@ bool FEzAbilityContext::IsNetAuthority() const
 
 bool FEzAbilityContext::IsValid() const
 {
-	return OwnerActor != nullptr && AbilityComponent != nullptr;
+	return Ability && Ability->IsReadyToRun();
 }
 
 bool FEzAbilityContext::SetGlobalParameters(const FInstancedPropertyBag& Parameters) const
@@ -187,7 +194,7 @@ EAbilityRunStatus FEzAbilityContext::Start(UEzAbility* InAbility, const FEzAbili
 
 	SetGlobalParameters(Ability->GetDefaultParameters());
 	
-	FEzAbilityExecutionFrame InitFrame = State.ActiveFrames.AddDefaulted_GetRef();
+	FEzAbilityExecutionFrame& InitFrame = State.ActiveFrames.AddDefaulted_GetRef();
 	InitFrame.Ability			= Ability;
 	InitFrame.RootState			= FEzAbilityStateHandle::Root;
 	InitFrame.ActiveStates		= {};
@@ -199,7 +206,7 @@ EAbilityRunStatus FEzAbilityContext::Start(UEzAbility* InAbility, const FEzAbili
 	//TODO 设置InstanceData
 	
 	
-	return EAbilityRunStatus::Succeeded;
+	return EAbilityRunStatus::Running;
 }
 
 EAbilityRunStatus FEzAbilityContext::GetAbilityRunStatus() const
@@ -322,8 +329,10 @@ FString FEzAbilityContext::GetInstanceDescription() const
 void FEzAbilityContext::UpdateInstanceData(TConstArrayView<FEzAbilityExecutionFrame> CurrentActiveFrames, TArrayView<FEzAbilityExecutionFrame> NextActiveFrames)
 {
 	int32 EstimatedNumStructs = 0;
-	for (FEzAbilityExecutionFrame& Frame : NextActiveFrames)
+	for (int32 FrameIndex = 0; FrameIndex < NextActiveFrames.Num(); FrameIndex++)
 	{
+		FEzAbilityExecutionFrame& Frame = NextActiveFrames[FrameIndex];
+		
 		if(Frame.bIsGlobalFrame)
 		{
 			EstimatedNumStructs += Frame.Ability->NumGlobalInstanceData;

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

@@ -20,7 +20,8 @@ class EZABILITY_API UEzAbility : public UDataAsset
 	GENERATED_BODY()
 public:
 	UEzAbility(const FObjectInitializer& ObjectInitializer);
-	
+
+	virtual bool IsReadyToRun() const;
 	virtual bool CanActivateAbility(FEzAbilityContext& Context, FText& OutText) const;
 	virtual bool ShouldReplicate(const FEzAbilityInstance& Instance) const;
 

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

@@ -58,8 +58,8 @@ public:
 	bool IsValid() const;
 	bool SetGlobalParameters(const FInstancedPropertyBag& Parameters) const;
 	
-	UObject*	GetOwner() const { return OwnerActor; }
-	UWorld*		GetWorld() const { return OwnerActor->GetWorld(); };
+	UObject*	GetOwner() const { return Owner; }
+	UWorld*		GetWorld() const { return Owner->GetWorld(); };
 	
 	const	FEzAbilityInstanceData* GetInstanceData()			const	{ return &InstanceData; }
 			FEzAbilityInstanceData* GetMutableInstanceData()			{ return &InstanceData; }
@@ -93,7 +93,10 @@ protected:
 	TObjectPtr<UEzAbilityComponent>	AbilityComponent;
 	
 	UPROPERTY(Transient)
-	TObjectPtr<UEzAbility>			Ability;
+	TObjectPtr<const UEzAbility>	Ability;
+	
+	UPROPERTY(Transient)
+	TObjectPtr<UObject>				Owner;
 	
 	UPROPERTY(Transient)
 	TObjectPtr<AActor>				OwnerActor;
@@ -107,6 +110,7 @@ protected:
 	UPROPERTY(Transient)
 	FEzAbilityTarget				Target;
 
+	FOnCollectEzAbilityExternalData CollectExternalDataDelegate;
 public:
 	/** Helper struct to track currently processed frame. */
 	struct FCurrentlyProcessedFrameScope

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

@@ -356,7 +356,7 @@ struct EZABILITY_API FEzAbilityExecutionFrame
 	}
 	
 	UPROPERTY()
-	TObjectPtr<class UEzAbility> Ability = nullptr;
+	TObjectPtr<const class UEzAbility> Ability = nullptr;
 
 	UPROPERTY()
 	FEzAbilityActiveStates ActiveStates;

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

@@ -30,7 +30,7 @@ struct EZABILITY_API FEzAbilityTemporaryInstanceData
 	GENERATED_BODY()
 
 	UPROPERTY()
-	TObjectPtr<class UEzAbility> Ability = nullptr;
+	TObjectPtr<const class UEzAbility> Ability = nullptr;
 
 	UPROPERTY()
 	FEzAbilityStateHandle RootState = FEzAbilityStateHandle::Invalid;

+ 1 - 2
Ability/Plugins/EzAbility/Source/EzAbility/Public/EzAbilityNodeBase.h

@@ -27,8 +27,7 @@ PRAGMA_DISABLE_DEPRECATION_WARNINGS
 PRAGMA_ENABLE_DEPRECATION_WARNINGS
 
 	virtual ~FEzAbilityNodeBase() = default;
-
-	virtual UStruct* GetInstanceDataType() const { return nullptr; }
+	virtual const UStruct* GetInstanceDataType() const { return nullptr; }
 	virtual bool Link(FEzAbilityLinker& Linker) { return true; }
 	/**
 	 * Called during State Tree compilation, allows to modify and validate the node and instance data.

+ 46 - 6
Ability/Plugins/EzAbility/Source/EzAbilityTest/Private/EzAbilityTest.cpp

@@ -5,6 +5,8 @@
 
 #include "AITestsCommon.h"
 #include "EzAbility.h"
+#include "EzAbilityCompiler.h"
+#include "EzAbilityCompilerLog.h"
 #include "EzAbilityComponent.h"
 #include "EzAbilityEditorData.h"
 #include "EzAblityTestTypes.h"
@@ -35,6 +37,44 @@ struct FEzAbilityTest_MakeAndBakeEzAbility : FAITestBase
 {
 	virtual bool InstantTest() override
 	{
+		UEzAbility& EzAbility = UE::EzAbility::Tests::NewAbility(&GetWorld());
+		UEzAbilityEditorData& EditorData = *Cast<UEzAbilityEditorData>(EzAbility.EditorData);
+		
+		UEzAbilityState& Root = EditorData.AddSubTree(FName(TEXT("Root")));
+		UEzAbilityState& StateA = Root.AddChildState(FName(TEXT("A")));
+		UEzAbilityState& StateB = Root.AddChildState(FName(TEXT("B")));
+
+		// Root
+		auto& EvalA = EditorData.AddEvaluator<FTestEval_A>();
+		
+		// State A
+		auto& TaskB1 = StateA.AddTask<FTestTask_B>();
+		EditorData.AddPropertyBinding(EvalA, TEXT("IntA"), TaskB1, TEXT("IntB"));
+
+		// auto& IntCond = StateA.AddEnterCondition<FEzAbilityCompareIntCondition>(EGenericAICheck::Less);
+		// IntCond.GetInstanceData().Right = 2;
+		//
+		// EditorData.AddPropertyBinding(EvalA, TEXT("IntA"), IntCond, TEXT("Left"));
+
+		StateA.AddTransition(EEzAbilityTransitionTrigger::OnStateCompleted, EEzAbilityTransitionType::GotoState, &StateB);
+
+		// State B
+		auto& TaskB2 = StateB.AddTask<FTestTask_B>();
+		EditorData.AddPropertyBinding(EvalA, TEXT("bBoolA"), TaskB2, TEXT("bBoolB"));
+
+		FEzAbilityTransition& Trans = StateB.AddTransition({}, EEzAbilityTransitionType::GotoState, &Root);
+		// auto& TransFloatCond = Trans.AddCondition<FEzAbilityCompareFloatCondition>(EGenericAICheck::Less);
+		// TransFloatCond.GetInstanceData().Right = 13.0f;
+		//EditorData.AddPropertyBinding(EvalA, TEXT("FloatA"), TransFloatCond, TEXT("Left"));
+
+		StateB.AddTransition(EEzAbilityTransitionTrigger::OnStateCompleted, EEzAbilityTransitionType::Succeeded);
+
+		FEzAbilityCompilerLog Log;
+		FEzAbilityCompiler Compiler(Log);
+		const bool bResult = Compiler.Compile(EzAbility);
+
+		AITEST_TRUE("EzAbility should get compiled", bResult);
+		AITEST_TRUE("EzAbility should be ready to run", EzAbility.IsReadyToRun());
 		return true;
 	}
 };
@@ -53,12 +93,12 @@ struct FEzAbilityTest_EmptyAbility : FAITestBase
 		UEzAbilityState& Root = EditorData.AddSubTree(FName(TEXT("Root")));
 		Root.AddTransition(EEzAbilityTransitionTrigger::OnStateCompleted, EEzAbilityTransitionType::Succeeded);
 
-		// FEzAbilityCompilerLog Log;
-		// FEzAbilityCompiler Compiler(Log);
-		// const bool bResult = Compiler.Compile(EzAbility);
-		//
-		// AITEST_TRUE("EzAbility should get compiled", bResult);
-		//
+		FEzAbilityCompilerLog Log;
+		FEzAbilityCompiler Compiler(Log);
+		const bool bResult = Compiler.Compile(Ability);
+		
+		AITEST_TRUE("EzAbility should get compiled", bResult);
+		
 		EAbilityRunStatus Status = EAbilityRunStatus::Unset;
 		FEzAbilityInstanceData InstanceData;
 		FTestEzAbilityExecutionContext Exec(Ability, Ability, InstanceData);

+ 65 - 65
Ability/Plugins/EzAbility/Source/EzAbilityTest/Private/EzAblityTestTypes.h

@@ -93,71 +93,71 @@ struct FTestEzAbilityExecutionContext : public FEzAbilityContext
 	
 };
 
-// USTRUCT()
-// struct FTestEval_AInstanceData
-// {
-// 	GENERATED_BODY()
-// 	
-// 	UPROPERTY(EditAnywhere, Category = Parameter)
-// 	float FloatA = 0.0f;
-//
-// 	UPROPERTY(EditAnywhere, Category = Parameter)
-// 	int32 IntA = 0;
-//
-// 	UPROPERTY(EditAnywhere, Category = Parameter)
-// 	bool bBoolA = false;
-// };
-//
-// USTRUCT()
-// struct FTestEval_A : public FEzAbilityEvaluator
-// {
-// 	GENERATED_BODY()
-//
-// 	using FInstanceDataType = FTestEval_AInstanceData;
-//
-// 	FTestEval_A() = default;
-// 	FTestEval_A(const FName InName) { Name = InName; }
-// 	virtual ~FTestEval_A() override {}
-//
-// 	virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }
-// };
-//
-// USTRUCT()
-// struct FTestTask_BInstanceData
-// {
-// 	GENERATED_BODY()
-//
-// 	UPROPERTY(EditAnywhere, Category = Parameter)
-// 	float FloatB = 0.0f;
-//
-// 	UPROPERTY(EditAnywhere, Category = Parameter)
-// 	int32 IntB = 0;
-//
-// 	UPROPERTY(EditAnywhere, Category = Parameter)
-// 	bool bBoolB = false;
-// };
-//
-// USTRUCT()
-// struct FTestTask_B : public FEzAbilityTask
-// {
-// 	GENERATED_BODY()
-//
-// 	using FInstanceDataType = FTestTask_BInstanceData;
-//
-// 	FTestTask_B() = default;
-// 	FTestTask_B(const FName InName) { Name = InName; }
-// 	virtual ~FTestTask_B() override {}
-// 	
-// 	virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }
-//
-// 	virtual EAbilityRunStatus EnterState(FEzAbilityContext& Context, const FEzAbilityTransitionResult& Transition) const override
-// 	{
-// 		FTestEzAbilityExecutionContext& TestContext = static_cast<FTestEzAbilityExecutionContext&>(Context);
-// 		TestContext.Log(Name,  TEXT("EnterState"));
-// 		return EAbilityRunStatus::Running;
-// 	}
-// };
-//
+USTRUCT()
+struct FTestEval_AInstanceData
+{
+	GENERATED_BODY()
+	
+	UPROPERTY(EditAnywhere, Category = Parameter)
+	float FloatA = 0.0f;
+
+	UPROPERTY(EditAnywhere, Category = Parameter)
+	int32 IntA = 0;
+
+	UPROPERTY(EditAnywhere, Category = Parameter)
+	bool bBoolA = false;
+};
+
+USTRUCT()
+struct FTestEval_A : public FEzAbilityEvaluator
+{
+	GENERATED_BODY()
+
+	using FInstanceDataType = FTestEval_AInstanceData;
+
+	FTestEval_A() = default;
+	FTestEval_A(const FName InName) { Name = InName; }
+	virtual ~FTestEval_A() override {}
+
+	virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }
+};
+
+USTRUCT()
+struct FTestTask_BInstanceData
+{
+	GENERATED_BODY()
+
+	UPROPERTY(EditAnywhere, Category = Parameter)
+	float FloatB = 0.0f;
+
+	UPROPERTY(EditAnywhere, Category = Parameter)
+	int32 IntB = 0;
+
+	UPROPERTY(EditAnywhere, Category = Parameter)
+	bool bBoolB = false;
+};
+
+USTRUCT()
+struct FTestTask_B : public FEzAbilityTask
+{
+	GENERATED_BODY()
+
+	using FInstanceDataType = FTestTask_BInstanceData;
+
+	FTestTask_B() = default;
+	FTestTask_B(const FName InName) { Name = InName; }
+	virtual ~FTestTask_B() override {}
+	
+	virtual const UStruct* GetInstanceDataType() const override { return FInstanceDataType::StaticStruct(); }
+
+	virtual EAbilityRunStatus EnterState(FEzAbilityContext& Context, const FEzAbilityTransitionResult& Transition) const override
+	{
+		FTestEzAbilityExecutionContext& TestContext = static_cast<FTestEzAbilityExecutionContext&>(Context);
+		TestContext.Log(Name,  TEXT("EnterState"));
+		return EAbilityRunStatus::Running;
+	}
+};
+
 // USTRUCT()
 // struct FTestTask_PrintValueInstanceData
 // {