Merge
This commit is contained in:
@@ -21,3 +21,63 @@ ConnectionType=USBOnly
|
||||
bUseManualIPAddress=False
|
||||
ManualIPAddress=
|
||||
|
||||
[/Script/Engine.UserInterfaceSettings]
|
||||
UIScaleCurve=(EditorCurveData=(Keys=((Time=480.000000,Value=0.444000),(Time=720.000000,Value=0.666000),(Time=1080.000000,Value=1.000000),(Time=8640.000000,Value=8.000000)),DefaultValue=340282346638528859811704183484516925440.000000,PreInfinityExtrap=RCCE_Constant,PostInfinityExtrap=RCCE_Constant),ExternalCurve=None)
|
||||
|
||||
[/Script/Engine.CollisionProfile]
|
||||
-Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision",bCanModify=False)
|
||||
-Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
|
||||
-Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
|
||||
-Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
|
||||
-Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
|
||||
-Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.",bCanModify=False)
|
||||
-Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ",bCanModify=False)
|
||||
-Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ",bCanModify=False)
|
||||
-Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic",Response=ECR_Block),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.",bCanModify=False)
|
||||
-Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.",bCanModify=False)
|
||||
-Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors",bCanModify=False)
|
||||
-Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors",bCanModify=False)
|
||||
-Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.",bCanModify=False)
|
||||
-Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.",bCanModify=False)
|
||||
-Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.",bCanModify=False)
|
||||
-Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.",bCanModify=False)
|
||||
-Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.",bCanModify=False)
|
||||
-Profiles=(Name="UI",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Block),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
|
||||
+Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision")
|
||||
+Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ")
|
||||
+Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ")
|
||||
+Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ")
|
||||
+Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ")
|
||||
+Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.")
|
||||
+Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ")
|
||||
+Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ")
|
||||
+Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic"),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.")
|
||||
+Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.")
|
||||
+Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors")
|
||||
+Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors")
|
||||
+Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.")
|
||||
+Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.")
|
||||
+Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.")
|
||||
+Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.")
|
||||
+Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.")
|
||||
+Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility"),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ")
|
||||
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=True,bStaticObject=False,Name="Clickable")
|
||||
-ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
|
||||
-ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
|
||||
-ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
|
||||
-ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor")
|
||||
-ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic")
|
||||
+ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
|
||||
+ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
|
||||
+ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
|
||||
+ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor")
|
||||
+ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic")
|
||||
-CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic")
|
||||
-CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
|
||||
-CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
|
||||
-CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")
|
||||
+CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic")
|
||||
+CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
|
||||
+CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
|
||||
+CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")
|
||||
|
||||
|
||||
Binary file not shown.
BIN
Content/ConsoleBP.uasset
LFS
BIN
Content/ConsoleBP.uasset
LFS
Binary file not shown.
BIN
Content/LpxLevel.umap
LFS
BIN
Content/LpxLevel.umap
LFS
Binary file not shown.
BIN
Content/Luprex/Widgets/lxConsoleWidget.uasset
LFS
Normal file
BIN
Content/Luprex/Widgets/lxConsoleWidget.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Luprex/Widgets/lxCrosshairImage.uasset
LFS
Normal file
BIN
Content/Luprex/Widgets/lxCrosshairImage.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Luprex/Widgets/lxCrosshairWidget.uasset
LFS
Normal file
BIN
Content/Luprex/Widgets/lxCrosshairWidget.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Luprex/lxCrosshairImage.uasset
LFS
Normal file
BIN
Content/Luprex/lxCrosshairImage.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/Luprex/lxGameMode.uasset
LFS
Executable file → Normal file
BIN
Content/Luprex/lxGameMode.uasset
LFS
Executable file → Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/__ExternalActors__/LpxLevel/E/9Q/NGAUKYIQ0ILXBND0RRPBAT.uasset
LFS
Normal file
BIN
Content/__ExternalActors__/LpxLevel/E/9Q/NGAUKYIQ0ILXBND0RRPBAT.uasset
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,28 @@
|
||||
diff --git a/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py b/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py
|
||||
index f56f5ea9cac4..ff1c4030b38f 100644
|
||||
--- a/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py
|
||||
+++ b/Engine/Extras/LLDBDataFormatters/UEDataFormatters_2ByteChars.py
|
||||
@@ -32,7 +32,7 @@ def UETCharSummaryProvider(valobj,dict):
|
||||
if DataVal == 0:
|
||||
Val = 'NULL'
|
||||
else:
|
||||
- Expr = '(char16_t*)(%s)' % Data
|
||||
+ Expr = '(char16_t*)(%s)' % DataVal
|
||||
ValRef = valobj.CreateValueFromExpression('string', Expr)
|
||||
Val = ValRef.GetSummary()
|
||||
elif Type.IsReferenceType():
|
||||
@@ -47,6 +47,11 @@ def UETCharSummaryProvider(valobj,dict):
|
||||
Expr = '(char16_t*)(%s)' % valobj.GetAddress()
|
||||
ValRef = valobj.CreateValueFromExpression('string', Expr)
|
||||
Val = ValRef.GetSummary()
|
||||
+ else:
|
||||
+ DataVal = valobj.GetValueAsUnsigned(0)
|
||||
+ Expr = '(char16_t)(%s)' % DataVal
|
||||
+ ValRef = valobj.CreateValueFromExpression('string', Expr)
|
||||
+ Val = ValRef.GetSummary()
|
||||
return Val
|
||||
|
||||
def UESignedCharSummaryProvider(valobj,dict):
|
||||
diff --git a/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp b/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp
|
||||
index ca5f4b5fb5ff..a436a624d5b7 100644
|
||||
--- a/Engine/Source/Runtime/ApplicationCore/Private/Linux/LinuxPlatformApplicationMisc.cpp
|
||||
|
||||
@@ -81,8 +81,9 @@ void UlxAnimationStepLibrary::UnpackAnimationStep(bool &bChanged, FString &Actio
|
||||
bChanged = false;
|
||||
Action = TEXT("");
|
||||
|
||||
if (prefix.IsEmpty()) {
|
||||
UlxUtilityLibrary::Assert(false, TEXT("You may not pass an empty string for prefix"));
|
||||
if (prefix.IsEmpty())
|
||||
{
|
||||
UE_LOG(LogBlueprint, Error, TEXT("UnpackAnimationStep: You may not pass an empty string for prefix"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -92,8 +93,7 @@ void UlxAnimationStepLibrary::UnpackAnimationStep(bool &bChanged, FString &Actio
|
||||
|
||||
FStructProperty* stepproperty = FindAnimationStepProperty(uclass, prefix);
|
||||
if (stepproperty == nullptr) {
|
||||
UE_LOG(LogBlueprint, Error, TEXT("Target object: %s Prefix: %s"), *(target->GetName()), *prefix);
|
||||
UlxUtilityLibrary::Assert(false, TEXT("Target object does not have an variable named '<prefix> Animation Step'"));
|
||||
UE_LOG(LogBlueprint, Error, TEXT("UnpackAnimationStep: Target object does not have a variable named: '%s Animation Step'"), *prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
//
|
||||
////////////////////////////////////////////////
|
||||
|
||||
USTRUCT(Blueprintable)
|
||||
USTRUCT(BlueprintType)
|
||||
struct INTEGRATION_API FlxAnimationStep {
|
||||
GENERATED_BODY()
|
||||
|
||||
|
||||
137
Source/Integration/BlueprintErrors.cpp
Normal file
137
Source/Integration/BlueprintErrors.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
|
||||
#include "BlueprintErrors.h"
|
||||
#include "Internationalization/TextFormatter.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
#include "Kismet2/KismetDebugUtilities.h"
|
||||
|
||||
#include "Kismet/KismetTextLibrary.h"
|
||||
|
||||
ELogVerbosity::Type UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(ElxLogVerbosity Verbosity) {
|
||||
switch (Verbosity) {
|
||||
case ElxLogVerbosity::Error: return ELogVerbosity::Error;
|
||||
case ElxLogVerbosity::Warning: return ELogVerbosity::Warning;
|
||||
case ElxLogVerbosity::Display: return ELogVerbosity::Display;
|
||||
case ElxLogVerbosity::Log: return ELogVerbosity::Log;
|
||||
case ElxLogVerbosity::Verbose: return ELogVerbosity::Verbose;
|
||||
case ElxLogVerbosity::VeryVerbose: return ELogVerbosity::VeryVerbose;
|
||||
case ElxLogVerbosity::Fatal: return ELogVerbosity::Fatal;
|
||||
}
|
||||
}
|
||||
|
||||
void UlxBlueprintErrorLibrary::FormatErrorInternal(UObject *Context, ElxLogVerbosity Verbosity, ElxErrorDisplayDuration DisplayDuration, 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();
|
||||
|
||||
// Convert the DisplayDuration enum into a number of seconds.
|
||||
//
|
||||
int Seconds = int(DisplayDuration);
|
||||
if (Seconds > 100) Seconds = (Seconds - 100) * 60;
|
||||
|
||||
// Choose a color appropriate to the verbosity level.
|
||||
//
|
||||
FLinearColor Color;
|
||||
switch (Verbosity) {
|
||||
case ElxLogVerbosity::Fatal : Color = FLinearColor(1.0, 0.6, 0.6); break;
|
||||
case ElxLogVerbosity::Error : Color = FLinearColor(1.0, 0.6, 0.6); break;
|
||||
case ElxLogVerbosity::Warning : Color = FLinearColor(0.9, 0.9, 0.6); break;
|
||||
default: Color = FLinearColor(0.8, 0.8, 0.8); break;
|
||||
}
|
||||
|
||||
// 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 Screen, if requested.
|
||||
//
|
||||
if (Seconds != 0)
|
||||
{
|
||||
UKismetSystemLibrary::PrintText(NULL, Message, true, false, Color, Seconds, NAME_None);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FlxDebugBlueprintErrorsOutputDevice::FlxDebugBlueprintErrorsOutputDevice(const ElxLogVerbosity &SensitivityRef)
|
||||
: Sensitivity(SensitivityRef)
|
||||
{
|
||||
GLog->AddOutputDevice(this);
|
||||
}
|
||||
|
||||
FlxDebugBlueprintErrorsOutputDevice::~FlxDebugBlueprintErrorsOutputDevice()
|
||||
{
|
||||
GLog->RemoveOutputDevice(this);
|
||||
}
|
||||
|
||||
namespace UBreakPoint {
|
||||
static volatile int V;
|
||||
FORCENOINLINE static void OnLogFatal() {
|
||||
V = 0;
|
||||
}
|
||||
FORCENOINLINE static void OnLogError() {
|
||||
V = 1;
|
||||
OnLogFatal();
|
||||
}
|
||||
FORCENOINLINE static void OnLogWarning() {
|
||||
V = 2;
|
||||
OnLogError();
|
||||
}
|
||||
}
|
||||
|
||||
static const FName LogBlueprintDebugName(TEXT("LogBlueprintDebug"));
|
||||
|
||||
|
||||
void FlxDebugBlueprintErrorsOutputDevice::Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const FName& Category)
|
||||
{
|
||||
// If the error isn't serious enough, do nothing.
|
||||
//
|
||||
if (Verbosity > UlxBlueprintErrorLibrary::ConvertElxLogVerbosity(Sensitivity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the Category is LogBlueprintDebug, then we're inside the debugger already.
|
||||
//
|
||||
if (Category == LogBlueprintDebugName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out if we're running in a blueprint thread. If not, return.
|
||||
//
|
||||
FFrame* Frame = FFrame::GetThreadLocalTopStackFrame();
|
||||
if (Frame == nullptr) return;
|
||||
UObject *TopObject = Frame->Object;
|
||||
if (TopObject == nullptr) return;
|
||||
|
||||
// Notify the debugger that there's been an exception.
|
||||
//
|
||||
FBlueprintExceptionInfo ExceptionInfo(EBlueprintExceptionType::Breakpoint, FText::FromStringView(FStringView(V)));
|
||||
FBlueprintCoreDelegates::ThrowScriptException(TopObject, *Frame, ExceptionInfo);
|
||||
}
|
||||
|
||||
|
||||
181
Source/Integration/BlueprintErrors.h
Normal file
181
Source/Integration/BlueprintErrors.h
Normal file
@@ -0,0 +1,181 @@
|
||||
//
|
||||
// BlueprintErrors: Better error handling for blueprint errors.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Containers/Array.h"
|
||||
#include "CoreMinimal.h"
|
||||
#include "HAL/Platform.h"
|
||||
#include "Misc/OutputDeviceError.h"
|
||||
#include "UObject/NameTypes.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
|
||||
#include "BlueprintErrors.generated.h"
|
||||
|
||||
/*
|
||||
* enum class ElxLogVerbosity, below, contains all the same error severity levels
|
||||
* as ELogVerbosity, but in a form that the blueprint editor can manipulate.
|
||||
*
|
||||
* We deliberately moved 'Fatal' to the end of the list, and made 'Error' option 0.
|
||||
* We did that because we want the editor to default to 'Error' in most cases.
|
||||
* Unfortunately, that means the numeric values of the two enums don't match up,
|
||||
* so we will need a conversion function.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** Log Verbosity: The importance of an error message, which affects which logs the error
|
||||
* message gets written to, and how that message gets filtered.
|
||||
*
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxLogVerbosity : uint8 {
|
||||
|
||||
/* Prints an error to the console and log file. The editor collects and reports errors. */
|
||||
Error,
|
||||
|
||||
/* Prints a warning to the console and log file. The editor collects and report warnings. */
|
||||
Warning,
|
||||
|
||||
/* Prints a message to the console and log file. */
|
||||
Display,
|
||||
|
||||
/* Prints a message to the log file, however, it does not print to the console. */
|
||||
Log,
|
||||
|
||||
/* Prints a message to a log file only if Verbose logging is enabled for the given category. This is usually used for detailed logging. */
|
||||
Verbose,
|
||||
|
||||
/* Prints a message to a log file. If VeryVerbose logging is enabled, then this is used for detailed logging that would otherwise spam output. */
|
||||
VeryVerbose,
|
||||
|
||||
/* Danger! Prints a fatal error to the console and log file, then crashes (this crashes the editor too). */
|
||||
Fatal,
|
||||
};
|
||||
|
||||
|
||||
/** Display Duration: How long to display an error message in the game's viewport.
|
||||
*
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxErrorDisplayDuration : uint8 {
|
||||
|
||||
/* Do not display the message in the viewport */
|
||||
No_Show = 0,
|
||||
|
||||
/* Display the message in the viewport for 1 seconds */
|
||||
Show_1_Seconds = 1,
|
||||
|
||||
/* Display the message in the viewport for 2 seconds */
|
||||
Show_2_Seconds = 2,
|
||||
|
||||
/* Display the message in the viewport for 3 seconds */
|
||||
Show_3_Seconds = 3,
|
||||
|
||||
/* Display the message in the viewport for 4 seconds */
|
||||
Show_4_Seconds = 4,
|
||||
|
||||
/* Display the message in the viewport for 5 seconds */
|
||||
Show_5_Seconds = 5,
|
||||
|
||||
/* Display the message in the viewport for 10 seconds */
|
||||
Show_10_Seconds = 10,
|
||||
|
||||
/* Display the message in the viewport for 20 seconds */
|
||||
Show_20_Seconds = 20,
|
||||
|
||||
/* Display the message in the viewport for 30 seconds */
|
||||
Show_30_Seconds = 30,
|
||||
|
||||
/* Display the message in the viewport for 40 seconds */
|
||||
Show_40_Seconds = 40,
|
||||
|
||||
/* Display the message in the viewport for 50 seconds */
|
||||
Show_50_Seconds = 50,
|
||||
|
||||
/* Display the message in the viewport for 60 seconds */
|
||||
Show_60_Seconds = 60,
|
||||
|
||||
/* Display the message in the viewport for 70 seconds */
|
||||
Show_70_Seconds = 70,
|
||||
|
||||
/* Display the message in the viewport for 80 seconds */
|
||||
Show_80_Seconds = 80,
|
||||
|
||||
/* Display the message in the viewport for 90 seconds */
|
||||
Show_90_Seconds = 90,
|
||||
|
||||
/* Display the message in the viewport for 1 minutes */
|
||||
Show_1_Minutes = 101,
|
||||
|
||||
/* Display the message in the viewport for 2 minutes */
|
||||
Show_2_Minutes = 102,
|
||||
|
||||
/* Display the message in the viewport for 3 minutes */
|
||||
Show_3_Minutes = 103,
|
||||
|
||||
/* Display the message in the viewport for 4 minutes */
|
||||
Show_4_Minutes = 104,
|
||||
|
||||
/* Display the message in the viewport for 5 minutes */
|
||||
Show_5_Minutes = 105,
|
||||
};
|
||||
|
||||
/* A library containing assorted useful functions for blueprint error handling.
|
||||
*
|
||||
*/
|
||||
UCLASS(MinimalAPI)
|
||||
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, ElxErrorDisplayDuration DisplayDuration, const FString &InPattern, TArray<FFormatArgumentData> InArgs);
|
||||
|
||||
// Convert an ElxLogVerbosity to an ELogVerbosity::Type
|
||||
//
|
||||
static ELogVerbosity::Type ConvertElxLogVerbosity(ElxLogVerbosity Verbosity);
|
||||
};
|
||||
|
||||
/* Debug Blueprint Errors output device.
|
||||
*
|
||||
* When an error message gets written to the log, using "Format Error Message,"
|
||||
* or any other means that writes an error message to the log,
|
||||
* we can optionally notify the blueprint debugger to pause execution.
|
||||
* This only affects errors that are generated during blueprint execution.
|
||||
* Errors in other threads do not pause the blueprint.
|
||||
*
|
||||
*/
|
||||
struct FlxDebugBlueprintErrorsOutputDevice : public FOutputDevice
|
||||
{
|
||||
public:
|
||||
// The constructor and destructor automatically register this output device with GLog.
|
||||
//
|
||||
// This struct doesn't store the sensitivity threshold. It relies on some blueprint
|
||||
// class to do that, so that the threshold can be easily edited with the blueprint
|
||||
// editor. This struct must be initialized with a reference to the threshold variable.
|
||||
//
|
||||
FlxDebugBlueprintErrorsOutputDevice(const ElxLogVerbosity &SensitivityRef);
|
||||
~FlxDebugBlueprintErrorsOutputDevice();
|
||||
|
||||
// Inspect a log message.
|
||||
//
|
||||
INTEGRATION_API virtual void Serialize(const TCHAR* V, ELogVerbosity::Type Verbosity, const FName& Category) override;
|
||||
|
||||
// If the device is marked 'CanBeUsedOnMultipleThreads,' then UE_LOG will
|
||||
// call Serialize from the current thread, otherwise, it will call Serialize from
|
||||
// the logging thread. Using the logging thread would defeat the purpose of this
|
||||
// device, so it's imperative that we set this flag.
|
||||
//
|
||||
INTEGRATION_API virtual bool CanBeUsedOnMultipleThreads() const override { return true; }
|
||||
|
||||
private:
|
||||
const ElxLogVerbosity &Sensitivity;
|
||||
};
|
||||
@@ -15,12 +15,10 @@
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "HAL/PlatformCrt.h"
|
||||
#include "Internationalization/Internationalization.h"
|
||||
#include "Internationalization/TextFormatter.h"
|
||||
#include "K2Node_CallFunction.h"
|
||||
#include "K2Node_MakeArray.h"
|
||||
#include "K2Node_MakeStruct.h"
|
||||
#include "Kismet/KismetMathLibrary.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
#include "Kismet/KismetTextLibrary.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
#include "Kismet2/CompilerResultsLog.h"
|
||||
@@ -104,8 +102,8 @@ void UK2Node_FormatError::CreateCorrectPins()
|
||||
}
|
||||
|
||||
if (FindPin(FormatPinName, EGPD_Input) == nullptr) {
|
||||
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Text, FormatPinName);
|
||||
P->DefaultTextValue = LOCTEXT("FormatErrorMessage_DefaultMessage", "Error Message");
|
||||
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, FormatPinName);
|
||||
P->DefaultValue = TEXT("Error Message");
|
||||
}
|
||||
|
||||
if (FindPin(VerbosityPinName, EGPD_Input) == nullptr) {
|
||||
@@ -115,7 +113,7 @@ void UK2Node_FormatError::CreateCorrectPins()
|
||||
}
|
||||
|
||||
if (FindPin(DisplayDurationPinName, EGPD_Input) == nullptr) {
|
||||
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Byte, StaticEnum<ElxDisplayDuration>(), DisplayDurationPinName);
|
||||
UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Byte, StaticEnum<ElxErrorDisplayDuration>(), DisplayDurationPinName);
|
||||
P->DefaultValue = TEXT("No_Display");
|
||||
P->AutogeneratedDefaultValue = P->DefaultValue;
|
||||
}
|
||||
@@ -252,7 +250,7 @@ void UK2Node_FormatError::PinDefaultValueChanged(UEdGraphPin* Pin)
|
||||
if(IsFormatPin(Pin))
|
||||
{
|
||||
PinNames.Empty();
|
||||
FText::GetFormatPatternParameters(Pin->DefaultTextValue, PinNames);
|
||||
FText::GetFormatPatternParameters(FText::FromString(Pin->DefaultValue), PinNames);
|
||||
CreateCorrectPins();
|
||||
GetGraph()->NotifyNodeChanged(this);
|
||||
}
|
||||
@@ -318,7 +316,7 @@ void UK2Node_FormatError::ExpandNode(class FKismetCompilerContext& CompilerConte
|
||||
|
||||
// This is the node that does all the Format work and outputs the message.
|
||||
UK2Node_CallFunction* CallFormatFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph);
|
||||
UFunction *FormatFunction = UlxFormatErrorLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxFormatErrorLibrary, FormatErrorInternal));
|
||||
UFunction *FormatFunction = UlxBlueprintErrorLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxBlueprintErrorLibrary, FormatErrorInternal));
|
||||
CallFormatFunction->SetFromFunction(FormatFunction);
|
||||
CallFormatFunction->AllocateDefaultPins();
|
||||
CompilerContext.MessageLog.NotifyIntermediateObjectCreation(CallFormatFunction, this);
|
||||
@@ -608,71 +606,5 @@ FText UK2Node_FormatError::GetMenuCategory() const
|
||||
return FEditorCategoryUtils::GetCommonCategory(FCommonEditorCategory::Text);
|
||||
}
|
||||
|
||||
void UlxFormatErrorLibrary::FormatErrorInternal(UObject *Context, ElxLogVerbosity Verbosity, ElxDisplayDuration DisplayDuration, FText InPattern, TArray<FFormatArgumentData> InArgs)
|
||||
{
|
||||
// Generate the formatted string.
|
||||
//
|
||||
FText Message = FTextFormatter::Format(MoveTemp(InPattern), MoveTemp(InArgs), false, false);
|
||||
FString MessageString = Message.ToString();
|
||||
|
||||
// Convert the DisplayDuration enum into a number of seconds.
|
||||
//
|
||||
int Seconds = int(DisplayDuration);
|
||||
if (Seconds > 100) Seconds = (Seconds - 100) * 60;
|
||||
|
||||
// Choose a color appropriate to the verbosity level.
|
||||
//
|
||||
FLinearColor Color;
|
||||
switch (Verbosity) {
|
||||
case ElxLogVerbosity::Fatal : Color = FLinearColor(1.0, 0.6, 0.6); break;
|
||||
case ElxLogVerbosity::Error : Color = FLinearColor(1.0, 0.6, 0.6); break;
|
||||
case ElxLogVerbosity::Warning : Color = FLinearColor(0.9, 0.9, 0.6); break;
|
||||
default: Color = FLinearColor(0.8, 0.8, 0.8); break;
|
||||
}
|
||||
|
||||
// Convert verbosity to an internal value.
|
||||
//
|
||||
ELogVerbosity::Type VerbosityValue;
|
||||
switch (Verbosity) {
|
||||
case ElxLogVerbosity::Error: VerbosityValue = ELogVerbosity::Error; break;
|
||||
case ElxLogVerbosity::Warning: VerbosityValue = ELogVerbosity::Warning; break;
|
||||
case ElxLogVerbosity::Display: VerbosityValue = ELogVerbosity::Display; break;
|
||||
case ElxLogVerbosity::Log: VerbosityValue = ELogVerbosity::Log; break;
|
||||
case ElxLogVerbosity::Verbose: VerbosityValue = ELogVerbosity::Verbose; break;
|
||||
case ElxLogVerbosity::VeryVerbose: VerbosityValue = ELogVerbosity::VeryVerbose; break;
|
||||
case ElxLogVerbosity::Fatal: VerbosityValue = ELogVerbosity::Fatal; break;
|
||||
}
|
||||
|
||||
// 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 Screen, if requested.
|
||||
//
|
||||
if (Seconds != 0)
|
||||
{
|
||||
UKismetSystemLibrary::PrintText(NULL, Message, true, false, Color, Seconds, NAME_None);
|
||||
}
|
||||
|
||||
// Output to Log
|
||||
//
|
||||
FMsg::Logf(BlueprintNameAnsi.Get(), 0, BlueprintNameLogCategory, VerbosityValue, TEXT("%s"), *MessageString);
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BlueprintErrors.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "CoreMinimal.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
@@ -12,6 +13,7 @@
|
||||
#include "UObject/NameTypes.h"
|
||||
#include "UObject/ObjectMacros.h"
|
||||
#include "UObject/UObjectGlobals.h"
|
||||
#include "BlueprintErrors.h"
|
||||
|
||||
#include "FormatError.generated.h"
|
||||
|
||||
@@ -23,121 +25,6 @@ class UObject;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// The following UENUM contains all the ELogVerbosity levels, in a form
|
||||
// that the blueprint editor can manipulate.
|
||||
//
|
||||
// We deliberately moved Fatal to the end of the list, because the editor
|
||||
// will display these values in the order shown here, and we want Error to
|
||||
// be the value that is 'promoted', and we want Fatal to be buried as a
|
||||
// rarely-used option.
|
||||
//
|
||||
|
||||
/** Log Verbosity: The importance of the message, which affects where the message goes and how it is filtered. */
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxLogVerbosity : uint8 {
|
||||
|
||||
/* Prints an error to the console and log file. The editor collects and reports errors. */
|
||||
Error,
|
||||
|
||||
/* Prints a warning to the console and log file. The editor collects and report warnings. */
|
||||
Warning,
|
||||
|
||||
/* Prints a message to the console and log file. */
|
||||
Display,
|
||||
|
||||
/* Prints a message to the log file, however, it does not print to the console. */
|
||||
Log,
|
||||
|
||||
/* Prints a message to a log file only if Verbose logging is enabled for the given category. This is usually used for detailed logging. */
|
||||
Verbose,
|
||||
|
||||
/* Prints a message to a log file. If VeryVerbose logging is enabled, then this is used for detailed logging that would otherwise spam output. */
|
||||
VeryVerbose,
|
||||
|
||||
/* Danger! Prints a fatal error to the console and log file, then crashes (this crashes the editor too). */
|
||||
Fatal,
|
||||
};
|
||||
|
||||
/** Display Duration: How long to display a message in the game's viewport */
|
||||
UENUM(BlueprintType)
|
||||
enum class ElxDisplayDuration : uint8 {
|
||||
|
||||
/* Do not display the message in the viewport */
|
||||
No_Display_in_Viewport = 0,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_1_Seconds = 1,
|
||||
|
||||
/* Display the message in the viewport for 2 second */
|
||||
Display_2_Seconds = 2,
|
||||
|
||||
/* Display the message in the viewport for 3 second */
|
||||
Display_3_Seconds = 3,
|
||||
|
||||
/* Display the message in the viewport for 4 second */
|
||||
Display_4_Seconds = 4,
|
||||
|
||||
/* Display the message in the viewport for 5 second */
|
||||
Display_5_Seconds = 5,
|
||||
|
||||
/* Display the message in the viewport for 10 second */
|
||||
Display_10_Seconds = 10,
|
||||
|
||||
/* Display the message in the viewport for 20 second */
|
||||
Display_20_Seconds = 20,
|
||||
|
||||
/* Display the message in the viewport for 30 second */
|
||||
Display_30_Seconds = 30,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_40_Seconds = 40,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_50_Seconds = 50,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_60_Seconds = 60,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_70_Seconds = 70,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_80_Seconds = 80,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_90_Seconds = 90,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_1_Minute = 101,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_2_Minutes = 102,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_3_Minutes = 103,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_4_Minutes = 104,
|
||||
|
||||
/* Display the message in the viewport for 1 second */
|
||||
Display_5_Minutes = 105,
|
||||
};
|
||||
|
||||
//
|
||||
// Library functions used by Format Error Message.
|
||||
//
|
||||
UCLASS(MinimalAPI)
|
||||
class UlxFormatErrorLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, meta=(WorldContext = "Context", BlueprintInternalUseOnly = "true"))
|
||||
static void FormatErrorInternal(UObject *Context, ElxLogVerbosity Verbosity, ElxDisplayDuration DisplayDuration, FText InPattern, TArray<FFormatArgumentData> InArgs);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// The Format Error Message K2Node.
|
||||
//
|
||||
|
||||
@@ -77,6 +77,9 @@ void AIntegrationGameModeBase::ResetToInitialState()
|
||||
w->release(w.Get());
|
||||
}
|
||||
|
||||
// Stop trapping log errors to the debugger.
|
||||
BreakToDebuggerLogVerbosityDevice.Reset();
|
||||
|
||||
// Clear the lua call assembly buffer.
|
||||
LuaCallBuffer.clear();
|
||||
|
||||
@@ -84,8 +87,8 @@ void AIntegrationGameModeBase::ResetToInitialState()
|
||||
PlayerId = 0;
|
||||
|
||||
// Clear the look-at state;
|
||||
PreviousLookAt = nullptr;
|
||||
CurrentLookAt = nullptr;
|
||||
PreviousLookAt.Init();
|
||||
CurrentLookAt.Init();
|
||||
|
||||
// Reset the clocks.
|
||||
EngineSeconds = 0.0;
|
||||
@@ -316,6 +319,10 @@ void AIntegrationGameModeBase::BeginPlay()
|
||||
// Initialize the tangible manager.
|
||||
TangibleManager = NewObject<UlxTangibleManager>();
|
||||
TangibleManager->Init(GetWorld(), this);
|
||||
|
||||
// If somebody generates a log message that's severe enough, break to debugger.
|
||||
BreakToDebuggerLogVerbosityDevice.Reset(
|
||||
new FlxDebugBlueprintErrorsOutputDevice(BreakToDebuggerLogVerbosity));
|
||||
}
|
||||
|
||||
void AIntegrationGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
@@ -342,7 +349,7 @@ AIntegrationGameModeBase *AIntegrationGameModeBase::GetFromContext(UObject *cont
|
||||
void AIntegrationGameModeBase::UpdateLookAt() {
|
||||
// Rotate the variables.
|
||||
PreviousLookAt = CurrentLookAt;
|
||||
CurrentLookAt = nullptr;
|
||||
CurrentLookAt.Init();
|
||||
|
||||
// Make sure the world is fully configured before we attempt to cast rays.
|
||||
UlxTangible *possessed = TangibleManager->GetPossessedTangible();
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "TangibleManager.h"
|
||||
#include "LuprexSockets.h"
|
||||
#include "TriggeredTask.h"
|
||||
#include "BlueprintErrors.h"
|
||||
#include "IntegrationGameModeBase.generated.h"
|
||||
|
||||
|
||||
@@ -46,13 +47,13 @@ public:
|
||||
int64 GetPlayerId();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Look-At Detection")
|
||||
void SetLookAt(AActor *actor) { CurrentLookAt = actor; }
|
||||
void SetLookAt(const FHitResult &hit) { CurrentLookAt = hit; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Look-At Detection")
|
||||
AActor *GetLookAt() const { return CurrentLookAt; }
|
||||
const FHitResult &GetLookAt() const { return CurrentLookAt; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Look-At Detection")
|
||||
bool LookAtChanged() const { return CurrentLookAt != PreviousLookAt; }
|
||||
bool LookAtChanged() const { return CurrentLookAt.HitObjectHandle != PreviousLookAt.HitObjectHandle; }
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent, Category = "Luprex|Look-At Detection")
|
||||
void CalculateLookAt(AActor *Player, APlayerController *PlayerController, APlayerCameraManager *Camera);
|
||||
@@ -110,13 +111,17 @@ public:
|
||||
UPROPERTY()
|
||||
UlxTangibleManager *TangibleManager;
|
||||
|
||||
// The actor that the player is looking at, previous frame.
|
||||
// The actor that the player was looking at, previous frame.
|
||||
UPROPERTY()
|
||||
AActor *PreviousLookAt;
|
||||
FHitResult PreviousLookAt;
|
||||
|
||||
// The actor that the player is looking at, current frame.
|
||||
UPROPERTY()
|
||||
AActor *CurrentLookAt;
|
||||
FHitResult CurrentLookAt;
|
||||
|
||||
// The sensitivity level at which a log message triggers a debugger breakpoint.
|
||||
UPROPERTY(EditAnywhere, Category="Debugging Tools")
|
||||
ElxLogVerbosity BreakToDebuggerLogVerbosity;
|
||||
|
||||
// This stores the entire text currently visible in the console.
|
||||
FlxConsoleOutput ConsoleOutput;
|
||||
@@ -150,4 +155,7 @@ public:
|
||||
// These allow us to pre-tick and post-tick.
|
||||
FDelegateHandle OnWorldPreActorTickHandle;
|
||||
FDelegateHandle OnWorldPostActorTickHandle;
|
||||
|
||||
// The device that implements BreakToDebuggerLogVerbosity, above.
|
||||
TUniquePtr<FlxDebugBlueprintErrorsOutputDevice> BreakToDebuggerLogVerbosityDevice;
|
||||
};
|
||||
|
||||
@@ -4,24 +4,17 @@
|
||||
#include "UtilityLibrary.h"
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
|
||||
#define LOCTEXT_NAMESPACE "Luprex Utility"
|
||||
|
||||
void UlxUtilityLibrary::Assert(bool condition, const FString &message) {
|
||||
if (!condition) {
|
||||
FBlueprintExceptionInfo ExceptionInfo(EBlueprintExceptionType::FatalError, FText::FromString(message));
|
||||
FBlueprintCoreDelegates::ThrowScriptException(FFrame::GetThreadLocalTopStackFrame()->Object, *FFrame::GetThreadLocalTopStackFrame(), ExceptionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void UlxUtilityLibrary::CallFunctionByName(UObject *object, const FString &namepart1, const FString &namepart2, const FString &fallback, bool bFailIfNotFound) {
|
||||
FString fullname = namepart1 + namepart2;
|
||||
if (!IsValid(object)) {
|
||||
const FBlueprintExceptionInfo ExceptionInfo(
|
||||
EBlueprintExceptionType::FatalError,
|
||||
LOCTEXT("CallFunctionByName_ObjectIsNotValid", "In CallFunctionByName, object passed in is not valid.")
|
||||
);
|
||||
FBlueprintCoreDelegates::ThrowScriptException(FFrame::GetThreadLocalTopStackFrame()->Object, *FFrame::GetThreadLocalTopStackFrame(), ExceptionInfo);
|
||||
UE_LOG(LogBlueprint, Error, TEXT("In CallFunctionByName, object passed in is not valid."));
|
||||
return;
|
||||
}
|
||||
UFunction* function = object->FindFunction(FName(*fullname));
|
||||
@@ -31,20 +24,12 @@ void UlxUtilityLibrary::CallFunctionByName(UObject *object, const FString &namep
|
||||
if (!bFailIfNotFound) {
|
||||
return;
|
||||
}
|
||||
const FBlueprintExceptionInfo ExceptionInfo(
|
||||
EBlueprintExceptionType::FatalError,
|
||||
LOCTEXT("CallFunctionByName_NoSuchFunction", "In CallFunctionByName, cannot find the named function or the fallback function.")
|
||||
);
|
||||
FBlueprintCoreDelegates::ThrowScriptException(FFrame::GetThreadLocalTopStackFrame()->Object, *FFrame::GetThreadLocalTopStackFrame(), ExceptionInfo);
|
||||
UE_LOG(LogBlueprint, Error, TEXT("In CallFunctionByName, cannot find the named function or the fallback function"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (function->ParmsSize != 0) {
|
||||
const FBlueprintExceptionInfo ExceptionInfo(
|
||||
EBlueprintExceptionType::FatalError,
|
||||
LOCTEXT("CallFunctionByName_FunctionHasParameters", "CallFunctionByName can only call functions that have no parameters and no return values.")
|
||||
);
|
||||
FBlueprintCoreDelegates::ThrowScriptException(FFrame::GetThreadLocalTopStackFrame()->Object, *FFrame::GetThreadLocalTopStackFrame(), ExceptionInfo);
|
||||
UE_LOG(LogBlueprint, Error, TEXT("CallFunctionByName can only call functions that have no parameters and no return values"));
|
||||
return;
|
||||
}
|
||||
object->ProcessEvent(function, nullptr);
|
||||
@@ -91,3 +76,45 @@ UEnhancedInputLocalPlayerSubsystem *UlxUtilityLibrary::GetEnhancedInputLocalPlay
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool UlxUtilityLibrary::LineTraceThroughPixel(const APlayerController* PlayerController,
|
||||
FVector2D PixelXY, double MaxDistanceFromCamera,
|
||||
ETraceTypeQuery TraceChannel, bool bTraceComplex, EDrawDebugTrace::Type DrawDebugType, bool bIgnorePlayerPawn,
|
||||
const TArray<AActor*>& ActorsToIgnore, FHitResult& HitResult)
|
||||
{
|
||||
const FLinearColor TraceColor = FLinearColor::Red;
|
||||
const FLinearColor TraceHitColor = FLinearColor::Green;
|
||||
const double DrawTime = 1.0;
|
||||
|
||||
// Zero out the return values.
|
||||
HitResult.Init();
|
||||
|
||||
// Sanity check the distance.
|
||||
if (MaxDistanceFromCamera <= 0.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure there's a player pawn.
|
||||
AActor *PlayerPawn = PlayerController->GetPawn();
|
||||
if (!PlayerPawn) return false;
|
||||
|
||||
// Calculate the trace start and trace end positions in world space.
|
||||
FVector WorldStart, WorldDirection, WorldEnd;
|
||||
if (!UGameplayStatics::DeprojectScreenToWorld(PlayerController, PixelXY, WorldStart, WorldDirection))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
WorldEnd = WorldStart + (WorldDirection * MaxDistanceFromCamera);
|
||||
|
||||
// Find the hit.
|
||||
if (UKismetSystemLibrary::LineTraceSingle(PlayerPawn, WorldStart, WorldEnd, TraceChannel, bTraceComplex,
|
||||
ActorsToIgnore, DrawDebugType, HitResult, bIgnorePlayerPawn, TraceColor, TraceHitColor, DrawTime))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fail.
|
||||
HitResult.Init();
|
||||
return false;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user