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)
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||||
TArray<TSubclassOf<UFFState>> States;
|
TSubclassOf<UFFState> EntryState;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
||||||
|
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
|
||||||
|
#if !UE_BUILD_SHIPPING
|
||||||
|
PrimaryComponentTick.bCanEverTick = true;
|
||||||
|
#else
|
||||||
PrimaryComponentTick.bCanEverTick = false;
|
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