Debug SM, expose StateData to blueprint, make state duration optional
This commit is contained in:
		
							parent
							
								
									3938ac54b5
								
							
						
					
					
						commit
						8420f654e8
					
				@ -45,7 +45,7 @@ void UFFState::Update(float OneFrame, const FFFStateContext& InStateContext)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    OnUpdate(OneFrame, InStateContext);
 | 
					    OnUpdate(OneFrame, InStateContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(InStateContext.Parent->GetTicksInState() >= StateDuration)
 | 
					    if(bStateHasDuration && InStateContext.Parent->GetTicksInState() >= StateDuration)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Finish(InStateContext);
 | 
					        Finish(InStateContext);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,14 @@ public:
 | 
				
			|||||||
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
 | 
						UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
 | 
				
			||||||
	FName Name;
 | 
						FName Name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
						 *	True if this state has some duration where it should return to the entry state
 | 
				
			||||||
 | 
						 *	if this state is not cancelled out of by other means.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
 | 
				
			||||||
 | 
						bool bStateHasDuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: this should only be editable if bStateHasDuration is true
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 *	How long this state will be active before finishing if this state is not cancelled out of
 | 
						 *	How long this state will be active before finishing if this state is not cancelled out of
 | 
				
			||||||
	 *	by other means.
 | 
						 *	by other means.
 | 
				
			||||||
 | 
				
			|||||||
@ -14,12 +14,15 @@
 | 
				
			|||||||
/**
 | 
					/**
 | 
				
			||||||
 *	
 | 
					 *	
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
UCLASS()
 | 
					UCLASS(BlueprintType)
 | 
				
			||||||
class UNREALFIGHTINGFRAMEWORK_API UFFStateData : public UDataAsset
 | 
					class UNREALFIGHTINGFRAMEWORK_API UFFStateData : public UDataAsset
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GENERATED_BODY()
 | 
						GENERATED_BODY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
 | 
				
			||||||
 | 
						TSubclassOf<UFFState> EntryState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
 | 
						UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
 | 
				
			||||||
	TArray<TSubclassOf<UFFState>> States;
 | 
						TArray<TSubclassOf<UFFState>> OtherStates;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -5,18 +5,30 @@
 | 
				
			|||||||
// FF includes
 | 
					// FF includes
 | 
				
			||||||
#include "FFState.h"
 | 
					#include "FFState.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !UE_BUILD_SHIPPING
 | 
				
			||||||
 | 
					static int32 StateMachineDebug = 0;
 | 
				
			||||||
 | 
					FAutoConsoleVariableRef CVARStateMachineDebug(TEXT("ff.StateMachine.ShowDebug"),
 | 
				
			||||||
 | 
											StateMachineDebug, 
 | 
				
			||||||
 | 
											TEXT("Print state machine information for character"), 
 | 
				
			||||||
 | 
											ECVF_Cheat);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
UFFStateMachineComponent::UFFStateMachineComponent()
 | 
					UFFStateMachineComponent::UFFStateMachineComponent()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Don't use Unreal's tick instead use a fixed tick
 | 
					    // Don't use Unreal's tick instead use a fixed tick
 | 
				
			||||||
	PrimaryComponentTick.bCanEverTick = false;
 | 
					#if !UE_BUILD_SHIPPING
 | 
				
			||||||
 | 
					    PrimaryComponentTick.bCanEverTick = true;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    PrimaryComponentTick.bCanEverTick = false;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void UFFStateMachineComponent::Initialize()
 | 
					void UFFStateMachineComponent::Initialize(TSubclassOf<UFFState> EntryState, const TArray<TSubclassOf<UFFState>>& InitialStates)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    UFFState* EntryStateInstance = AddState(EntryState);
 | 
					    UFFState* EntryStateInstance = AddState(EntryState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(const TSubclassOf<UFFState>& CurrState : DefaultStates)
 | 
					    for(const TSubclassOf<UFFState>& CurrState : InitialStates)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        AddState(CurrState);
 | 
					        AddState(CurrState);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -134,7 +146,12 @@ void UFFStateMachineComponent::FixedTick(float OneFrame)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    // CurrentState should never be null
 | 
					    // CurrentState should never be null
 | 
				
			||||||
    // TODO: Should probably assert or whatever UE's equivalent is
 | 
					    // TODO: Should probably assert or whatever UE's equivalent is
 | 
				
			||||||
    check(CurrentState);
 | 
					    //check(CurrentState);
 | 
				
			||||||
 | 
					    // TODO: yet another reason I want FULL CONTROL over when my game objects are created and initialized
 | 
				
			||||||
 | 
					    if(!CurrentState)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Should we switch states?
 | 
					    // Should we switch states?
 | 
				
			||||||
    UFFState* StateToTransitionTo = nullptr;
 | 
					    UFFState* StateToTransitionTo = nullptr;
 | 
				
			||||||
@ -161,16 +178,6 @@ void UFFStateMachineComponent::FixedTick(float OneFrame)
 | 
				
			|||||||
        TicksInState++;
 | 
					        TicksInState++;
 | 
				
			||||||
        CurrentState->Update(OneFrame, GetCurrentStateContext());   
 | 
					        CurrentState->Update(OneFrame, GetCurrentStateContext());   
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Debug
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void UFFStateMachineComponent::BeginPlay()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Super::BeginPlay();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Initialize();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -185,7 +192,26 @@ UFFState* UFFStateMachineComponent::FindStateWithName(FName StateName)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UE_LOG(LogTemp, Warning,
 | 
						UE_LOG(LogTemp, Warning,
 | 
				
			||||||
			TEXT("Could not find state in state machine with name %s on %s"), *StateName.ToString(), *Owner->GetName());
 | 
								TEXT("Could not find state in state machine with name %s"), *StateName.ToString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nullptr;
 | 
						return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !UE_BUILD_SHIPPING
 | 
				
			||||||
 | 
					void UFFStateMachineComponent::TickComponent(float DeltaTime, ELevelTick TickType,
 | 
				
			||||||
 | 
					    FActorComponentTickFunction* ThisTickFunction)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Debug
 | 
				
			||||||
 | 
					    if(StateMachineDebug)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        FString SMDebugString = "---State Machine Info---\n";
 | 
				
			||||||
 | 
							SMDebugString.Append(FString::Printf(TEXT("Current State: %s\n"), *CurrentState->Name.ToString()));
 | 
				
			||||||
 | 
							SMDebugString.Append(FString::Printf(TEXT("Current SubState Label: %s\n"), *CurrentSubStateLabel.ToString()));
 | 
				
			||||||
 | 
							SMDebugString.Append(FString::Printf(TEXT("Ticks In State: %lld\n"), TicksInState));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Green, SMDebugString);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@ public:
 | 
				
			|||||||
	/**
 | 
						/**
 | 
				
			||||||
	 *	Creates and adds default states and enters the first state
 | 
						 *	Creates and adds default states and enters the first state
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	void Initialize();
 | 
						void Initialize(TSubclassOf<UFFState> EntryState, const TArray<TSubclassOf<UFFState>>& InitialStates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
	 *	Initializes pointers to what owns this state machine and what avatar this state represents.
 | 
						 *	Initializes pointers to what owns this state machine and what avatar this state represents.
 | 
				
			||||||
@ -116,20 +116,6 @@ protected:
 | 
				
			|||||||
    /** How many ticks have elapsed since the currently active state was entered */
 | 
					    /** How many ticks have elapsed since the currently active state was entered */
 | 
				
			||||||
	int64 TicksInState;
 | 
						int64 TicksInState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 *	The state the state machine will enter when the game begins and the state that will be
 | 
					 | 
				
			||||||
	 *	transitioned into if a state finishes and no other states are eligible for transition.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	UPROPERTY(EditDefaultsOnly, Category="UFF|State Machine")
 | 
					 | 
				
			||||||
	TSubclassOf<UFFState> EntryState;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 *	States classes other than the entry state to create and add to this state machine when the
 | 
					 | 
				
			||||||
	 *	game starts.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	UPROPERTY(EditDefaultsOnly, Category="UFF|State Machine")
 | 
					 | 
				
			||||||
	TArray<TSubclassOf<UFFState>> DefaultStates;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/** Current active state for this state machine */
 | 
						/** Current active state for this state machine */
 | 
				
			||||||
	UPROPERTY()
 | 
						UPROPERTY()
 | 
				
			||||||
	UFFState* CurrentState;
 | 
						UFFState* CurrentState;
 | 
				
			||||||
@ -146,7 +132,9 @@ protected:
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	UFFState* FindStateWithName(FName StateName);
 | 
						UFFState* FindStateWithName(FName StateName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !UE_BUILD_SHIPPING
 | 
				
			||||||
	// UActorComponent interface
 | 
						// UActorComponent interface
 | 
				
			||||||
	virtual void BeginPlay() override;
 | 
						virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
 | 
				
			||||||
	// End of UActorComponent interface
 | 
						// End of UActorComponent interface
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user