Can now switch the skeletal mesh on a character
This commit is contained in:
@@ -3,7 +3,12 @@
|
|||||||
"allow": [
|
"allow": [
|
||||||
"WebFetch(domain:dev.epicgames.com)",
|
"WebFetch(domain:dev.epicgames.com)",
|
||||||
"WebFetch(domain:github.com)",
|
"WebFetch(domain:github.com)",
|
||||||
"Bash(grep:*)"
|
"Bash(grep:*)",
|
||||||
|
"WebSearch",
|
||||||
|
"Bash(clangd:*)",
|
||||||
|
"Bash(clangd-16:*)",
|
||||||
|
"Bash(ssh jyelon-office \"clangd --version 2>/dev/null || clangd-16 --version 2>/dev/null || clangd-18 --version 2>/dev/null || ls /usr/bin/clangd*\")",
|
||||||
|
"Bash(git check-ignore:*)"
|
||||||
],
|
],
|
||||||
"deny": [
|
"deny": [
|
||||||
"Bash(git commit *)",
|
"Bash(git commit *)",
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
Content/SkeletalMeshes/SKM_Manny.uasset
LFS
Normal file
BIN
Content/SkeletalMeshes/SKM_Manny.uasset
LFS
Normal file
Binary file not shown.
BIN
Content/SkeletalMeshes/SKM_Quinn.uasset
LFS
Normal file
BIN
Content/SkeletalMeshes/SKM_Quinn.uasset
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
52
Docs/Error-Handling-in-Blueprints.md
Normal file
52
Docs/Error-Handling-in-Blueprints.md
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
# Error Handling in Blueprints
|
||||||
|
|
||||||
|
## Format Log Message Node
|
||||||
|
|
||||||
|
We have implemented "Format Message", which is an improved version of Unreal's
|
||||||
|
"Format Text". Unlike "Format Text", it has built-in support to print
|
||||||
|
vectors, rotations, enums, and quite a few other types.
|
||||||
|
|
||||||
|
We have also implemented "Format Log Message", which is like Format Message
|
||||||
|
except that the output goes to the unreal logs. It might help to familiarize
|
||||||
|
yourself with Unreal's built-in logging function, UE_LOG. Format Log Message
|
||||||
|
is meant to be the Blueprint front end to UE_LOG.
|
||||||
|
|
||||||
|
Format Message and Format Log Message both require a format string, which
|
||||||
|
will typically look something like this:
|
||||||
|
|
||||||
|
"Hello, {Name}, the weather today will be {Weather}"
|
||||||
|
|
||||||
|
When you set a format string such as the one above, the Format Message node
|
||||||
|
will add pins for the placeholders - in the example above, the pins
|
||||||
|
Name and Weather would be added. These are wildcard pins that you can
|
||||||
|
connect any printable value to.
|
||||||
|
|
||||||
|
To make a new type printable, look at FormatDataLibrary.h
|
||||||
|
|
||||||
|
Format Log Message accepts a severity level, this is directly based on
|
||||||
|
the severity levels supported by UE_LOG. It adds *ThrottledDisplay* and
|
||||||
|
*ThrottledLog*, which do the same thing as *Display* and *Log*, except
|
||||||
|
that output is limited to one message per second.
|
||||||
|
|
||||||
|
## The Blueprint Debugger Pauses on Error Messages
|
||||||
|
|
||||||
|
The blueprint debugger will pause whenever you log an error message. This is functionality we have added to Unreal.
|
||||||
|
You can control the severity at which it pauses: in the GameMode, there is a dropdown for the severity level.
|
||||||
|
You can also effectively turn it off by telling to only pause on fatal errors.
|
||||||
|
|
||||||
|
There is a quirk: the debugger pauses before the error gets put into the logs. So when you're in the
|
||||||
|
blueprint debugger,
|
||||||
|
the only place the error will appear is in the lower-right corner of the screen, where debugger messages are
|
||||||
|
reported. You won't see the error in the unreal output log. If you single-step, the error will appear
|
||||||
|
in the output log as well.
|
||||||
|
|
||||||
|
To understand how this is implemented, it helps to understand that log messages in unreal go to a bunch of
|
||||||
|
different output devices: the unreal editor output window, the visual studio output window, a log file, and
|
||||||
|
several more places. To dispatch messages to all these different destinations, Unreal has an output device
|
||||||
|
list that you can add an output device to.
|
||||||
|
|
||||||
|
To implement this break-on-error-message functionality, we implemented a pseudo-output-device.
|
||||||
|
The pseudo device doesn't actually send
|
||||||
|
the error message anywhere, it just triggers the debugger. For more information about implementation,
|
||||||
|
see BreakToDebugger.h
|
||||||
|
|
||||||
@@ -143,3 +143,6 @@ it adds those string to the UlxConsoleOutput. The UlxConsoleOutput
|
|||||||
turns those individual lines into one big string. From there,
|
turns those individual lines into one big string. From there,
|
||||||
the LuprexGameMode copies the entire string into the body of
|
the LuprexGameMode copies the entire string into the body of
|
||||||
a UMG text widget.
|
a UMG text widget.
|
||||||
|
|
||||||
|
## A Possible new lua print function
|
||||||
|
|
||||||
|
|||||||
@@ -627,45 +627,43 @@ void UlxAnimationStepLibrary::AnimationStepApplyMaterials(const FlxAnimationStep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlxAnimationStepLibrary::AnimationStepApplyMesh(const FlxAnimationStep& step, bool FallbackToBP, AActor* actor) {
|
void UlxAnimationStepLibrary::AnimationStepApplyStaticMesh(const FlxAnimationStep& step, bool FallbackToBP,
|
||||||
if (actor == nullptr) return;
|
UStaticMeshComponent* MeshComp, UStaticMesh* Fallback) {
|
||||||
|
if (MeshComp == nullptr) return;
|
||||||
|
|
||||||
// Step 1: Look for a "mesh" or "bp" string field in the animation step.
|
|
||||||
//
|
|
||||||
FString MeshName = AnimationStepGetString(step, TEXT("mesh"));
|
FString MeshName = AnimationStepGetString(step, TEXT("mesh"));
|
||||||
if (MeshName.IsEmpty() && FallbackToBP) {
|
if (MeshName.IsEmpty() && FallbackToBP) {
|
||||||
MeshName = AnimationStepGetString(step, TEXT("bp"));
|
MeshName = AnimationStepGetString(step, TEXT("bp"));
|
||||||
}
|
}
|
||||||
if (MeshName.IsEmpty()) return;
|
|
||||||
|
|
||||||
// Step 2: Find the actor's mesh component. There must be exactly one.
|
UStaticMesh* NewMesh = nullptr;
|
||||||
//
|
if (!MeshName.IsEmpty()) {
|
||||||
TInlineComponentArray<UMeshComponent*> MeshComponents;
|
UlxAssetLookup::LoadStaticMeshAsset(NewMesh, MeshComp, MeshName);
|
||||||
actor->GetComponents<UMeshComponent>(MeshComponents);
|
|
||||||
if (MeshComponents.Num() != 1) {
|
|
||||||
UE_LOG(LogLuprexIntegration, Error, TEXT("AnimationStepApplyMesh: Actor %s has %d mesh components, expected exactly 1"), *actor->GetName(), MeshComponents.Num());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
UMeshComponent* MeshComp = MeshComponents[0];
|
if (NewMesh == nullptr) NewMesh = Fallback;
|
||||||
|
if (NewMesh == nullptr) return;
|
||||||
// Step 3: Apply the mesh based on the component type.
|
if (MeshComp->GetStaticMesh() != NewMesh) {
|
||||||
//
|
MeshComp->SetStaticMesh(NewMesh);
|
||||||
if (UStaticMeshComponent* StaticComp = Cast<UStaticMeshComponent>(MeshComp)) {
|
}
|
||||||
UStaticMesh* NewMesh = nullptr;
|
}
|
||||||
UlxAssetLookup::LoadStaticMeshAsset(NewMesh, actor, MeshName, false);
|
|
||||||
if (NewMesh == nullptr) return;
|
void UlxAnimationStepLibrary::AnimationStepApplySkeletalMesh(const FlxAnimationStep& step, bool FallbackToBP,
|
||||||
if (StaticComp->GetStaticMesh() != NewMesh) {
|
USkeletalMeshComponent* MeshComp, USkeletalMesh* Fallback) {
|
||||||
StaticComp->SetStaticMesh(NewMesh);
|
if (MeshComp == nullptr) return;
|
||||||
}
|
|
||||||
} else if (USkeletalMeshComponent* SkelComp = Cast<USkeletalMeshComponent>(MeshComp)) {
|
FString MeshName = AnimationStepGetString(step, TEXT("mesh"));
|
||||||
USkeletalMesh* NewMesh = nullptr;
|
if (MeshName.IsEmpty() && FallbackToBP) {
|
||||||
UlxAssetLookup::LoadSkeletalMeshAsset(NewMesh, actor, MeshName, true);
|
MeshName = AnimationStepGetString(step, TEXT("bp"));
|
||||||
if (NewMesh == nullptr) return;
|
}
|
||||||
if (SkelComp->GetSkeletalMeshAsset() != NewMesh) {
|
|
||||||
SkelComp->SetSkeletalMeshAsset(NewMesh);
|
USkeletalMesh* NewMesh = nullptr;
|
||||||
}
|
if (!MeshName.IsEmpty()) {
|
||||||
} else {
|
UlxAssetLookup::LoadSkeletalMeshAsset(NewMesh, MeshComp, MeshName);
|
||||||
UE_LOG(LogLuprexIntegration, Error, TEXT("AnimationStepApplyMesh: Actor %s has unsupported mesh component type"), *actor->GetName());
|
}
|
||||||
|
if (NewMesh == nullptr) NewMesh = Fallback;
|
||||||
|
if (NewMesh == nullptr) return;
|
||||||
|
if (MeshComp->GetSkeletalMeshAsset() != NewMesh) {
|
||||||
|
MeshComp->SetSkeletalMeshAsset(NewMesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,55 +125,40 @@ public:
|
|||||||
UFUNCTION(BlueprintPure, meta = (BlueprintAutocast), Category = "Luprex|Animation Step")
|
UFUNCTION(BlueprintPure, meta = (BlueprintAutocast), Category = "Luprex|Animation Step")
|
||||||
static int64 AnimationStepID(const FlxAnimationStep& step) { return step.Hash; }
|
static int64 AnimationStepID(const FlxAnimationStep& step) { return step.Hash; }
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
// Using mat_xxxx values from the animation step, update the actor's
|
// Using mat_xxxx values from the animation step, update the actor's
|
||||||
// material parameters. Doing this may involve creating or replacing
|
// material parameters. Doing this may involve creating or replacing
|
||||||
// dynamic material instances for the actor.
|
// dynamic material instances for the actor.
|
||||||
=======
|
|
||||||
// Scan an animation step for key-value pairs of the
|
|
||||||
// form mat_XXXX={x,y,z}. For each match, create a
|
|
||||||
// dynamic material instance on the actor's mesh
|
|
||||||
// components and set the vector parameter XXXX.
|
|
||||||
// Materials are restored to their base (non-dynamic)
|
|
||||||
// state before applying, so parameters from previous
|
|
||||||
// calls do not persist.
|
|
||||||
>>>>>>> 9b1dd00a45a7b17c3546f8574d00e5ec78f17c75
|
|
||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "actor"), Category = "Luprex|Animation Step")
|
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "actor"), Category = "Luprex|Animation Step")
|
||||||
static void AnimationStepApplyMaterials(const FlxAnimationStep& step, AActor* actor);
|
static void AnimationStepApplyMaterials(const FlxAnimationStep& step, AActor* actor);
|
||||||
|
|
||||||
<<<<<<< HEAD
|
// Loads a new static mesh, using the animation step to choose it.
|
||||||
// Look for a mesh=name key-value pair in the animation step.
|
// If the chosen mesh is already installed, no changes are made.
|
||||||
// If found, load the named mesh and apply it to the actor's
|
// Looks for 'mesh=name' first; if not found and FallbackToBP is
|
||||||
// mesh component. The actor must have exactly one mesh component.
|
// true, looks for 'bp=name'. If no mesh is successfully loaded,
|
||||||
// If FallbackToBP is true, and mesh=name is not present, looks
|
// uses the Fallback mesh. Failed loads are logged once.
|
||||||
// for a bp=name pair instead.
|
|
||||||
=======
|
|
||||||
// Look for a mesh=name key-value pair. If found, load
|
|
||||||
// the named mesh and apply it to the actor's mesh
|
|
||||||
// component. The actor must have exactly one mesh
|
|
||||||
// component.
|
|
||||||
>>>>>>> 9b1dd00a45a7b17c3546f8574d00e5ec78f17c75
|
|
||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, Meta = (DefaultToSelf = "actor"), Category = "Luprex|Animation Step")
|
UFUNCTION(BlueprintCallable, Category = "Luprex|Animation Step")
|
||||||
static void AnimationStepApplyMesh(const FlxAnimationStep& step, bool FallbackToBP, AActor* actor);
|
static void AnimationStepApplyStaticMesh(const FlxAnimationStep& step, bool FallbackToBP,
|
||||||
|
UStaticMeshComponent* MeshComp, UStaticMesh* Fallback = nullptr);
|
||||||
|
|
||||||
|
// Loads a new skeletal mesh, using the animation step to choose it.
|
||||||
|
// If the chosen mesh is already installed, no changes are made.
|
||||||
|
// Looks for 'mesh=name' first; if not found and FallbackToBP is
|
||||||
|
// true, looks for 'bp=name'. If no mesh is successfully loaded,
|
||||||
|
// uses the Fallback mesh. Failed loads are logged once.
|
||||||
|
//
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Luprex|Animation Step")
|
||||||
|
static void AnimationStepApplySkeletalMesh(const FlxAnimationStep& step, bool FallbackToBP,
|
||||||
|
USkeletalMeshComponent* MeshComp, USkeletalMesh* Fallback = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
<<<<<<< HEAD
|
|
||||||
// An animation step that doesn't actually store the step,
|
// An animation step that doesn't actually store the step,
|
||||||
// it just contains a pointer to the string.
|
// it just contains a pointer to the string.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////
|
|
||||||
=======
|
|
||||||
// FlxAnimationStepView
|
|
||||||
//
|
|
||||||
// A lightweight, non-owning view of an animation
|
|
||||||
// step (hash + body as a string_view).
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
>>>>>>> 9b1dd00a45a7b17c3546f8574d00e5ec78f17c75
|
|
||||||
|
|
||||||
struct FlxAnimationStepView {
|
struct FlxAnimationStepView {
|
||||||
int64 Hash;
|
int64 Hash;
|
||||||
@@ -266,13 +251,8 @@ private:
|
|||||||
FlxStreamBuffer Decoder;
|
FlxStreamBuffer Decoder;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
<<<<<<< HEAD
|
|
||||||
// Initialize the FlxAnimationStepDecoder.
|
|
||||||
//
|
|
||||||
=======
|
|
||||||
// Initialize from an encoded step body.
|
// Initialize from an encoded step body.
|
||||||
//
|
//
|
||||||
>>>>>>> 9b1dd00a45a7b17c3546f8574d00e5ec78f17c75
|
|
||||||
FlxAnimationStepDecoder(std::string_view body) : Decoder(body) {}
|
FlxAnimationStepDecoder(std::string_view body) : Decoder(body) {}
|
||||||
|
|
||||||
// Return true if the parser has reached EOF.
|
// Return true if the parser has reached EOF.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ void UlxAssetLookup::RebuildIndex()
|
|||||||
IAssetRegistry::GetChecked().WaitForCompletion();
|
IAssetRegistry::GetChecked().WaitForCompletion();
|
||||||
AssetPaths.Empty();
|
AssetPaths.Empty();
|
||||||
AddAssets(TEXT("/Game/StaticMeshes"), UStaticMesh::StaticClass(), TEXT("SM_"));
|
AddAssets(TEXT("/Game/StaticMeshes"), UStaticMesh::StaticClass(), TEXT("SM_"));
|
||||||
AddAssets(TEXT("/Game/SkeletalMeshes"), USkeletalMesh::StaticClass(), TEXT("SK_"));
|
AddAssets(TEXT("/Game/SkeletalMeshes"), USkeletalMesh::StaticClass(), TEXT("SKM_"));
|
||||||
AddAssets(TEXT("/Game/AnimSequences"), UAnimSequence::StaticClass(), TEXT("SEQ_"));
|
AddAssets(TEXT("/Game/AnimSequences"), UAnimSequence::StaticClass(), TEXT("SEQ_"));
|
||||||
AddAssets(TEXT("/Game/Tangibles"), UBlueprint::StaticClass(), TEXT("TAN_"));
|
AddAssets(TEXT("/Game/Tangibles"), UBlueprint::StaticClass(), TEXT("TAN_"));
|
||||||
AddAssets(TEXT("/Game/Widgets"), UWidgetBlueprint::StaticClass(), TEXT("WB_"));
|
AddAssets(TEXT("/Game/Widgets"), UWidgetBlueprint::StaticClass(), TEXT("WB_"));
|
||||||
@@ -52,16 +52,22 @@ void UlxAssetLookup::AddAssets(const TCHAR *Path, UClass *Class, const TCHAR *Na
|
|||||||
FoundData.Num(), *Class->GetName(), Path);
|
FoundData.Num(), *Class->GetName(), Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
UObject *UlxAssetLookup::LoadAsset(const UObject *Context, UClass *Class, UClass *ChildOf, const FString &Name, bool ErrorIfNotFound)
|
void UlxAssetLookup::ReportFailedLoad(const FString &ClassName, const FString &Name, const FString &Reason)
|
||||||
|
{
|
||||||
|
static TSet<FString> Reported;
|
||||||
|
FString Key = ClassName + TEXT(":") + Name + TEXT(":") + Reason;
|
||||||
|
if (Reported.Contains(Key)) return;
|
||||||
|
Reported.Add(Key);
|
||||||
|
UE_LOG(LogLuprexIntegration, Display, TEXT("Loading %s %s: %s"), *ClassName, *Name, *Reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
UObject *UlxAssetLookup::LoadAsset(const UObject *Context, UClass *Class, UClass *ChildOf, const FString &Name)
|
||||||
{
|
{
|
||||||
const UlxAssetLookup *Lookup = ALuprexGameModeBase::FromContext(Context)->GetAssetLookup();
|
const UlxAssetLookup *Lookup = ALuprexGameModeBase::FromContext(Context)->GetAssetLookup();
|
||||||
const FString *Path = Lookup->AssetPaths.Find(MakeTuple(Class->GetName(), FName(Name)));
|
const FString *Path = Lookup->AssetPaths.Find(MakeTuple(Class->GetName(), FName(Name)));
|
||||||
if (Path == nullptr)
|
if (Path == nullptr)
|
||||||
{
|
{
|
||||||
if (ErrorIfNotFound)
|
ReportFailedLoad(Class->GetName(), Name, TEXT("asset not found"));
|
||||||
{
|
|
||||||
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading %s %s: asset not found"), *Class->GetName(), *Name);
|
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +83,7 @@ UObject *UlxAssetLookup::LoadAsset(const UObject *Context, UClass *Class, UClass
|
|||||||
|
|
||||||
if (Result == nullptr)
|
if (Result == nullptr)
|
||||||
{
|
{
|
||||||
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading %s %s: unknown load failure"), *Class->GetName(), *Name);
|
ReportFailedLoad(Class->GetName(), Name, TEXT("unknown load failure"));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +92,7 @@ UObject *UlxAssetLookup::LoadAsset(const UObject *Context, UClass *Class, UClass
|
|||||||
UClass *ResClass = (UClass *)Result;
|
UClass *ResClass = (UClass *)Result;
|
||||||
if (!ResClass->IsChildOf(ChildOf))
|
if (!ResClass->IsChildOf(ChildOf))
|
||||||
{
|
{
|
||||||
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading %s %s: blueprint not a child of %s"), *Class->GetName(), *Name, *ChildOf->GetName());
|
ReportFailedLoad(Class->GetName(), Name, FString::Printf(TEXT("blueprint not a child of %s"), *ChildOf->GetName()));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,50 +101,50 @@ UObject *UlxAssetLookup::LoadAsset(const UObject *Context, UClass *Class, UClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
ElxValidOrNotValid UlxAssetLookup::LoadStaticMeshAsset(
|
ElxValidOrNotValid UlxAssetLookup::LoadStaticMeshAsset(
|
||||||
UStaticMesh *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
UStaticMesh *&Result, const UObject *Context, const FString &Name)
|
||||||
{
|
{
|
||||||
Result = (UStaticMesh *)LoadAsset(Context, UStaticMesh::StaticClass(), nullptr, Name, ErrorIfNotFound);
|
Result = (UStaticMesh *)LoadAsset(Context, UStaticMesh::StaticClass(), nullptr, Name);
|
||||||
return Result ? Valid : NotValid;
|
return Result ? Valid : NotValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElxValidOrNotValid UlxAssetLookup::LoadSkeletalMeshAsset(
|
ElxValidOrNotValid UlxAssetLookup::LoadSkeletalMeshAsset(
|
||||||
USkeletalMesh *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
USkeletalMesh *&Result, const UObject *Context, const FString &Name)
|
||||||
{
|
{
|
||||||
Result = (USkeletalMesh *)LoadAsset(Context, USkeletalMesh::StaticClass(), nullptr, Name, ErrorIfNotFound);
|
Result = (USkeletalMesh *)LoadAsset(Context, USkeletalMesh::StaticClass(), nullptr, Name);
|
||||||
return Result ? Valid : NotValid;
|
return Result ? Valid : NotValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElxValidOrNotValid UlxAssetLookup::LoadAnimSequenceAsset(
|
ElxValidOrNotValid UlxAssetLookup::LoadAnimSequenceAsset(
|
||||||
UAnimSequence *&Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
UAnimSequence *&Result, const UObject *Context, const FString &Name)
|
||||||
{
|
{
|
||||||
Result = (UAnimSequence *)LoadAsset(Context, UAnimSequence::StaticClass(), nullptr, Name, ErrorIfNotFound);
|
Result = (UAnimSequence *)LoadAsset(Context, UAnimSequence::StaticClass(), nullptr, Name);
|
||||||
return Result ? Valid : NotValid;
|
return Result ? Valid : NotValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElxValidOrNotValid UlxAssetLookup::LoadTangibleBlueprintAsset(
|
ElxValidOrNotValid UlxAssetLookup::LoadTangibleBlueprintAsset(
|
||||||
TSubclassOf<AActor> &Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
TSubclassOf<AActor> &Result, const UObject *Context, const FString &Name)
|
||||||
{
|
{
|
||||||
Result = (UClass*)LoadAsset(Context, UBlueprint::StaticClass(), AActor::StaticClass(), Name, ErrorIfNotFound);
|
Result = (UClass*)LoadAsset(Context, UBlueprint::StaticClass(), AActor::StaticClass(), Name);
|
||||||
if (Result == nullptr) return NotValid;
|
if (Result == nullptr) return NotValid;
|
||||||
UFunction *aqchanged = Result->FindFunctionByName(FName(TEXT("Animation Queue Changed")));
|
UFunction *aqchanged = Result->FindFunctionByName(FName(TEXT("Animation Queue Changed")));
|
||||||
if ((aqchanged == nullptr)||(aqchanged->ParmsSize != 0))
|
if ((aqchanged == nullptr)||(aqchanged->ParmsSize != 0))
|
||||||
{
|
{
|
||||||
UE_LOG(LogLuprexIntegration, Error, TEXT("Loading Blueprint %s: Tangible does not have 'Animation Queue Changed' function"), *Name);
|
ReportFailedLoad(TEXT("Blueprint"), Name, TEXT("tangible does not have 'Animation Queue Changed' function"));
|
||||||
Result = nullptr; return NotValid;
|
Result = nullptr; return NotValid;
|
||||||
}
|
}
|
||||||
return Valid;
|
return Valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElxValidOrNotValid UlxAssetLookup::LoadUserWidgetAsset(
|
ElxValidOrNotValid UlxAssetLookup::LoadUserWidgetAsset(
|
||||||
TSubclassOf<UUserWidget> &Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
TSubclassOf<UUserWidget> &Result, const UObject *Context, const FString &Name)
|
||||||
{
|
{
|
||||||
Result = (UClass *)LoadAsset(Context, UWidgetBlueprint::StaticClass(), UUserWidget::StaticClass(), Name, ErrorIfNotFound);
|
Result = (UClass *)LoadAsset(Context, UWidgetBlueprint::StaticClass(), UUserWidget::StaticClass(), Name);
|
||||||
return Result ? Valid : NotValid;
|
return Result ? Valid : NotValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElxValidOrNotValid UlxAssetLookup::LoadLuaWidgetAsset(
|
ElxValidOrNotValid UlxAssetLookup::LoadLuaWidgetAsset(
|
||||||
TSubclassOf<UlxLuaWidget> &Result, const UObject *Context, const FString &Name, bool ErrorIfNotFound)
|
TSubclassOf<UlxLuaWidget> &Result, const UObject *Context, const FString &Name)
|
||||||
{
|
{
|
||||||
Result = (UClass *)LoadAsset(Context, UWidgetBlueprint::StaticClass(), UlxLuaWidget::StaticClass(), Name, ErrorIfNotFound);
|
Result = (UClass *)LoadAsset(Context, UWidgetBlueprint::StaticClass(), UlxLuaWidget::StaticClass(), Name);
|
||||||
return Result ? Valid : NotValid;
|
return Result ? Valid : NotValid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ private:
|
|||||||
|
|
||||||
void AddAssets(const TCHAR *Path, UClass *Class, const TCHAR *NamePrefix);
|
void AddAssets(const TCHAR *Path, UClass *Class, const TCHAR *NamePrefix);
|
||||||
|
|
||||||
static UObject *LoadAsset(const UObject *Context, UClass *Class, UClass *ChildOf, const FString &Name, bool ErrorIfNotFound);
|
static void ReportFailedLoad(const FString &ClassName, const FString &Name, const FString &Reason);
|
||||||
|
|
||||||
|
static UObject *LoadAsset(const UObject *Context, UClass *Class, UClass *ChildOf, const FString &Name);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void RebuildIndex();
|
void RebuildIndex();
|
||||||
@@ -52,41 +54,35 @@ public:
|
|||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
||||||
static ElxValidOrNotValid LoadStaticMeshAsset(
|
static ElxValidOrNotValid LoadStaticMeshAsset(
|
||||||
UStaticMesh *&Result,
|
UStaticMesh *&Result, const UObject *Context, const FString &Name);
|
||||||
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
|
|
||||||
|
|
||||||
// Get a skeletal mesh by name.
|
// Get a skeletal mesh by name.
|
||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
||||||
static ElxValidOrNotValid LoadSkeletalMeshAsset(
|
static ElxValidOrNotValid LoadSkeletalMeshAsset(
|
||||||
USkeletalMesh *&Result,
|
USkeletalMesh *&Result, const UObject *Context, const FString &Name);
|
||||||
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
|
|
||||||
|
|
||||||
// Get an animation sequence by name.
|
// Get an animation sequence by name.
|
||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
||||||
static ElxValidOrNotValid LoadAnimSequenceAsset(
|
static ElxValidOrNotValid LoadAnimSequenceAsset(
|
||||||
UAnimSequence *&Result,
|
UAnimSequence *&Result, const UObject *Context, const FString &Name);
|
||||||
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
|
|
||||||
|
|
||||||
// Get a tangible class by name.
|
// Get a tangible class by name.
|
||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
||||||
static ElxValidOrNotValid LoadTangibleBlueprintAsset(
|
static ElxValidOrNotValid LoadTangibleBlueprintAsset(
|
||||||
TSubclassOf<AActor> &Result,
|
TSubclassOf<AActor> &Result, const UObject *Context, const FString &Name);
|
||||||
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
|
|
||||||
|
|
||||||
// Get a widget blueprint by name.
|
// Get a widget blueprint by name.
|
||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
||||||
static ElxValidOrNotValid LoadUserWidgetAsset(
|
static ElxValidOrNotValid LoadUserWidgetAsset(
|
||||||
TSubclassOf<UUserWidget> &Result,
|
TSubclassOf<UUserWidget> &Result, const UObject *Context, const FString &Name);
|
||||||
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
|
|
||||||
|
|
||||||
// Get a look-at widget blueprint by name.
|
// Get a look-at widget blueprint by name.
|
||||||
//
|
//
|
||||||
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
UFUNCTION(BlueprintCallable, meta = (WorldContext = "Context", ExpandEnumAsExecs="ReturnValue"), Category = "Luprex|Asset Loading")
|
||||||
static ElxValidOrNotValid LoadLuaWidgetAsset(
|
static ElxValidOrNotValid LoadLuaWidgetAsset(
|
||||||
TSubclassOf<UlxLuaWidget> &Result,
|
TSubclassOf<UlxLuaWidget> &Result, const UObject *Context, const FString &Name);
|
||||||
const UObject *Context, const FString &Name, bool ErrorIfNotFound = false);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,18 +15,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Containers/UnrealString.h"
|
#include "Containers/UnrealString.h"
|
||||||
|
|
||||||
#include "ConsoleOutput.generated.h"
|
#include "ConsoleOutput.generated.h"
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
=======
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
>>>>>>> 9b1dd00a45a7b17c3546f8574d00e5ec78f17c75
|
|
||||||
//
|
//
|
||||||
// UlxConsoleOutput
|
// UlxConsoleOutput
|
||||||
//
|
//
|
||||||
<<<<<<< HEAD
|
|
||||||
// When the lua code executes a print statement, the text
|
// When the lua code executes a print statement, the text
|
||||||
// eventually gets passed to the GameMode blueprint: see
|
// eventually gets passed to the GameMode blueprint: see
|
||||||
// Docs/Print-Statement-Handling.md for more information.
|
// Docs/Print-Statement-Handling.md for more information.
|
||||||
@@ -52,10 +46,7 @@
|
|||||||
// If the GameMode wants to use some other framework to
|
// If the GameMode wants to use some other framework to
|
||||||
// implement the virtual console, that's perfectly fine.
|
// implement the virtual console, that's perfectly fine.
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
=======
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
>>>>>>> 9b1dd00a45a7b17c3546f8574d00e5ec78f17c75
|
|
||||||
|
|
||||||
UCLASS(BlueprintType)
|
UCLASS(BlueprintType)
|
||||||
class UlxConsoleOutput : public UObject
|
class UlxConsoleOutput : public UObject
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/HitResult.h"
|
||||||
#include "GameFramework/GameModeBase.h"
|
#include "GameFramework/GameModeBase.h"
|
||||||
#include "lpx-enginewrapper.hpp"
|
#include "lpx-enginewrapper.hpp"
|
||||||
#include "StringDecoder.h"
|
#include "StringDecoder.h"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ function login.init()
|
|||||||
global.set("nextplayer", player + 1)
|
global.set("nextplayer", player + 1)
|
||||||
dprint("login.init initializing player ", player)
|
dprint("login.init initializing player ", player)
|
||||||
actor.player = player
|
actor.player = player
|
||||||
tangible.animinit{tan=actor, anim={bp="character", plane="earth", xyz={player * 100, 0, 90}}}
|
tangible.animinit{tan=actor, anim={bp="character", mesh="manny", plane="earth", xyz={player * 100, 0, 90}}}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This gets called on the admin user. You can call login.init in here if you want.
|
-- This gets called on the admin user. You can call login.init in here if you want.
|
||||||
|
|||||||
Reference in New Issue
Block a user