c++ – Creating an external tool to edit Unreal project optimization settings

INTRO

I am creating a C++ app that will help users to set up optimization settings in the Unreal game engine. I want to let the program make all this work on its own. This application is being written for Windows 10 platform (maybe it will be cross-platform in the future).


PROBLEM DESCRIPTION

To make the program working as intended, I must be able to change configuration files, add some UE objects to the project and call editor functions (e.g. rebuild lights).


MY SOLUTION

I can parse some of the .ini files and edit them. However, the real problem is with UE objects and editor functions. One of the possible ways is to get symbols from the .dll and run that function in a separate process. Another way is to use the actual UE4 code for these tasks.


QUESTION

Is there any easier and safer way to achieve what I need?

unreal 4 – Why is the Set new visibility doesn’t resets the hair’s skeletal mesh visibility to be visible?

The helmet is loaded when pressed a defined key and helmet is removed automatically by setting the remove on 2s delay.
The Problem when the helmet is removed, the hairs visibility doesn’t sets to be visible while blueprint is set to restore the visibility.
setvisibility and sethiddeningame both are tested, none of them works.
How to fix it? any help appreciated.
BLUEPRINT 1
BLUEPRINT 2

c++ – Unreal Engine Procedural Mesh causing crash when rendering chunk size too large

Hey guys im pretty new to unreal but id consider myself a fairly advanced programmer. Im really stuck on rendering my chunks for my voxel game. The implementation is pretty simple and everything works wonders when the chunk sizes are less than 16x16x16. But when i try to render a chunk larger i get a crash.

here is my soruce

   void AVoxelActor::OnConstruction(const FTransform& Transform)
{
    numVoxelsXY = 16;
    numVoxelsZ = 64;

    //create name
    FString string = "Voxel_" + FString::FromInt(chunkXPos) + "_" + FString::FromInt(chunkYPos);
    FName name = FName(*string);

    //create mesh comp and register
    proceduralMeshComponenent = NewObject<UProceduralMeshComponent>(this, name);
    proceduralMeshComponenent->RegisterComponent();

    RootComponent = proceduralMeshComponenent;
    RootComponent->SetWorldTransform(Transform);

    Super::OnConstruction(Transform);

    GenerateChunk(); 
    UpdateMesh();
}



void AVoxelActor::GenerateChunk() {
    m_vBlocks = new VoxelBlock * *(numVoxelsXY);
    for (int i = 0; i < numVoxelsXY; i++) {
        m_vBlocks(i) = new VoxelBlock *(numVoxelsXY);
        for (int j = 0; j < numVoxelsXY; j++) {
            m_vBlocks(i)(j) = new VoxelBlock  (numVoxelsZ);
            
        }
    }
}



void AVoxelActor::UpdateMesh() {

    
    TArray<FVector> Vertices;
    TArray<int32> Triangles;
    TArray<FVector> Normals;
    TArray<FVector2D> UVs;
    TArray<FProcMeshTangent> Tangents;
    TArray<FColor> VertexColors;

    int32 elementID = 0;


    bool lDefault = true;

    for (int x = 0; x < numVoxelsXY; x++) {

        for (int y = 0; y < numVoxelsXY; y++) {

            for (int z = 0; z < numVoxelsZ; z++) {



                //Check if block exists else dont render anything
                if (m_vBlocks(x)(y)(z).IsActive() == false) { // Don't create triangle data for inactive blocks
                    continue;
                }

                //check faces to see if they are visible or not to render
                bool lXNegative = lDefault;
                if (x > 0) lXNegative = !m_vBlocks(x - 1)(y)(z).IsActive();
                bool lXPositive = lDefault;
                if (x < numVoxelsXY - 1) lXPositive = !m_vBlocks(x + 1)(y)(z).IsActive();
                bool lYNegative = lDefault;
                if (y > 0) lYNegative = !m_vBlocks(x)(y - 1)(z).IsActive();
                bool lYPositive = lDefault;
                if (y < numVoxelsXY - 1) lYPositive = !m_vBlocks(x)(y + 1)(z).IsActive();
                bool lZNegative = lDefault;
                if (z > 0) lZNegative = !m_vBlocks(x)(y)(z - 1).IsActive();
                bool lZPositive = lDefault;
                if (z < numVoxelsZ - 1) lZPositive = !m_vBlocks(x)(y)(z + 1).IsActive();



                //create mesh and vertices info for faces of cube that are visible
                int triangle_num = 0;
                for (int i = 0; i < 6; i++)
                {

                    Triangles.Add(bTriangles(0) + triangle_num + elementID);
                    Triangles.Add(bTriangles(1) + triangle_num + elementID);
                    Triangles.Add(bTriangles(2) + triangle_num + elementID);
                    Triangles.Add(bTriangles(3) + triangle_num + elementID);
                    Triangles.Add(bTriangles(4) + triangle_num + elementID);
                    Triangles.Add(bTriangles(5) + triangle_num + elementID);
                    triangle_num += 4; // add 4 vertices to next triangle

                    switch (i)
                    {
                        case 0: {
                            if (lZPositive) {
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));

                                Normals.Append(bNormals0, UE_ARRAY_COUNT(bNormals0));
                            }
                                break;
                            
                        }

                        case 1: {
                            if (lZNegative) {
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));

                                Normals.Append(bNormals1, UE_ARRAY_COUNT(bNormals1));
                            }
                                break;
                            
                        }

                        case 2: {
                            if (lYPositive) {
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));

                                Normals.Append(bNormals2, UE_ARRAY_COUNT(bNormals2));
                            }
                                break;
                        
                        }

                        case 3: {

                            if (lYNegative) {
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));

                                Normals.Append(bNormals3, UE_ARRAY_COUNT(bNormals3));
                            }
                                break;
                            
                        }
                        case 4: {
                            if (lXPositive) {
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector((voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));

                                Normals.Append(bNormals4, UE_ARRAY_COUNT(bNormals4));
                            }
                                break;
                        }
                        case 5: {
                            if (lXNegative) {
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), (voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), -(voxelSize / 2) + (z * voxelSize)));
                                Vertices.Add(FVector(-(voxelSize / 2) + (x * voxelSize), -(voxelSize / 2) + (y * voxelSize), (voxelSize / 2) + (z * voxelSize)));

                                Normals.Append(bNormals5, UE_ARRAY_COUNT(bNormals5));
                            }
                            break;
                        }
                    }
                          UVs.Append(bUVs, UE_ARRAY_COUNT(bUVs));
                          FColor color = FColor(255, 255, 255, i);
                          VertexColors.Add(color); VertexColors.Add(color); VertexColors.Add(color); VertexColors.Add(color);
                    
                }
                elementID += triangle_num;
            }


        }

    }
    proceduralMeshComponenent->ClearAllMeshSections();
    proceduralMeshComponenent->CreateMeshSection(0, Vertices, Triangles, Normals, UVs, VertexColors, Tangents, true);
}

and this is the error i get, also if i turn off the collison generation for the mesh i can generate no problem. This makes me believe that its a performance issue causing the crash but i am completely stuck

Exception thrown at 0x00007FFCAA395092 (PhysX3CookingPROFILE_x64.dll) in UE4Editor-Win64-DebugGame.exe: 0xC0000005: Access violation reading location 0x0000016947772F38.

unreal 4 – Custom event doesn’t update blueprint variables

Here’s what I have:

enter image description here

To sum it up: calling the OnInteract event (which comes from an interface) prints the ‘Proceed’ variable. Clicking Fire sets the variable to true and prints it. ‘Proceed’ is false by default.

The problem is that the OnInteract event always prints ‘false’, even if the Fire event has been called. The Fire event correctly prints ‘true’, but if I call the OnInteract event later, it still prints ‘false’, even though logically the variable should be ‘true’.

No outside entity is changing the variable. If I set the default value of the variable to ‘true’, it prints ‘true’. The entire project is just the First Person template, a single blueprint actor whose entire event graph is what you see in the screenshot, and an outside entity calling the OnInteract event when I press the button.

Curiously, if I ditch the OnInteract event completely and replace it with InputAction Jump, the code works as expected and prints ‘true’.

What’s going on? This is so simple, and yet it has me beat.

c++ – Unreal Engine 4: Referencing an asset with asset user data instead of a class?

I created a subclass of Uassetuserdata, creating a new type of asset. Now I can reference this new class in the user asset data section of my skeletal mesh. I noticed that I could create a blueprint subclass of this new class, blueprint that I can put anywhere in my project and call from the user data section of my mesh.

Now I’m wondering, is it possible to call an asset belonging to my new class and not the class directly in the user data asset section? An asset that wouldn’t be a blueprint. I did create a new factory for my new class so that I can spawn assets of it in my project, but I can’t call them in the asset user data section of my mesh, only the class itself. I’m pretty sure I saw someone do it once but I can’t remember how. Do you have any ideas? Thank you!

unreal 4 – Cannot create EAttachmentRule variable in a Blueprint struct

I’m trying to add a EAttachmentRule variable in a struct but the enum doesn’t appear in the list of available types

enter image description here

I managed to create a variable in a BP by dragging the pin from an AttachActorToComponent node and promoting it to a variable. But I can’t do the same thing to create a variable in a struct

unreal 4 – Unable to turn project into exe file

I’m new to Unreal Engine and I’ve been looking for an answer online but I don’t understand why my project I just started on is unable to project. I used only blueprints. Here is the log.

UATHelper: Packaging (Windows (64-bit)): Running AutomationTool…
UATHelper: Packaging (Windows (64-bit)): Parsing command line: -ScriptsForProject=C:/Users/belmo/OneDrive/Documents/GitHub/EscapeFromDarksidePenitentiary/EscapeFromDarkSide/EscapeFromDarkSide.uproject BuildCookRun -nocompileeditor -installed -nop4 -project=C:/Users/belmo/OneDrive/Documents/GitHub/EscapeFromDarksidePenitentiary/EscapeFromDarkSide/EscapeFromDa
rkSide.uproject -cook -stage -archive -archivedirectory=C:/Users/belmo/OneDrive/Documents/GitHub/EscapeFromDarksidePenitentiary/EscapeFromDarkSide -package -ue4exe=”C:Program FilesEpic GamesUE_4.26EngineBinariesWin64UE4Editor-Cmd.exe” -ddc=InstalledDerivedDataBackendGraph -pak -prereqs -nodebuginfo -targetplatform=Win64 -clientconfig=Development -utf8
output
UATHelper: Packaging (Windows (64-bit)): Setting up ProjectParams for C:UsersbelmoOneDriveDocumentsGitHubEscapeFromDarksidePenitentiaryEscapeFromDarkSideEscapeFromDarkSide.uproject
UATHelper: Packaging (Windows (64-bit)): ********** COOK COMMAND STARTED **********
UATHelper: Packaging (Windows (64-bit)): Running UE4Editor Cook for project C:UsersbelmoOneDriveDocumentsGitHubEscapeFromDarksidePenitentiaryEscapeFromDarkSideEscapeFromDarkSide.uproject
UATHelper: Packaging (Windows (64-bit)): ERROR: Cook failed.
UATHelper: Packaging (Windows (64-bit)): (see C:UsersbelmoAppDataRoamingUnreal EngineAutomationToolLogsC+Program+Files+Epic+Games+UE_4.26Log.txt for full exception trace)
PackagingResults: Error: Cook failed.
UATHelper: Packaging (Windows (64-bit)): AutomationTool exiting with ExitCode=25 (Error_UnknownCookFailure)
UATHelper: Packaging (Windows (64-bit)): BUILD FAILED
PackagingResults: Error: Unknown Cook Failure
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogEditorViewport: Clicking on Actor (LMB): StaticMeshActor (Cube11)
LogSlate: Window ‘Output Log’ being destroyed
LogSlate: Window ‘Output Log’ being destroyed
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogD3D11RHI: CreateSwapChainForHwnd failed with result ‘DXGI_ERROR_INVALID_CALL’ (0x887A0001), falling back to legacy CreateSwapChain.
LogEditorViewport: Clicking on Actor (LMB): StaticMeshActor (Cube11)

unreal 4 – An inherited scene component has no details panel and can’t be moved

I’m making an fps, and I’m spawning the gun at a location on the player character. To do this I added a scene component to the players class, and that is what the gun is attached to when it is spawned. ( the scene component was added after I had created the blueprint derived from the cpp class). This worked fine, and the gun is spawing. Its spawning at the bottom of the character however, so I need to move the scene component to where I want the gun to spawn. When I try to do this, I notice there’s no widget to move the component, and it has no details in the details panel. I tried creating a new blueprint derived from the class to see if the details would work there, but they didn’t.

here’s my header file code for creating the object:

USceneComponent* GunSpawnPoint;

And here’s my cpp constructor code:

AGunBase::AGunBase()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
    RootSceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
    RootSceneComponent->SetupAttachment(RootComponent);
    GunMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
    GunMesh->SetupAttachment(RootSceneComponent);
    BulletSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("Spawn Point"));
    BulletSpawnPoint->SetupAttachment(GunMesh);
}

Is this a bug? How do i fix this?

Unreal virtual function causing unresolved external error

I’m making a base gun cpp class that just has the stuff all the other guns will have. I have a virtual function called PullTrigger that doesn’t do anything, I just want to have it on the base gun so i can implement it on the derived classes without recreating it. in my header file under private, I have this code

virtual void PullTrigger();

I tried adding override after the parantheses, but it gave me an error. As is, VS is uncomplaining, but Unreal says the function has an “Unresolved external symbol”. I have no clue what that is. How do i fix this?