Download

[FEATURE REQUEST] Construction script for BP components

Hi,

Id like to procedurally add meshes in various blueprints.
It would be cool to place that into a BP component so this ability could be added to various BPs.
But for that BP components would need to have a construction script…

Cheers,
Klaus

I put my construction script relevant stuff into its own function which I can then call either from the main construction script or even during runtime, if I need to :smiley:

In the same way I just call a construction function in my child blue prints

Say, I have an array full of data and several functions that spawn meshes according to that data.
Some BPs need that, some dont. But inheritance is not really feasible in this case.
Id like to have that encapsulated together, so I can have several instances with different array values.
Components would be ideal to give a BP this mesh spawn toolset, or not.

But I just discovered that you cant even create static mesh components inside BP component functions, so I guess the component approach is dead anyway :frowning:

well I have something working that does spawn instances of another blueprint (no inheritance) and of each instance of these I can assign different values and trigger different behaviors and such. Though I only advice doing that low frequency, e.g. during construction. :slight_smile:

I always failed with that.
In the construction script, I could set values for the spawned new BP actor, but it would not get applied.

This is an older post aboout it. Maybe you can shed some light what is going wrong there?

https://forums.unrealengine.com/showthread.php?68646-Still-a-problem-with-acessing-a-child-actor-component-s-variables&highlight=fassade

It would be really cool to solve this type of problem :slight_smile:

Gooooooooooood morning :smiley:

Have you been able to test the possible solution we discussed?

For those who weren’t in our Skype call:

  • YES, changing properties of a child BP does not trigger that child BP’s Construction Script

  • the solution is to move the BP-implementation of your Construction Script to its own function and call that function from the CS as well as from the parent BP to update the thing :smiley:

Hi,

Just sent you a skype msg :stuck_out_tongue:

I recreated a simple example case, and its still not working :frowning:
If I call the building function of the child from within the parents constructor… nothing happens.

Here is an overview:

This is a simple BP that creates some meshes, based on an Instance and height offset parameter.
The implementation happens in the BuildStuff function.

SubConst.JPG

This is the BuildStuff function:

SubBuild.JPG

If I place them in the level, they work like a charm, even at construction time:

SubEditor.JPG

So, now I define a struct for some data for the “Master” BP:

7a29bf14c8a59d3d972ccc17fda7a5deaf2eb6c2.jpeg

And the Master BP also implements its stuff in a dedicated function, called BuildBPs:

MasterConst.JPG

The implementation of BuildBPs spawns now the SubBPs and calls its BuildStuff function…

f5e966e9703f4ab6d97387cbf304ec8e9206ceb5.jpeg

But in the editor, nothing is happening. Not at designtime, nor during gameplay of course… :frowning:

c61a4fdb91209abbe5d0bb3a44d6c8668d73a9e3.jpeg

BUT: If I hook up the BuildBPs function in the master BP begin play event, like so:

7f9e66026fd965bd542c2f1d146dc230ef219410.jpeg

Then I get the spawning during gameplay:

d2c0a81104e1a1029a672dd554c8fa2b5d83c7e6.jpeg

But this is not really usefull for a lot of reasons. I cant design a whole urban environment “into the blind” and only see during PIE where my buildings are…
Since they are not spawned before BeginPlay, they cannot receive any lightmass attention. Hence the warning in the screenshot above…
Plus a lot of warnings about it:

errors.JPG

Of course. I set them to be static, but spawning at Begin Play just isnt…

So even with the function being explicitly called… Nothing happens.
If that would be fixed/possible, Blueprint would be a fully fledged “Prefab” system…

Or am I still doing something stupendously wrong here :confused:

Cheers,
Klaus

thanks for the in-depth reply. As discussed in Skype we will continue adding a little code and then post the results here. I am confident that we can make it work - even if it means adding a little black magic :wink:

Whenever something isn’t working as expected, check the output log tab first!
In this case, it will be telling you that you’re not allowed to spawn new actors from within a construction script. I think this is an intentional limitation - it’s one thing to keep track of what components were created procedurally and remove them when the script is rerun, but to try to have such dependencies between actors would likely get out of hand rather too quickly.

You should be able to achieve what you want, but you’ll have to do it with components only, meaning you can only have one construction script driving the whole process.

The problem with that is that BP components cant create static mesh components. Just found out that the node is simply not available in components. :frowning:

Yep that’s true, you’d have to do it all directly from the actor construction script.
I think your original request would be nice to have, was just pointing out what you can/can’t do currently.

So one is actually encouraged to abandon all OOP wisdom and create a monster class on purpose…:rolleyes:
On the other hand. In my world outliner, I would only have one actor for the entire level geometry. However, this actor would then have thousands of functions and public variables… :frowning:

Sure.
Lets hope Epic catches the drift :smiley:

PS: And making it a single actor would also mean that if I change one value, the entire script is rerun…
That rules out the creation of large environments…

Oh, and just for the sake of completeness: The macro approach is also not possible. :frowning:

A macro like this:

6d3945036f5078dad753b09de398a09ff2ba44b4.jpeg

produces this, when used:

266498a812010e4a90ae42ae73f8a5597cd9dbfa.jpeg

It really seems to be impossible to add static meshes in any organized fashion. :frowning:

Can you use C++?

Why not write some helper methods (actually a Blueprint Function Library) which provides the functionality you want? For example, a static method which takes an actor and a static mesh and creates and attaches a static mesh component to that actor?

Im not very good at C++ (still early learner), especially with the Unreal specifics of C++…

Did you try using “Add Child Actor Component”?

Edit:

Actually, I dont quite understand why you would want to use a construction script inside components to provide functionality. This is in my opinion the wrong approach. I agree with the above statement to use methods to add static mesh components to an existing actor.
Also, instead of spawning actors you will want to add them as child actors through the “Add Child Actor Component” Node. You will not be able to pass anything to the “Exposed on Spawn” Variables of the child actor, so its construction script will run with the default parameters. But you receive a pointer to this child through the above mentioned node and you can set its exposed variables afterward. After setting them, you will want to rerun the construction script. This currently seems to be not supported by the engine (that is: manually rerunning the construction script) but it is possible through C++ afaik. I have already tried it today, when I had to leave in a rush and it basically worked for except one problem. I will try to fix it next week though, after I have consulted the community about what I am trying to do xD

Edit2: Please correct me if I am off or wrong with anything I point out or when you have something to point out, dont keep it to yourself :smiley: Im still new to unreal engine (I started a few months ago)

In the end they are supposed to be independent actors.
Id like to split functionality on the actor level. A house BP knows how to build a house from modular meshes and given parameters about story count, roof type, etc.
Now I want a cityblock BP that places those house actors in a fashion so they form a pattern, again driven by parameters.
The City BP would then place a couple of cityblocks, together, set their values, to form a city.
Then I can still go into each placed house or cityblock and tweak the actor values individually.
Rerunning the construction script would indeed be required after a value change. So for a house BP, the script would need to rerun either when I change a value in the details panel, or change a value in the cityblock BP (holding a reference to the house BP), which is then supposed to rebuild the house(s).

I just want to avoid constructing a city with houndrets of (more or less individual) houses in one huge levelscript or something, because if i change just one value on one of the meshes, the whole city would be rebuilt.

That is exactly what I am doing as well and it works. Last time, I had some troubles reading the values of the child BP actor afterwards, but I think that was due to me reading the value before I had reconstructed it (and thus the value was just the default value of 0). When I read the value after reconstruction in the very same Blueprint, it was the way I expected it.

What I am doing is the following (you will need a C++ project - I hope your project is not just for blueprints):

  1. Create a new C++ class named “MyBlueprintFunctionLibrary” or however you want to call it and inherit from BlueprintFunctionLibrary
  2. The header file looks like this:

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"

/**
 * 
 */
UCLASS()
class MYGAME_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:
	UFUNCTION(BlueprintCallable, Category="GlobalFunctionLibrary")
		static void CallMe(class AActor* actor);
	
};

  1. The source file looks like this:

// Fill out your copyright notice in the Description page of Project Settings.

#include "MYGAME.h"
#include "GameFramework/Actor.h"
#include "MyBlueprintFunctionLibrary.h"



void UMyBlueprintFunctionLibrary::CallMe(AActor* actor){
	actor->RerunConstructionScripts();
}


There are other methods available you could call on an actor in order to reconstruct it, but I am not sure what the difference is and which would be the best way. I also wonder why there is no default node to reconstruct a BP, so maybe there is a catch? I am going to post a question about it though, so stay tuned maybe?

After you hit compile in your editor, you can access this method from anywhere in every blueprint as a node.

Edit: Be aware of loops. If you call this method inside the construction script of two actors on each other, you will end up causing an infinite loop

This functionality would still be useful, it’s an oversight to not implement it.

I have an actor component that enhances the behaviour of whatever actor it’s added to. Unfortunately you can’t see the effects of it in the editor until you hit play because it’s lacking a construction script. The intent is to simply add it to any actor and it just works, but instead the user now specifically has to call its construction function from within their actor’s construction script.

In my example I can add a skeletal mesh actor to the world and attach my component and during play it works as intended, but if I want it to look right in the editor I now have to add a blueprint specifically for that use case, even though the only thing it does is call a construction function. This is pointless structural bureaucracy.

This could be done much better. I don’t see the reasoning behind NOT having a construction script in a component either by design or by the limitations of the framework. For a publisher it is much easier to simply indicate which component to add to an actor than to also need to show people what blueprints they need to make for it to work. This defies the purpose of components. They should be as self-encapsulated as the developer wants them to be.

Why not just create the meshes as components from within the actor ?

Though your example with the boxes, these would rather be independent actors.

so, implement your oop at the actor level, not component.

Look into the factory design pattern. You can create one instance of a ‘factory’ bp, that handles all spawing and deleting of a certain type of actor bp