Lots of refactoring related to Movement Component State. Still not done yet.
This commit is contained in:
@@ -1,12 +1,7 @@
|
||||
|
||||
#include "BlueprintErrors.h"
|
||||
#include "Blueprint/BlueprintExceptionInfo.h"
|
||||
#include "LuaCall.h"
|
||||
#include "Internationalization/TextFormatter.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
#include "Kismet2/KismetDebugUtilities.h"
|
||||
#include "Kismet/KismetTextLibrary.h"
|
||||
#include "AnimQueue.h"
|
||||
|
||||
ELogVerbosity::Type UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(ElxLogVerbosity Verbosity) {
|
||||
switch (Verbosity) {
|
||||
@@ -20,231 +15,6 @@ ELogVerbosity::Type UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(ElxLogVerbo
|
||||
}
|
||||
}
|
||||
|
||||
void UlxBlueprintErrorLibrary::FormatErrorInternal(UObject *Context, ElxLogVerbosity Verbosity, const FString &InPattern, TArray<FFormatArgumentData> InArgs)
|
||||
{
|
||||
// Generate the formatted string.
|
||||
//
|
||||
FText InPatternText(FText::FromString(InPattern));
|
||||
FText Message = FTextFormatter::Format(MoveTemp(InPatternText), MoveTemp(InArgs), false, false);
|
||||
FString MessageString = Message.ToString();
|
||||
|
||||
// Get the blueprint name.
|
||||
//
|
||||
// Normally, the log function expects you to pass in a filename, and a log
|
||||
// category name. We use the blueprint name for both.
|
||||
//
|
||||
// Using the blueprint name as a log category name is not technically
|
||||
// correct. However, there is no correct way to create log categories
|
||||
// from inside of blueprints. Doing it this way at least produces a reasonable
|
||||
// message inside the log. What doesn't work correctly is the log message
|
||||
// suppression system. Ie, console commands like 'log <category> verbose'
|
||||
// don't have any effect here. The design of the log message suppression
|
||||
// system is such that there just is no reasonable way to hook into it from
|
||||
// inside of blueprints.
|
||||
//
|
||||
FString BlueprintNameString = Context->GetClass()->GetName();
|
||||
auto BlueprintNameAnsi = StringCast<ANSICHAR>(*BlueprintNameString);
|
||||
FLogCategoryName BlueprintNameLogCategory(Context->GetClass()->GetFName());
|
||||
|
||||
// Output to Log
|
||||
//
|
||||
ELogVerbosity::Type VerbosityValue = ConvertElxLogVerbosity(Verbosity);
|
||||
if (VerbosityValue <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY)
|
||||
{
|
||||
FMsg::Logf(BlueprintNameAnsi.Get(), 0, BlueprintNameLogCategory, VerbosityValue, TEXT("%s"), *MessageString);
|
||||
}
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataBool(bool Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_BoolToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataByte(uint8 Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = Value;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataInt(int Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = Value;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataInt64(int64 Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = Value;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataFloat(float Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Float;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueFloat = Value;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataDouble(double Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Double;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueDouble = Value;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataText(FText Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = Value;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataString(FString Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_StringToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataName(FName Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_NameToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataKey(FKey Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_NameToText(Value.GetFName());
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataGender(ETextGender Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Gender;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueGender = Value;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataObject(UObject *Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_ObjectToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataVector(const FVector &Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_VectorToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataVector2D(const FVector2D &Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_Vector2dToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataRotator(const FRotator &Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_RotatorToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataTransform(const FTransform &Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_TransformToText(Value);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataLuaValues(const UlxLuaValues *Value, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(Value->DebugString());
|
||||
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 Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText();
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxBlueprintErrorLibrary::FormatArgumentDataEnum(uint8 Value, const FString &Name, const UObject *PinSubCategoryObject)
|
||||
{
|
||||
const UEnum *Enum = Cast<const UEnum>(PinSubCategoryObject);
|
||||
FFormatArgumentData Result;
|
||||
if (Enum == nullptr)
|
||||
{
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::Format(INVTEXT("<{0}>"), Enum->GetDisplayNameTextByValue(Value));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
FlxDebugBlueprintErrorsOutputDevice::FlxDebugBlueprintErrorsOutputDevice(const ElxLogVerbosity &SensitivityRef)
|
||||
: Sensitivity(SensitivityRef)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "Containers/Array.h"
|
||||
#include "CoreMinimal.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "HAL/Platform.h"
|
||||
#include "Misc/OutputDeviceError.h"
|
||||
#include "UObject/NameTypes.h"
|
||||
@@ -16,9 +15,6 @@
|
||||
|
||||
#include "BlueprintErrors.generated.h"
|
||||
|
||||
class UlxLuaValues;
|
||||
struct FlxAnimationStep;
|
||||
|
||||
/*
|
||||
* enum class ElxLogVerbosity, below, contains all the same error severity levels
|
||||
* as ELogVerbosity, but in a form that the blueprint editor can manipulate.
|
||||
@@ -69,93 +65,11 @@ class UlxBlueprintErrorLibrary : public UBlueprintFunctionLibrary
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// The Format Error Message blueprint node macroexpands, the following
|
||||
// function is the core of the expansion. The actual K2Node itself is in
|
||||
// its own source file.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, meta=(WorldContext = "Context", BlueprintInternalUseOnly = "true"))
|
||||
static void FormatErrorInternal(UObject *Context, ElxLogVerbosity Verbosity, const FString &InPattern, TArray<FFormatArgumentData> InArgs);
|
||||
|
||||
// A formatting routine for pins that were never connected.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataBlank(const FString &Name);
|
||||
|
||||
// A specialized formatting routine for pins of enum types.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataEnum(uint8 Value, const FString &Name, const UObject *PinSubCategoryObject);
|
||||
|
||||
// Convert an ElxLogVerbosity to an ELogVerbosity::Type
|
||||
//
|
||||
static ELogVerbosity::Type ConvertElxLogVerbosity(ElxLogVerbosity Verbosity);
|
||||
};
|
||||
|
||||
/*
|
||||
* A library that contains functions that convert data into FFormatArgumentData
|
||||
* structs, so that the data can be passed to FText::Format.
|
||||
*/
|
||||
UCLASS(MinimalAPI)
|
||||
class UlxFormatDataLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataBool(bool Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataByte(uint8 Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataInt(int Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataInt64(int64 Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataFloat(float Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataDouble(double Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataText(FText Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataString(FString Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataName(FName Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataKey(FKey Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataGender(ETextGender Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataObject(UObject *Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataVector(const FVector &Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataVector2D(const FVector2D &Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataRotator(const FRotator &Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataTransform(const FTransform &Value, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
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.
|
||||
*
|
||||
* When an error message gets written to the log, using "Format Error Message,"
|
||||
|
||||
205
Source/Integration/FormatDataLibrary.cpp
Normal file
205
Source/Integration/FormatDataLibrary.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
|
||||
#include "FormatDataLibrary.h"
|
||||
#include "LuaCall.h"
|
||||
#include "AnimQueue.h"
|
||||
#include "MovementComponentState.h"
|
||||
#include "Kismet/KismetTextLibrary.h"
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataBool(bool AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_BoolToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataByte(uint8 AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = AutoConvertedValue;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataInt(int AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = AutoConvertedValue;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataInt64(int64 AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = AutoConvertedValue;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataFloat(float AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Float;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueFloat = AutoConvertedValue;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataDouble(double AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Double;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueDouble = AutoConvertedValue;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataText(FText AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = AutoConvertedValue;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataString(FString AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_StringToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataName(FName AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_NameToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataKey(FKey AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_NameToText(AutoConvertedValue.GetFName());
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataGender(ETextGender AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Gender;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueGender = AutoConvertedValue;
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataObject(UObject *AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_ObjectToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataVector(const FVector &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_VectorToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataVector2D(const FVector2D &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_Vector2dToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataRotator(const FRotator &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_RotatorToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataTransform(const FTransform &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = UKismetTextLibrary::Conv_TransformToText(AutoConvertedValue);
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataLuaValues(const UlxLuaValues *AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(AutoConvertedValue->DebugString());
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataAnimationStep(const FlxAnimationStep &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(UlxAnimationStepLibrary::AnimationStepDebugString(AutoConvertedValue));
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataMovementComponentState(const FlxMovementComponentState &AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::FromString(UlxMovementComponentStateLibrary::DebugString(AutoConvertedValue));
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataBlank(const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText();
|
||||
return Result;
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataEnum(uint8 Value, const FString &Name, const UObject *PinSubCategoryObject)
|
||||
{
|
||||
const UEnum *Enum = Cast<const UEnum>(PinSubCategoryObject);
|
||||
FFormatArgumentData Result;
|
||||
if (Enum == nullptr)
|
||||
{
|
||||
Result.ArgumentValueType = EFormatArgumentType::Int;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValueInt = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.ArgumentValueType = EFormatArgumentType::Text;
|
||||
Result.ArgumentName = Name;
|
||||
Result.ArgumentValue = FText::Format(INVTEXT("<{0}>"), Enum->GetDisplayNameTextByValue(Value));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
104
Source/Integration/FormatDataLibrary.h
Normal file
104
Source/Integration/FormatDataLibrary.h
Normal file
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// FormatDataLibrary: Functions that convert data into FFormatArgumentData
|
||||
// structs, so that the data can be passed to FText::Format.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InputCoreTypes.h"
|
||||
#include "HAL/Platform.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
|
||||
#include "FormatDataLibrary.generated.h"
|
||||
|
||||
class UlxLuaValues;
|
||||
struct FlxAnimationStep;
|
||||
struct FlxMovementComponentState;
|
||||
|
||||
/*
|
||||
* A library that contains functions that convert data into FFormatArgumentData
|
||||
* structs, so that the data can be passed to FTextFormatter::Format.
|
||||
*
|
||||
* The FormatLogMessage K2Node scans this library using reflection,
|
||||
* looking for functions that have a parameter named "AutoConvertedValue".
|
||||
* It uses the type of that parameter to determine which function to
|
||||
* call for a given pin type. Functions without an "AutoConvertedValue"
|
||||
* parameter are ignored by the reflection scan.
|
||||
*
|
||||
*/
|
||||
UCLASS(MinimalAPI)
|
||||
class UlxFormatDataLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataBool(bool AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataByte(uint8 AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataInt(int AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataInt64(int64 AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataFloat(float AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataDouble(double AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataText(FText AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataString(FString AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataName(FName AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataKey(FKey AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataGender(ETextGender AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataObject(UObject *AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataVector(const FVector &AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataVector2D(const FVector2D &AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataRotator(const FRotator &AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataTransform(const FTransform &AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataLuaValues(const UlxLuaValues *AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataAnimationStep(const FlxAnimationStep &AutoConvertedValue, const FString &Name);
|
||||
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataMovementComponentState(const FlxMovementComponentState &AutoConvertedValue, const FString &Name);
|
||||
|
||||
// A formatting routine for pins that were never connected.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataBlank(const FString &Name);
|
||||
|
||||
// A specialized formatting routine for pins of enum types.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, meta = (BlueprintInternalUseOnly = "true"), Category = "Luprex|Utility")
|
||||
static FFormatArgumentData FormatArgumentDataEnum(uint8 Value, const FString &Name, const UObject *PinSubCategoryObject);
|
||||
};
|
||||
@@ -1,8 +1,9 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
|
||||
#include "FormatError.h"
|
||||
#include "FormatMessage.h"
|
||||
|
||||
#include "Internationalization/TextFormatter.h"
|
||||
#include "BlueprintActionDatabaseRegistrar.h"
|
||||
#include "BlueprintNodeSpawner.h"
|
||||
#include "Containers/EnumAsByte.h"
|
||||
@@ -301,7 +302,7 @@ UFunction *ToFormatArgumentData(const UEdGraphSchema_K2 *Schema, const FEdGraphP
|
||||
//
|
||||
if (PinType.PinCategory == UEdGraphSchema_K2::PC_Wildcard && AllowWild)
|
||||
{
|
||||
return UlxBlueprintErrorLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxBlueprintErrorLibrary, FormatArgumentDataBlank));
|
||||
return UlxFormatDataLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxFormatDataLibrary, FormatArgumentDataBlank));
|
||||
}
|
||||
|
||||
// Try to find a match in the UlxFormatDataLibrary.
|
||||
@@ -309,7 +310,7 @@ UFunction *ToFormatArgumentData(const UEdGraphSchema_K2 *Schema, const FEdGraphP
|
||||
for (auto It = TFieldIterator<UFunction>(UlxFormatDataLibrary::StaticClass()); It; ++It)
|
||||
{
|
||||
UFunction* Function = *It;
|
||||
FProperty* ValueProperty = Function->FindPropertyByName(TEXT("Value"));
|
||||
FProperty* ValueProperty = Function->FindPropertyByName(TEXT("AutoConvertedValue"));
|
||||
FEdGraphPinType ValuePinType;
|
||||
bool Convertible = Schema->ConvertPropertyToPinType(ValueProperty, ValuePinType);
|
||||
if (!Convertible) continue;
|
||||
@@ -322,7 +323,7 @@ UFunction *ToFormatArgumentData(const UEdGraphSchema_K2 *Schema, const FEdGraphP
|
||||
//
|
||||
if ((PinType.PinCategory == UEdGraphSchema_K2::PC_Byte) && (nullptr != Cast<const UEnum>(PinType.PinSubCategoryObject)))
|
||||
{
|
||||
return UlxBlueprintErrorLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxBlueprintErrorLibrary, FormatArgumentDataEnum));
|
||||
return UlxFormatDataLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxFormatDataLibrary, FormatArgumentDataEnum));
|
||||
}
|
||||
|
||||
// A case for subclasses of 'Object' which are not exactly 'Object'
|
||||
@@ -359,7 +360,7 @@ void UK2Node_FormatMessage::ExpandNode(class FKismetCompilerContext& CompilerCon
|
||||
UFunction *FormatFunction;
|
||||
if (IsFormatErrorMessage())
|
||||
{
|
||||
FormatFunction = UlxBlueprintErrorLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxBlueprintErrorLibrary, FormatErrorInternal));
|
||||
FormatFunction = UK2Node_FormatMessage::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UK2Node_FormatMessage, FormatLogMessageInternal));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -399,7 +400,7 @@ void UK2Node_FormatMessage::ExpandNode(class FKismetCompilerContext& CompilerCon
|
||||
ConvertNode->SetFromFunction(Converter);
|
||||
ConvertNode->AllocateDefaultPins();
|
||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(ConvertNode, this);
|
||||
UEdGraphPin *ValuePin = ConvertNode->FindPin(TEXT("Value"));
|
||||
UEdGraphPin *ValuePin = ConvertNode->FindPin(TEXT("AutoConvertedValue"));
|
||||
UEdGraphPin *NamePin = ConvertNode->FindPinChecked(TEXT("Name"));
|
||||
UEdGraphPin *SubCategoryObjectPin = ConvertNode->FindPin(TEXT("PinSubCategoryObject"));
|
||||
|
||||
@@ -559,7 +560,7 @@ UK2Node_FormatMessage::UK2Node_FormatMessage(const FObjectInitializer& ObjectIni
|
||||
);
|
||||
}
|
||||
|
||||
UK2Node_FormatErrorMessage::UK2Node_FormatErrorMessage(const FObjectInitializer& ObjectInitializer)
|
||||
UK2Node_FormatLogMessage::UK2Node_FormatLogMessage(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
NodeTooltip = LOCTEXT("NodeTooltip",
|
||||
@@ -572,4 +573,39 @@ UK2Node_FormatErrorMessage::UK2Node_FormatErrorMessage(const FObjectInitializer&
|
||||
);
|
||||
}
|
||||
|
||||
void UK2Node_FormatMessage::FormatLogMessageInternal(UObject *Context, ElxLogVerbosity Verbosity, const FString &InPattern, TArray<FFormatArgumentData> InArgs)
|
||||
{
|
||||
// Generate the formatted string.
|
||||
//
|
||||
FText InPatternText(FText::FromString(InPattern));
|
||||
FText Message = FTextFormatter::Format(MoveTemp(InPatternText), MoveTemp(InArgs), false, false);
|
||||
FString MessageString = Message.ToString();
|
||||
|
||||
// Get the blueprint name.
|
||||
//
|
||||
// Normally, the log function expects you to pass in a filename, and a log
|
||||
// category name. We use the blueprint name for both.
|
||||
//
|
||||
// Using the blueprint name as a log category name is not technically
|
||||
// correct. However, there is no correct way to create log categories
|
||||
// from inside of blueprints. Doing it this way at least produces a reasonable
|
||||
// message inside the log. What doesn't work correctly is the log message
|
||||
// suppression system. Ie, console commands like 'log <category> verbose'
|
||||
// don't have any effect here. The design of the log message suppression
|
||||
// system is such that there just is no reasonable way to hook into it from
|
||||
// inside of blueprints.
|
||||
//
|
||||
FString BlueprintNameString = Context->GetClass()->GetName();
|
||||
auto BlueprintNameAnsi = StringCast<ANSICHAR>(*BlueprintNameString);
|
||||
FLogCategoryName BlueprintNameLogCategory(Context->GetClass()->GetFName());
|
||||
|
||||
// Output to Log
|
||||
//
|
||||
ELogVerbosity::Type VerbosityValue = UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(Verbosity);
|
||||
if (VerbosityValue <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY)
|
||||
{
|
||||
FMsg::Logf(BlueprintNameAnsi.Get(), 0, BlueprintNameLogCategory, VerbosityValue, TEXT("%s"), *MessageString);
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -3,6 +3,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "BlueprintErrors.h"
|
||||
#include "FormatDataLibrary.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "CoreMinimal.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
@@ -15,7 +16,7 @@
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "BlueprintErrors.h"
|
||||
|
||||
#include "FormatError.generated.h"
|
||||
#include "FormatMessage.generated.h"
|
||||
|
||||
class FBlueprintActionDatabaseRegistrar;
|
||||
class FString;
|
||||
@@ -77,6 +78,12 @@ protected:
|
||||
/** Our derived class will set this to true, altering the behavior of this K2Node. **/
|
||||
virtual bool IsFormatErrorMessage() const { return false; }
|
||||
|
||||
// When IsFormatErrorMessage is true, the K2Node macroexpands to call this
|
||||
// function, which formats the message and outputs it to the log.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, meta=(WorldContext = "Context", BlueprintInternalUseOnly = "true"))
|
||||
static void FormatLogMessageInternal(UObject *Context, ElxLogVerbosity Verbosity, const FString &InPattern, TArray<FFormatArgumentData> InArgs);
|
||||
|
||||
protected:
|
||||
/** When adding arguments to the node, their names are placed here and are generated as pins during construction */
|
||||
UPROPERTY()
|
||||
@@ -91,7 +98,7 @@ protected:
|
||||
// This derives from FormatMessage.
|
||||
//
|
||||
UCLASS(MinimalAPI)
|
||||
class UK2Node_FormatErrorMessage : public UK2Node_FormatMessage
|
||||
class UK2Node_FormatLogMessage : public UK2Node_FormatMessage
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
11
Source/Integration/LxCharacterBase.cpp
Normal file
11
Source/Integration/LxCharacterBase.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "LxCharacterBase.h"
|
||||
#include "GameFramework/CharacterMovementComponent.h"
|
||||
|
||||
|
||||
void AlxCharacterBase::SetMovementComponentMode(EMovementMode MovementMode)
|
||||
{
|
||||
UCharacterMovementComponent *CMC = GetCharacterMovement();
|
||||
if (CMC) CMC->SetMovementMode(MovementMode);
|
||||
}
|
||||
29
Source/Integration/LxCharacterBase.h
Normal file
29
Source/Integration/LxCharacterBase.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Character.h"
|
||||
#include "MovementComponentState.h"
|
||||
#include "LxCharacterBase.generated.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// We provide an AlxCharacterBase for characters in Luprex.
|
||||
//
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
UCLASS(BlueprintType)
|
||||
class INTEGRATION_API AlxCharacterBase : public ACharacter
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AlxCharacterBase() {}
|
||||
|
||||
// Set the movement component mode. This is a thin wrapper
|
||||
// around CharacterMovementComponent::SetMovementMode.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Movement Component State")
|
||||
void SetMovementComponentMode(EMovementMode MovementMode = MOVE_None);
|
||||
};
|
||||
60
Source/Integration/MovementComponentState.cpp
Normal file
60
Source/Integration/MovementComponentState.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "MovementComponentState.h"
|
||||
#include "Animation/AnimInstance.h"
|
||||
#include "GameFramework/CharacterMovementComponent.h"
|
||||
#include "Tangible.h"
|
||||
|
||||
FlxMovementComponentState::FlxMovementComponentState(UCharacterMovementComponent *CMC)
|
||||
{
|
||||
Velocity = CMC->Velocity;
|
||||
bIsAccelerating = !CMC->GetCurrentAcceleration().IsNearlyZero();
|
||||
MaxWalkSpeed = CMC->MaxWalkSpeed;
|
||||
MovementMode = CMC->MovementMode;
|
||||
bIsFalling = CMC->IsFalling();
|
||||
bIsCrouching = CMC->IsCrouching();
|
||||
}
|
||||
|
||||
FString UlxMovementComponentStateLibrary::DebugString(const FlxMovementComponentState &State)
|
||||
{
|
||||
const UEnum *ModeEnum = StaticEnum<EMovementMode>();
|
||||
FString ModeName = ModeEnum ? ModeEnum->GetNameStringByValue(State.MovementMode.GetValue()) : FString::FromInt(State.MovementMode.GetValue());
|
||||
ModeName.RemoveFromStart(TEXT("MOVE_"));
|
||||
return FString::Printf(TEXT("Vel=(%.1f, %.1f, %.1f) MaxWalk=%.1f Mode=%s Accel=%s Fall=%s Crouch=%s"),
|
||||
State.Velocity.X, State.Velocity.Y, State.Velocity.Z,
|
||||
State.MaxWalkSpeed,
|
||||
*ModeName,
|
||||
State.bIsAccelerating ? TEXT("true") : TEXT("false"),
|
||||
State.bIsFalling ? TEXT("true") : TEXT("false"),
|
||||
State.bIsCrouching ? TEXT("true") : TEXT("false"));
|
||||
}
|
||||
|
||||
bool UlxMovementComponentStateLibrary::GetShouldMove(const FlxMovementComponentState &State)
|
||||
{
|
||||
return State.bIsAccelerating && State.Velocity.Size2D() >= 3.0;
|
||||
}
|
||||
|
||||
FlxMovementComponentState UlxMovementComponentStateLibrary::GetMovementComponentState(UAnimInstance *AnimInstance)
|
||||
{
|
||||
if (!AnimInstance) return FlxMovementComponentState();
|
||||
|
||||
AActor *Actor = AnimInstance->GetOwningActor();
|
||||
if (!Actor) return FlxMovementComponentState();
|
||||
|
||||
UCharacterMovementComponent *CMC = Actor->FindComponentByClass<UCharacterMovementComponent>();
|
||||
if (CMC && CMC->MovementMode != MOVE_None) return FlxMovementComponentState(CMC);
|
||||
|
||||
UlxTangible *Tangible = UlxTangible::GetActorTangibleQuiet(Actor);
|
||||
if (Tangible) return Tangible->FakeMovementComponentState;
|
||||
|
||||
if (CMC) return FlxMovementComponentState(CMC);
|
||||
return FlxMovementComponentState();
|
||||
}
|
||||
|
||||
FlxMovementComponentState UlxMovementComponentStateLibrary::SetFakeMovementComponentState(AActor *Actor, const FlxMovementComponentState &State)
|
||||
{
|
||||
if (!Actor) return State;
|
||||
UlxTangible *Tangible = UlxTangible::GetActorTangibleOrLog(Actor);
|
||||
if (Tangible) Tangible->FakeMovementComponentState = State;
|
||||
return State;
|
||||
}
|
||||
129
Source/Integration/MovementComponentState.h
Normal file
129
Source/Integration/MovementComponentState.h
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "MovementComponentState.generated.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Very often, the animation blueprint of a character will
|
||||
// want to know the state of the character movement
|
||||
// component, including such things as Velocity,
|
||||
// Acceleration, IsFalling, etc. However, the movement
|
||||
// component cannot be accessed directly from the
|
||||
// animation graph, since it runs on a worker thread.
|
||||
// By copying the data into this plain struct, the
|
||||
// animation graph can safely read it.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct INTEGRATION_API FlxMovementComponentState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Movement Component State")
|
||||
FVector Velocity = FVector::ZeroVector;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Movement Component State")
|
||||
bool bIsAccelerating = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Movement Component State")
|
||||
float MaxWalkSpeed = 0.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Movement Component State")
|
||||
TEnumAsByte<EMovementMode> MovementMode = MOVE_None;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Movement Component State")
|
||||
bool bIsFalling = false;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Luprex|Movement Component State")
|
||||
bool bIsCrouching = false;
|
||||
|
||||
FlxMovementComponentState() = default;
|
||||
explicit FlxMovementComponentState(class UCharacterMovementComponent *CMC);
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class INTEGRATION_API UlxMovementComponentStateLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// True field getters.
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static FVector GetVelocity(const FlxMovementComponentState &State) { return State.Velocity; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static bool GetIsAccelerating(const FlxMovementComponentState &State) { return State.bIsAccelerating; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static float GetMaxWalkSpeed(const FlxMovementComponentState &State) { return State.MaxWalkSpeed; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static EMovementMode GetMovementMode(const FlxMovementComponentState &State) { return State.MovementMode; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static bool GetIsFalling(const FlxMovementComponentState &State) { return State.bIsFalling; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static bool GetIsCrouching(const FlxMovementComponentState &State) { return State.bIsCrouching; }
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// These are not true getters, but actually calculate
|
||||
// simple values from the existing fields.
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static float GetGroundSpeed(const FlxMovementComponentState &State) { return State.Velocity.Size2D(); }
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State", meta = (BlueprintThreadSafe))
|
||||
static bool GetShouldMove(const FlxMovementComponentState &State);
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// Debugging.
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Movement Component State")
|
||||
static FString DebugString(const FlxMovementComponentState &State);
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// Other operations.
|
||||
//
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
// Get a snapshot the Movement Component State.
|
||||
//
|
||||
// Normally, this just pulls data directly from the
|
||||
// character movement component. However, we sometimes
|
||||
// need to disable the movement component, especially
|
||||
// during cutscenes. We provide an alternative 'Fake
|
||||
// Movement Component State' stored on the actor's
|
||||
// UlxTangible. When the movement component's mode is
|
||||
// MOVE_None, this function returns the fake movement
|
||||
// component state instead. The fake movement component
|
||||
// state can be updated manually in blueprints.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Movement Component State", meta = (DefaultToSelf = "AnimInstance"))
|
||||
static FlxMovementComponentState GetMovementComponentState(UAnimInstance *AnimInstance);
|
||||
|
||||
// Update the fake movement component state stored on
|
||||
// the actor's tangible. The fake movement component
|
||||
// state is usually read by the animation blueprint
|
||||
// when the real movement component is disabled.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Movement Component State", meta = (AutoCreateRefTerm = "State"))
|
||||
static FlxMovementComponentState SetFakeMovementComponentState(AActor *Actor, const FlxMovementComponentState &State);
|
||||
};
|
||||
@@ -234,7 +234,7 @@ class INTEGRATION_API UlxScriptedAnimationLibrary : public UBlueprintFunctionLib
|
||||
public:
|
||||
// Get all the major 'World Clocks' in a single struct.
|
||||
//
|
||||
UFUNCTION(BlueprintPure, Category = "Utilities|Time", meta=(WorldContext = "WorldContextObject"))
|
||||
UFUNCTION(BlueprintCallable, Category = "Utilities|Time", meta=(WorldContext = "WorldContextObject"))
|
||||
static FlxWorldClocks GetAllWorldClocks(const UObject *WorldContextObject);
|
||||
|
||||
// Get the data to drive Sequence Evaluators and Multi Blend
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "AnimQueue.h"
|
||||
#include "MovementComponentState.h"
|
||||
#include "ScriptedAnimation.h"
|
||||
#include "Tangible.generated.h"
|
||||
|
||||
@@ -55,10 +56,14 @@ public:
|
||||
UPROPERTY()
|
||||
FString ActorBlueprintName;
|
||||
|
||||
// This is
|
||||
// Every tangible can store a set of scripted animations.
|
||||
UPROPERTY()
|
||||
UlxScriptedAnimations *ScriptedAnimations = nullptr;
|
||||
|
||||
// Every tangible can store a fake movement component state.
|
||||
UPROPERTY()
|
||||
FlxMovementComponentState FakeMovementComponentState;
|
||||
|
||||
// Animation tracker
|
||||
FlxAnimTracker AnimTracker;
|
||||
|
||||
|
||||
@@ -239,3 +239,15 @@ FKey UlxUtilityLibrary::GetKeyByNameString(const FString &Name)
|
||||
FKey Key = FKey(FName(*Name));
|
||||
return Key.IsValid() ? Key : FKey();
|
||||
}
|
||||
|
||||
FVector UlxUtilityLibrary::GetActorForwardVelocity(const AActor *Actor, double Speed, bool bSnapToXY)
|
||||
{
|
||||
if (!Actor) return FVector::ZeroVector;
|
||||
FVector Forward = Actor->GetActorForwardVector();
|
||||
if (bSnapToXY)
|
||||
{
|
||||
Forward.Z = 0.0;
|
||||
if (!Forward.Normalize()) return FVector::ZeroVector;
|
||||
}
|
||||
return Forward * Speed;
|
||||
}
|
||||
|
||||
@@ -158,4 +158,11 @@ public:
|
||||
//
|
||||
UFUNCTION(BlueprintPure, Category = "Input|Key")
|
||||
static FKey GetKeyByNameString(const FString &Name);
|
||||
|
||||
// Get the actor's forward vector multiplied by a speed.
|
||||
// If SnapToXY is true, the forward vector is projected
|
||||
// onto the XY plane and renormalized before scaling.
|
||||
//
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "Luprex|Utility", meta = (DefaultToSelf = "Actor"))
|
||||
static FVector GetActorForwardVelocity(const AActor *Actor, double Speed = 1.0, bool bSnapToXY = false);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user