Lots of refactoring related to Movement Component State. Still not done yet.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
[/Script/Engine.Engine]
|
[/Script/Engine.Engine]
|
||||||
+ActiveClassRedirects=(OldClassName="/Script/Integration.lxLookAtWidget",NewClassName="/Script/Integration.lxLuaWidget")
|
+ActiveClassRedirects=(OldClassName="/Script/Integration.lxLookAtWidget",NewClassName="/Script/Integration.lxLuaWidget")
|
||||||
|
+ActiveClassRedirects=(OldClassName="/Script/Integration.K2Node_FormatErrorMessage",NewClassName="/Script/Integration.K2Node_FormatLogMessage")
|
||||||
|
|
||||||
|
|
||||||
[/Script/Engine.Engine]
|
[/Script/Engine.Engine]
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,12 +1,7 @@
|
|||||||
|
|
||||||
#include "BlueprintErrors.h"
|
#include "BlueprintErrors.h"
|
||||||
#include "Blueprint/BlueprintExceptionInfo.h"
|
#include "Blueprint/BlueprintExceptionInfo.h"
|
||||||
#include "LuaCall.h"
|
|
||||||
#include "Internationalization/TextFormatter.h"
|
|
||||||
#include "Kismet/KismetSystemLibrary.h"
|
|
||||||
#include "Kismet2/KismetDebugUtilities.h"
|
#include "Kismet2/KismetDebugUtilities.h"
|
||||||
#include "Kismet/KismetTextLibrary.h"
|
|
||||||
#include "AnimQueue.h"
|
|
||||||
|
|
||||||
ELogVerbosity::Type UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(ElxLogVerbosity Verbosity) {
|
ELogVerbosity::Type UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(ElxLogVerbosity Verbosity) {
|
||||||
switch (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)
|
FlxDebugBlueprintErrorsOutputDevice::FlxDebugBlueprintErrorsOutputDevice(const ElxLogVerbosity &SensitivityRef)
|
||||||
: Sensitivity(SensitivityRef)
|
: Sensitivity(SensitivityRef)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "Containers/Array.h"
|
#include "Containers/Array.h"
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "InputCoreTypes.h"
|
|
||||||
#include "HAL/Platform.h"
|
#include "HAL/Platform.h"
|
||||||
#include "Misc/OutputDeviceError.h"
|
#include "Misc/OutputDeviceError.h"
|
||||||
#include "UObject/NameTypes.h"
|
#include "UObject/NameTypes.h"
|
||||||
@@ -16,9 +15,6 @@
|
|||||||
|
|
||||||
#include "BlueprintErrors.generated.h"
|
#include "BlueprintErrors.generated.h"
|
||||||
|
|
||||||
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
|
||||||
* as ELogVerbosity, but in a form that the blueprint editor can manipulate.
|
* as ELogVerbosity, but in a form that the blueprint editor can manipulate.
|
||||||
@@ -69,93 +65,11 @@ class UlxBlueprintErrorLibrary : public UBlueprintFunctionLibrary
|
|||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
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
|
// Convert an ElxLogVerbosity to an ELogVerbosity::Type
|
||||||
//
|
//
|
||||||
static ELogVerbosity::Type ConvertElxLogVerbosity(ElxLogVerbosity Verbosity);
|
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.
|
/* Debug Blueprint Errors output device.
|
||||||
*
|
*
|
||||||
* When an error message gets written to the log, using "Format Error Message,"
|
* 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.
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
|
||||||
#include "FormatError.h"
|
#include "FormatMessage.h"
|
||||||
|
|
||||||
|
#include "Internationalization/TextFormatter.h"
|
||||||
#include "BlueprintActionDatabaseRegistrar.h"
|
#include "BlueprintActionDatabaseRegistrar.h"
|
||||||
#include "BlueprintNodeSpawner.h"
|
#include "BlueprintNodeSpawner.h"
|
||||||
#include "Containers/EnumAsByte.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)
|
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.
|
// 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)
|
for (auto It = TFieldIterator<UFunction>(UlxFormatDataLibrary::StaticClass()); It; ++It)
|
||||||
{
|
{
|
||||||
UFunction* Function = *It;
|
UFunction* Function = *It;
|
||||||
FProperty* ValueProperty = Function->FindPropertyByName(TEXT("Value"));
|
FProperty* ValueProperty = Function->FindPropertyByName(TEXT("AutoConvertedValue"));
|
||||||
FEdGraphPinType ValuePinType;
|
FEdGraphPinType ValuePinType;
|
||||||
bool Convertible = Schema->ConvertPropertyToPinType(ValueProperty, ValuePinType);
|
bool Convertible = Schema->ConvertPropertyToPinType(ValueProperty, ValuePinType);
|
||||||
if (!Convertible) continue;
|
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)))
|
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'
|
// A case for subclasses of 'Object' which are not exactly 'Object'
|
||||||
@@ -359,7 +360,7 @@ void UK2Node_FormatMessage::ExpandNode(class FKismetCompilerContext& CompilerCon
|
|||||||
UFunction *FormatFunction;
|
UFunction *FormatFunction;
|
||||||
if (IsFormatErrorMessage())
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -399,7 +400,7 @@ void UK2Node_FormatMessage::ExpandNode(class FKismetCompilerContext& CompilerCon
|
|||||||
ConvertNode->SetFromFunction(Converter);
|
ConvertNode->SetFromFunction(Converter);
|
||||||
ConvertNode->AllocateDefaultPins();
|
ConvertNode->AllocateDefaultPins();
|
||||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(ConvertNode, this);
|
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(ConvertNode, this);
|
||||||
UEdGraphPin *ValuePin = ConvertNode->FindPin(TEXT("Value"));
|
UEdGraphPin *ValuePin = ConvertNode->FindPin(TEXT("AutoConvertedValue"));
|
||||||
UEdGraphPin *NamePin = ConvertNode->FindPinChecked(TEXT("Name"));
|
UEdGraphPin *NamePin = ConvertNode->FindPinChecked(TEXT("Name"));
|
||||||
UEdGraphPin *SubCategoryObjectPin = ConvertNode->FindPin(TEXT("PinSubCategoryObject"));
|
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)
|
: Super(ObjectInitializer)
|
||||||
{
|
{
|
||||||
NodeTooltip = LOCTEXT("NodeTooltip",
|
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
|
#undef LOCTEXT_NAMESPACE
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BlueprintErrors.h"
|
#include "BlueprintErrors.h"
|
||||||
|
#include "FormatDataLibrary.h"
|
||||||
#include "Containers/Array.h"
|
#include "Containers/Array.h"
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "EdGraph/EdGraphNode.h"
|
#include "EdGraph/EdGraphNode.h"
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
#include "UObject/UObjectGlobals.h"
|
#include "UObject/UObjectGlobals.h"
|
||||||
#include "BlueprintErrors.h"
|
#include "BlueprintErrors.h"
|
||||||
|
|
||||||
#include "FormatError.generated.h"
|
#include "FormatMessage.generated.h"
|
||||||
|
|
||||||
class FBlueprintActionDatabaseRegistrar;
|
class FBlueprintActionDatabaseRegistrar;
|
||||||
class FString;
|
class FString;
|
||||||
@@ -77,6 +78,12 @@ protected:
|
|||||||
/** Our derived class will set this to true, altering the behavior of this K2Node. **/
|
/** Our derived class will set this to true, altering the behavior of this K2Node. **/
|
||||||
virtual bool IsFormatErrorMessage() const { return false; }
|
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:
|
protected:
|
||||||
/** When adding arguments to the node, their names are placed here and are generated as pins during construction */
|
/** When adding arguments to the node, their names are placed here and are generated as pins during construction */
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
@@ -91,7 +98,7 @@ protected:
|
|||||||
// This derives from FormatMessage.
|
// This derives from FormatMessage.
|
||||||
//
|
//
|
||||||
UCLASS(MinimalAPI)
|
UCLASS(MinimalAPI)
|
||||||
class UK2Node_FormatErrorMessage : public UK2Node_FormatMessage
|
class UK2Node_FormatLogMessage : public UK2Node_FormatMessage
|
||||||
{
|
{
|
||||||
GENERATED_UCLASS_BODY()
|
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:
|
public:
|
||||||
// Get all the major 'World Clocks' in a single struct.
|
// 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);
|
static FlxWorldClocks GetAllWorldClocks(const UObject *WorldContextObject);
|
||||||
|
|
||||||
// Get the data to drive Sequence Evaluators and Multi Blend
|
// Get the data to drive Sequence Evaluators and Multi Blend
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Components/ActorComponent.h"
|
#include "Components/ActorComponent.h"
|
||||||
#include "AnimQueue.h"
|
#include "AnimQueue.h"
|
||||||
|
#include "MovementComponentState.h"
|
||||||
#include "ScriptedAnimation.h"
|
#include "ScriptedAnimation.h"
|
||||||
#include "Tangible.generated.h"
|
#include "Tangible.generated.h"
|
||||||
|
|
||||||
@@ -55,10 +56,14 @@ public:
|
|||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
FString ActorBlueprintName;
|
FString ActorBlueprintName;
|
||||||
|
|
||||||
// This is
|
// Every tangible can store a set of scripted animations.
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
UlxScriptedAnimations *ScriptedAnimations = nullptr;
|
UlxScriptedAnimations *ScriptedAnimations = nullptr;
|
||||||
|
|
||||||
|
// Every tangible can store a fake movement component state.
|
||||||
|
UPROPERTY()
|
||||||
|
FlxMovementComponentState FakeMovementComponentState;
|
||||||
|
|
||||||
// Animation tracker
|
// Animation tracker
|
||||||
FlxAnimTracker AnimTracker;
|
FlxAnimTracker AnimTracker;
|
||||||
|
|
||||||
|
|||||||
@@ -239,3 +239,15 @@ FKey UlxUtilityLibrary::GetKeyByNameString(const FString &Name)
|
|||||||
FKey Key = FKey(FName(*Name));
|
FKey Key = FKey(FName(*Name));
|
||||||
return Key.IsValid() ? Key : FKey();
|
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")
|
UFUNCTION(BlueprintPure, Category = "Input|Key")
|
||||||
static FKey GetKeyByNameString(const FString &Name);
|
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