Code is run before code before it finishes

I am running code, and I have it run on a slight delay to make sure everything (Widget stuff) is rendered before running the code, delay works fine but I have a function that is run to update the changes at the end of the initialization process.

The orange message is run from inside of the “UpdateDynamicTexture” function, and the yellow message is, as you can see, sequentially before it. Also, the printed statements both are referencing the same variable, in this image, “DrawingWindowSize.X” and “DrawingWindowSize.Y”

The function reads all of the parameters as empty, or zero.

// Delay execution by 0.1 second to let everything load
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &UDrawingWindow::ExecuteAfterDelay, 0.1f, false);
if (GEngine)
{
    FString Message = FString::Printf(TEXT("X: %f   Y: %f   X*Y: %f"), DrawingWindowSize.X, DrawingWindowSize.Y, DrawingWindowSize.X * DrawingWindowSize.Y);
    GEngine->AddOnScreenDebugMessage(-1, 30.0f, FColor::Yellow, Message);
}

UpdateDynamicTexture(Canvas, BlankCanvas, 0, 0, DrawingWindowSize.X, DrawingWindowSize.Y);

image

void UDrawingWindow::NativeConstruct()
{
    Super::NativeConstruct();
    
    // Delay execution by 0.1 second to let everything load
    FTimerHandle TimerHandle;
    GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &UDrawingWindow::ExecuteAfterDelay, 0.1f, false);
    Eraser.R = 255, Eraser.G = 255, Eraser.B = 255;
}

void UDrawingWindow::ExecuteAfterDelay()
{
    AsyncTask(ENamedThreads::GameThread, [this]()
        {
            InitCanvas(DrawingPanel);
        });
}

void UDrawingWindow::InitCanvas(UImage* ImageWidget) {
    
    if (!DrawingWindowDimensions)
    {
        GetImagePositionAndSize(ImageWidget, DrawingWindowLocation, DrawingWindowSize);
        DrawingWindowDimensions = true;
    }

    Canvas = CreateDynamicTexture(DrawingWindowSize.X, DrawingWindowSize.Y);
    
    SetImageTexture(ImageWidget, Canvas);
    
    uint32 NumPixels = DrawingWindowSize.X * DrawingWindowSize.Y;
    //TArray<FColor> BlankCanvas;
    BlankCanvas.SetNum(NumPixels);
    for (uint32 i = 0; i < NumPixels; ++i) { BlankCanvas[i] = FColor(255, 0, 0, 255); }
    
    if (GEngine)
    {
        FString Message = FString::Printf(TEXT("Width: %f   Height: %f   Width*Height: %f"), DrawingWindowSize.X, DrawingWindowSize.Y, DrawingWindowSize.X * DrawingWindowSize.Y);
        GEngine->AddOnScreenDebugMessage(-1, 30.0f, FColor::Yellow, Message);
    }

    UpdateDynamicTexture(Canvas, BlankCanvas, 0, 0, DrawingWindowSize.X, DrawingWindowSize.Y);
}

bool UDrawingWindow::UpdateDynamicTexture(UTexture2D* Texture, TArray<FColor>& NewPixels, int32 X, int32 Y, int32 Width, int32 Height)
{
    
    if (GEngine)
    {
        FString Message = FString::Printf(TEXT("Width: %f    Height: %f"), Width, Height);
        GEngine->AddOnScreenDebugMessage(-1, 120.0f, FColor::Orange, Message);
    }

    if (GEngine)
    {
        FString Message = FString::Printf(TEXT("%f"), NewPixels.Num());
        GEngine->AddOnScreenDebugMessage(-1, 120.0f, FColor::Orange, Message);
    }

    if (NewPixels.Num() == 0)
    {
        return false;
    }
    

    if (!Texture) 
    {
        return false;
    }
    // Ensure the new pixel data matches the textures resolution
    if (NewPixels.Num() != Width * Height)
    {
        return false;
    }
    if (X < 0 || Y < 0 || X + Width > Texture->GetSizeX() || Y + Height > Texture->GetSizeY())
    {
        return false;
    }
    if (static_cast<int>(Width) == 0 || static_cast<int>(Texture->GetSizeX()) == 0 || static_cast<int>(Height) == 0 || static_cast<int>(Texture->GetSizeY()) == 0)
    {
        return false;
    }
    /*if (GEngine)
    {
        FString Message = FString::Printf(TEXT("X: %f   Y: %f"), X, Y);
        GEngine->AddOnScreenDebugMessage(-1, 120.0f, FColor::Blue, Message);
    }*/
    
    // Code below is commented because it crashes the client
    /*if (GEngine)
    {
        FString Message = FString::Printf(TEXT("Texture->Blueprint_GetSizeX(): %f"), Texture->GetSizeX());
        GEngine->AddOnScreenDebugMessage(-1, 120.0f, FColor::Blue, Message);
    }
    if (GEngine)
    {
        FString Message = FString::Printf(TEXT("Texture->Blueprint_GetSizeY(): %f"), Texture->GetSizeY());
        GEngine->AddOnScreenDebugMessage(-1, 120.0f, FColor::Blue, Message);
    }*/
    /*
    // Create an update region
    FUpdateTextureRegion2D UpdateRegion(X, Y, 0, 0, Width, Height);
    
    // Update the texture
    Texture->UpdateTextureRegions(
        0, // Mip level
        1, // Number of regions
        &UpdateRegion, // Pointer to the update region
        Width * sizeof(FColor), // Source row pitch
        sizeof(FColor), // Source depth pitch
        reinterpret_cast<uint8*>(NewPixels.GetData()) // Source data
    );*/
    return true;
}

This is the UEFN forum, not the Unreal Engine one. :sweat_smile:
I’m sorry but I don’t have any knowledge on UE.

I literally don’t know the difference, where do I find the real one?

You are on the correct forum.

You will need to provide more context though, the snippets you have provided are not sufficient. Post all relevant code.

Just added it, think I got everything important

Hey @mathman212,

UpdateDynamicTexture() is taking it’s X, Y, Width and Height parameters as ints, but you are formatting them as if they are floats (%f).

The compiler was maybe warning you about the implicit conversions from float to int, it should have been… but of course warnings are often ignored.

Either change the format specifier to %i when formatting those params (if you are happy with the implicit conversion) or change the signature of UpdateDynamicTexture() to take them as floats.

Thanks for the clarification, but it appeared as the UEFN & Creative forum when I clicked on the thread via the UEFN forum search. I refreshed the page and now it appears as the UE forum. Weird.

Thanks for the help, when I changed it I did start seeing actual values instead of just zeros. The program, however, still continued to crash, so for this I will mark your reply as an answer since it did resolve the immediate issue, however still not know what the issue was I found a post describing how to do exactly what I was looking for, so I’m going to try following that instead, I’ll link it here.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.