Removed 'autofinish' from the animation C++ system, replaced it with more elegant implementation in blueprint.

This commit is contained in:
2025-09-22 16:17:21 -04:00
parent e8bc3389a6
commit 4b0f85ef19
11 changed files with 47 additions and 75 deletions

Binary file not shown.

View File

@@ -335,9 +335,6 @@ FlxAnimTracker::FlxAnimTracker() {
void FlxAnimTracker::Clear() { void FlxAnimTracker::Clear() {
AQ.Empty(); AQ.Empty();
Changed = true; Changed = true;
AutoFinish = false;
AutoFinishAction.Empty();
AutoFinishXYZ.Set(0,0,0);
} }
void FlxAnimTracker::FinishedAnimation(uint64 hash) { void FlxAnimTracker::FinishedAnimation(uint64 hash) {
@@ -349,6 +346,15 @@ void FlxAnimTracker::FinishedAnimation(uint64 hash) {
} }
} }
bool FlxAnimTracker::IsFinished(uint64 hash) {
for (int i = 0; i < AQ.Num(); i++) {
if (AQ[i].Hash == hash) {
return AQ[i].Finished;
}
}
return true;
}
void FlxAnimTracker::SkipToEnd() { void FlxAnimTracker::SkipToEnd() {
for (int i = 0; i < AQ.Num(); i++) { for (int i = 0; i < AQ.Num(); i++) {
if (!AQ[i].Finished) { if (!AQ[i].Finished) {
@@ -459,22 +465,6 @@ void FlxAnimTracker::Update(std::string_view encqueue) {
} }
AQ.SetNum(limit); AQ.SetNum(limit);
} }
// Autofinish up to one animation.
//
if (AutoFinish) {
for (int i = 0; i < AQ.Num(); i++) {
if (!AQ[i].Finished) {
if (MatchesAutoFinish(AQ[i])) {
AQ[i].Finished = true;
}
break;
}
}
AutoFinish = false;
AutoFinishAction.Empty();
AutoFinishXYZ.Set(0,0,0);
}
} }
FString FlxAnimTracker::DebugString() const FString FlxAnimTracker::DebugString() const
@@ -488,14 +478,6 @@ FString FlxAnimTracker::DebugString() const
{ {
Result += TEXT("changed=false "); Result += TEXT("changed=false ");
} }
if (AutoFinish)
{
Result += TEXT("autofinish=true");
}
else
{
Result += TEXT("autofinish=false");
}
Result += TEXT("\n"); Result += TEXT("\n");
for (int i = 0; i < AQ.Num(); i++) for (int i = 0; i < AQ.Num(); i++)
{ {
@@ -505,20 +487,6 @@ FString FlxAnimTracker::DebugString() const
return Result; return Result;
} }
void FlxAnimTracker::SetAutoFinish(const FString &action, const FVector &xyz) {
AutoFinish = true;
AutoFinishAction = action;
AutoFinishXYZ = xyz;
}
bool FlxAnimTracker::MatchesAutoFinish(const FlxAnimationStep &step) {
FVector xyz = UlxAnimationStepLibrary::AnimationStepGetVector(step, TEXT("xyz"));
if (xyz != AutoFinishXYZ) return false;
FString action = UlxAnimationStepLibrary::AnimationStepGetString(step, TEXT("action"));
if (action != AutoFinishAction) return false;
return true;
}
FString FlxAnimTracker::GetCurrentBlueprintName() { FString FlxAnimTracker::GetCurrentBlueprintName() {
for (int i = 0; i < AQ.Num(); i++) { for (int i = 0; i < AQ.Num(); i++) {
if (!AQ[i].Finished) { if (!AQ[i].Finished) {

View File

@@ -256,15 +256,6 @@ public:
// True if something has recently changed. // True if something has recently changed.
// //
bool Changed; bool Changed;
// Autofinish parameters.
//
bool AutoFinish;
FString AutoFinishAction;
FVector AutoFinishXYZ;
private:
bool MatchesAutoFinish(const FlxAnimationStep &step);
public: public:
// Construct a tracker. // Construct a tracker.
@@ -284,14 +275,6 @@ public:
// //
void Update(std::string_view encqueue); void Update(std::string_view encqueue);
// Auto-finish animation.
//
// Next time 'update' is called, we will check for the presence
// of a new animation matching these parameters. If there is
// one, it is automatically marked 'finished'.
//
void SetAutoFinish(const FString &action, const FVector &xyz);
// Get the current blueprint name, as a string. // Get the current blueprint name, as a string.
// //
FString GetCurrentBlueprintName(); FString GetCurrentBlueprintName();
@@ -312,6 +295,12 @@ public:
// //
void FinishedAnimation(uint64 Hash); void FinishedAnimation(uint64 Hash);
// Return true if an animation step is marked finished.
//
// Also return true if the animation step is not found.
//
bool IsFinished(uint64 Hash);
// Skip to the end of the animation queue. // Skip to the end of the animation queue.
// //
// This is equivalent to calling 'FinishedHash' on every // This is equivalent to calling 'FinishedHash' on every

View File

@@ -6,6 +6,7 @@
#include "Kismet/KismetSystemLibrary.h" #include "Kismet/KismetSystemLibrary.h"
#include "Kismet2/KismetDebugUtilities.h" #include "Kismet2/KismetDebugUtilities.h"
#include "Kismet/KismetTextLibrary.h" #include "Kismet/KismetTextLibrary.h"
#include "AnimQueue.h"
ELogVerbosity::Type UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(ElxLogVerbosity Verbosity) { ELogVerbosity::Type UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(ElxLogVerbosity Verbosity) {
switch (Verbosity) { switch (Verbosity) {
@@ -207,6 +208,15 @@ FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataLuaValues(const UlxL
return Result; return Result;
} }
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataAnimationStep(const FlxAnimationStep &Value, const FString &Name)
{
FFormatArgumentData Result;
Result.ArgumentValueType = EFormatArgumentType::Text;
Result.ArgumentName = Name;
Result.ArgumentValue = FText::FromString(UlxAnimationStepLibrary::AnimationStepDebugString(Value));
return Result;
}
FFormatArgumentData UlxBlueprintErrorLibrary::FormatArgumentDataBlank(const FString &Name) FFormatArgumentData UlxBlueprintErrorLibrary::FormatArgumentDataBlank(const FString &Name)
{ {
FFormatArgumentData Result; FFormatArgumentData Result;

View File

@@ -17,6 +17,7 @@
#include "BlueprintErrors.generated.h" #include "BlueprintErrors.generated.h"
class UlxLuaValues; class UlxLuaValues;
struct FlxAnimationStep;
/* /*
* enum class ElxLogVerbosity, below, contains all the same error severity levels * enum class ElxLogVerbosity, below, contains all the same error severity levels
@@ -150,6 +151,9 @@ public:
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility") UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
static FFormatArgumentData FormatArgumentDataLuaValues(const UlxLuaValues *Value, const FString &Name); static FFormatArgumentData FormatArgumentDataLuaValues(const UlxLuaValues *Value, const FString &Name);
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
static FFormatArgumentData FormatArgumentDataAnimationStep(const FlxAnimationStep &Value, const FString &Name);
}; };
/* Debug Blueprint Errors output device. /* Debug Blueprint Errors output device.

View File

@@ -126,7 +126,8 @@ public:
// tangibles that have been changed. // tangibles that have been changed.
void UpdateTangibles(); void UpdateTangibles();
// Maybe call 'BecomePossessed' on the player tangible. // Look for a tangible whose ID is equal to the current actor ID.
// Tell the player controller to possess that tangible.
void UpdatePossessedTangible(); void UpdatePossessedTangible();
// Call 'CalculateLookAt', but only if everything is valid. // Call 'CalculateLookAt', but only if everything is valid.

View File

@@ -42,8 +42,8 @@ void UlxTangible::DeleteCurrentActor()
CurrentActor->Rename(nullptr); CurrentActor->Rename(nullptr);
CurrentActor->Destroy(); CurrentActor->Destroy();
// If this actor previously was posessed by a player controller, // If this actor previously was possessed by a player controller,
// then it's not posessed anymore, because there is no actor any more. // then it's not possessed anymore, because there is no actor any more.
if (Manager->PossessedTangible == this) { if (Manager->PossessedTangible == this) {
Manager->PossessedTangible = nullptr; Manager->PossessedTangible = nullptr;
}; };
@@ -242,6 +242,12 @@ void UlxTangible::FinishedAnimation(AActor *target, const FlxAnimationStep &step
UE_LOG(LogLuprex, Display, TEXT("Animation Finished: %s"), *DebugString); UE_LOG(LogLuprex, Display, TEXT("Animation Finished: %s"), *DebugString);
} }
bool UlxTangible::AnimationStepIsFinished(AActor *target, const FlxAnimationStep &step) {
UlxTangible *tan = GetActorTangibleOrLog(target);
if (tan == nullptr) return true;
return tan->AnimTracker.IsFinished(step.Hash);
}
FString UlxTangible::GetTangiblePlane(AActor* target) { FString UlxTangible::GetTangiblePlane(AActor* target) {
UlxTangible *tan = GetActorTangibleOrLog(target); UlxTangible *tan = GetActorTangibleOrLog(target);
if (tan == nullptr) return TEXT(""); if (tan == nullptr) return TEXT("");
@@ -266,9 +272,3 @@ bool UlxTangible::IsLuprexTangible(AActor* target) {
return tan != nullptr; return tan != nullptr;
} }
void UlxTangible::SetAutoFinish(AActor *target, const FString &action, const FVector &xyz) {
UlxTangible *tan = GetActorTangibleOrLog(target);
if (tan == nullptr) return;
tan->AnimTracker.SetAutoFinish(action, xyz);
}

View File

@@ -154,8 +154,8 @@ public:
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "Target"), Category = "Luprex|Animation Queue") UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "Target"), Category = "Luprex|Animation Queue")
static void FinishedAnimation(AActor *Target, const FlxAnimationStep &Step, bool AutoUpdate = true); static void FinishedAnimation(AActor *Target, const FlxAnimationStep &Step, bool AutoUpdate = true);
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Luprex|Animation Queue") UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "Target", ExpandBoolAsExecs="ReturnValue"), Category = "Luprex|Animation Queue")
static void SetAutoFinish(AActor *target, const FString &action, const FVector &xyz); static bool AnimationStepIsFinished(AActor *Target, const FlxAnimationStep &Step);
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Luprex|Tangible") UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "target"), Category = "Luprex|Tangible")
static FString GetTangiblePlane(AActor* target); static FString GetTangiblePlane(AActor* target);

View File

@@ -29,7 +29,7 @@ public:
UPROPERTY() UPROPERTY()
TMap<int64, UlxTangible*> IdToTangible; TMap<int64, UlxTangible*> IdToTangible;
// The Tangible ID of the posessed tangible, if any. // The Tangible ID of the possessed tangible, if any.
UlxTangible *PossessedTangible; UlxTangible *PossessedTangible;
public: public:

View File

@@ -25,7 +25,7 @@ end
function engio.move(action, xyz, facing) function engio.move(action, xyz, facing)
-- todo: sanity check the parameters. -- todo: sanity check the parameters.
dprint("engio.move ", action, " ", xyz[1], " ", xyz[2], " ", xyz[3]) dprint("engio.move ", action, " ", xyz[1], " ", xyz[2], " ", xyz[3])
tangible.animate(actor, nil, {action=action, xyz=xyz, facing=facing}) tangible.animate(actor, nil, {action=action, interactive=true, xyz=xyz, facing=facing})
end end
function cube.lookhotkeys(keys) function cube.lookhotkeys(keys)