Resave blueprints, solve a crash
This commit is contained in:
@@ -9,7 +9,7 @@ public class ProjectEleriTarget : TargetRules
|
||||
{
|
||||
Type = TargetType.Game;
|
||||
DefaultBuildSettings = BuildSettingsVersion.Latest;
|
||||
//IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
|
||||
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_8;
|
||||
|
||||
ExtraModuleNames.AddRange( new string[] { "ProjectEleri", "PaperZD" } );
|
||||
|
||||
|
||||
@@ -113,6 +113,11 @@ void ABaseCharacter::ChangeFaceAnimation(EDialogueEmotion Emotion)
|
||||
CurrentFaceFrameIndex = 0;
|
||||
}
|
||||
|
||||
void ABaseCharacter::Interact_Implementation()
|
||||
{
|
||||
IZoneInteractableInterface::Interact_Implementation();
|
||||
}
|
||||
|
||||
// Called every frame
|
||||
void ABaseCharacter::Tick(float DeltaTime)
|
||||
{
|
||||
|
||||
@@ -38,12 +38,14 @@ public:
|
||||
|
||||
UFUNCTION(BlueprintCallable, BlueprintPure)
|
||||
UCapsuleComponent* GetCapsuleComponent() { return Capsule; }
|
||||
|
||||
virtual FText GetInteractionText_Implementation() override { return FText::FromString("Talk"); }
|
||||
virtual void Interact_Implementation() override;
|
||||
|
||||
protected:
|
||||
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
FText CharacterName;
|
||||
|
||||
|
||||
UPROPERTY(Category = Character, EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
TSoftObjectPtr<UFaceExpressionDataAsset> FaceExpressionData;
|
||||
UPROPERTY(Category = Character, EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
|
||||
@@ -52,15 +54,12 @@ protected:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly)
|
||||
TObjectPtr<UStateTreeAIComponent> StateTreeComponent;
|
||||
|
||||
/** Collision capsule (just like ACharacter) */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Components")
|
||||
UCapsuleComponent* Capsule;
|
||||
|
||||
/** Mesh component (SkeletalMesh) like Character's Mesh */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Components")
|
||||
USkeletalMeshComponent* Mesh;
|
||||
|
||||
/** Your custom movement component */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement")
|
||||
UExtendedPawnMovement* MovementComponent;
|
||||
|
||||
|
||||
@@ -19,6 +19,12 @@ UFlipbookImageWidget::UFlipbookImageWidget(const FObjectInitializer& ObjectIniti
|
||||
TSharedRef<SWidget> UFlipbookImageWidget::RebuildWidget()
|
||||
{
|
||||
SynchronizeFlipbookProperties();
|
||||
|
||||
// Safe to construct here: RebuildWidget only ever runs on the game thread.
|
||||
if (!TickProxy.IsValid())
|
||||
{
|
||||
TickProxy = MakeUnique<FFlipbookTickableProxy>(this);
|
||||
}
|
||||
|
||||
Image = SNew(SImage).FlipForRightToLeftFlowDirection(bFlipForRightToLeftFlowDirection);
|
||||
return Image.ToSharedRef();
|
||||
@@ -104,53 +110,10 @@ void UFlipbookImageWidget::ReleaseSlateResources(const bool bReleaseChildren)
|
||||
{
|
||||
Super::ReleaseSlateResources(bReleaseChildren);
|
||||
|
||||
TickProxy.Reset();
|
||||
Image.Reset();
|
||||
}
|
||||
|
||||
void UFlipbookImageWidget::Tick(const float DeltaTime)
|
||||
{
|
||||
if (FrameCounter == GFrameCounter || !Image.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto Frames = 0.0;
|
||||
|
||||
Elapsed += DeltaTime;
|
||||
Elapsed = Threshold * FMath::Modf(Elapsed / Threshold, &Frames);
|
||||
CurrentFrame += Frames;
|
||||
CurrentFrame %= TotalFrames;
|
||||
|
||||
if (CurrentFrame != LastFrame)
|
||||
{
|
||||
Image->SetImage(GetBrushAtFrame(CurrentFrame));
|
||||
Image->InvalidateImage();
|
||||
LastFrame = CurrentFrame;
|
||||
}
|
||||
|
||||
FrameCounter = GFrameCounter;
|
||||
}
|
||||
|
||||
bool UFlipbookImageWidget::IsTickableWhenPaused() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UFlipbookImageWidget::IsTickableInEditor() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TStatId UFlipbookImageWidget::GetStatId() const
|
||||
{
|
||||
RETURN_QUICK_DECLARE_CYCLE_STAT(UFlipbookImageWidget, STATGROUP_Tickables)
|
||||
}
|
||||
|
||||
UWorld* UFlipbookImageWidget::GetTickableGameObjectWorld() const
|
||||
{
|
||||
return GetWorld();
|
||||
}
|
||||
|
||||
void UFlipbookImageWidget::SetFlipbook(UPaperFlipbook* Value)
|
||||
{
|
||||
if (Flipbook != Value)
|
||||
@@ -228,6 +191,30 @@ FORCEINLINE const FSlateBrush* UFlipbookImageWidget::GetBrushAtFrame(const uint3
|
||||
return &SlateNoResource;
|
||||
}
|
||||
|
||||
void UFlipbookImageWidget::TickFlipbook(const float DeltaTime)
|
||||
{
|
||||
if (FrameCounter == GFrameCounter || !Image.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto Frames = 0.0;
|
||||
|
||||
Elapsed += DeltaTime;
|
||||
Elapsed = Threshold * FMath::Modf(Elapsed / Threshold, &Frames);
|
||||
CurrentFrame += Frames;
|
||||
CurrentFrame %= TotalFrames;
|
||||
|
||||
if (CurrentFrame != LastFrame)
|
||||
{
|
||||
Image->SetImage(GetBrushAtFrame(CurrentFrame));
|
||||
Image->InvalidateImage();
|
||||
LastFrame = CurrentFrame;
|
||||
}
|
||||
|
||||
FrameCounter = GFrameCounter;
|
||||
}
|
||||
|
||||
FORCEINLINE void UFlipbookImageWidget::SynchronizeFlipbookProperties() noexcept
|
||||
{
|
||||
if (Flipbook)
|
||||
|
||||
@@ -9,7 +9,7 @@ class SImage;
|
||||
class UPaperFlipbook;
|
||||
|
||||
UCLASS(MinimalAPI)
|
||||
class UFlipbookImageWidget : public UWidget, public FTickableGameObject
|
||||
class UFlipbookImageWidget : public UWidget
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
@@ -19,16 +19,6 @@ class UFlipbookImageWidget : public UWidget, public FTickableGameObject
|
||||
|
||||
virtual void ReleaseSlateResources(const bool bReleaseChildren) override;
|
||||
|
||||
virtual void Tick(const float DeltaTime) override;
|
||||
|
||||
virtual bool IsTickableWhenPaused() const override;
|
||||
|
||||
virtual bool IsTickableInEditor() const override;
|
||||
|
||||
virtual TStatId GetStatId() const override;
|
||||
|
||||
virtual UWorld* GetTickableGameObjectWorld() const override;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category=Appearance)
|
||||
void SetFlipbook(UPaperFlipbook* Value);
|
||||
|
||||
@@ -112,6 +102,47 @@ private:
|
||||
|
||||
double Threshold;
|
||||
double Elapsed;
|
||||
|
||||
// Proxy that owns the FTickableGameObject registration. Constructed lazily
|
||||
// in RebuildWidget() (always game-thread) instead of in this UObject's own
|
||||
// constructor, which can run on the async loading thread.
|
||||
class FFlipbookTickableProxy final : public FTickableGameObject
|
||||
{
|
||||
public:
|
||||
explicit FFlipbookTickableProxy(UFlipbookImageWidget* InOwner)
|
||||
: Owner(InOwner)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Tick(float DeltaTime) override
|
||||
{
|
||||
if (UFlipbookImageWidget* Widget = Owner.Get())
|
||||
{
|
||||
Widget->TickFlipbook(DeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool IsTickableWhenPaused() const override { return false; }
|
||||
virtual bool IsTickableInEditor() const override { return true; }
|
||||
|
||||
virtual TStatId GetStatId() const override
|
||||
{
|
||||
RETURN_QUICK_DECLARE_CYCLE_STAT(FFlipbookTickableProxy, STATGROUP_Tickables)
|
||||
}
|
||||
|
||||
virtual UWorld* GetTickableGameObjectWorld() const override
|
||||
{
|
||||
const UFlipbookImageWidget* Widget = Owner.Get();
|
||||
return Widget ? Widget->GetWorld() : nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
TWeakObjectPtr<UFlipbookImageWidget> Owner;
|
||||
};
|
||||
|
||||
TUniquePtr<FFlipbookTickableProxy> TickProxy;
|
||||
|
||||
void TickFlipbook(const float DeltaTime);
|
||||
|
||||
FORCEINLINE void SynchronizeFlipbookProperties() noexcept;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public class ProjectEleriEditorTarget : TargetRules
|
||||
{
|
||||
Type = TargetType.Editor;
|
||||
DefaultBuildSettings = BuildSettingsVersion.Latest;
|
||||
//IncludeOrderVersion = EngineIncludeOrderVersion.Latest;
|
||||
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_8;
|
||||
|
||||
ExtraModuleNames.AddRange( new string[] { "ProjectEleri", "ProjectEleriEditor" } );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user