Hi,
I started my first UE4 project and I’m struggling with implementation of something I designed. I tried many ways and each of them has disadvantages that I fail to omit. My goal is to have a C++ class extending AActor (it has a CollisionBox as a root component but that is irrelevant). The class should also “contain” variable amount of components in such a way that it is possible to select any particular component in UEditor and modify it’s properties. Let’s call the class DiffusionMesh and it’s components DiffusionNodes. Number of DiffusionNodes would change when I resize the box, and that part I have already implemented without problems. DiffusionNode has an UArrow component as a root for now, for testing purposes. Amount of DiffusionNodes inside Diffusion Mesh is hardcoded for now, but is suppose to be configurable in UEditor in DiffusionNode actor properties window. I want DiffusionNodes to be placed within collision box of DiffusionMesh therefore I attach these actors.
My first approach:
I implemented DiffusionNode as an ActorComponent subclass. Then I generated these components inside DiffusionMesh constructor (or OnStruct() inside method, can’t remember exactly now) with:
CreateDefaultSubobject<ADiffusionNode>(FName(*FString::FromInt(1000 * x + y)));
call and stored pointers in two dimensional TArray structure like this one:
TArray<TArray<ADiffusionNode*>> nodes;
This worked fine beside of the fact that I wasn’t able to select single DiffusionNode component in Viewport window. That didn’t bother me so much as I was able to select components in World Outliner window. The problem was that all DiffusionNode parameters were greyed out in UEditor and were read only because they missed the UPROPERTY() declaration.
I’ve found this threads:
but no good answers there.
So to summarise: declaring single DiffusionNode as a DiffusionMesh class member with proper UPROPERTY entry works good (it is possible to modify DiffusionNode properties in editor), but having a dynamic array of DiffusionNodes makes it impossible to expose their properties to edit in UEditor (even if the array declaration has UPROPERTY entry). Is there any way to dynamically generate and attach components to actor and still be able to edit them in editor?
My second approach:
I decided to implement DiffusionNode as subclass of AActor instead of actor component. Then I generate DiffusionNodes actors using this call:
ADiffusionNode* elem = World->SpawnActor<ADiffusionNode>(ADiffusionNode::StaticClass());
This makes it possible to select generated DiffusionNodes in viewport and edit their properties - great!
But now I’m dealing with another problem. For some reason when I drag my DiffusionMesh class (or a blueprint that derives from it) from content browser to my game level it actually creates two instances of this class. I added some console logging to class constructor to confirm that. First instance is created as soon as I hover mouse cursor with dragged class over my level in order to place it somewhere, and then the other instance is created when I release mouse button and drop the class somewhere. I imagine that the editor creates some temporary instance to visualise the actor while I’m dragging it and when I finally drop it then it creates the actual instance that is used in simulation. What is interesting is that no destructor is called after dropping the class, therefore the number of generated DiffusionNodes is doubled. For example when the amount of DiffusionNodes to be generated is hardcoded to 4, I can see 8 of them in both viewport and world outliner. I can see only one DiffusionMesh actor though.
I guess that creating two (or more) instances of an actor is just the way editor works and is not a bug. But in this case - what would be the best way of generating actors by some AActor subclass so that they are not doubled?
Currently generate actors inside OnConstruction() method. I compare hardcoded desired actors (DiffusionNode) amount to length of TArray<> where I store pointers to them so that they are generated only once (as long as desired amount is not increased).
I’m curious the answers of both main questions I asked above, but if you have any suggestion of totally different approach to designing and implementing my classes then I’ll also be grateful. Basically what I want to achieve is to have one class/blueprint visually represented by a “box” that I drag into my level, set it’s size, and automatically generate my other custom “objects” within the box with given density. So the larger box dimension I set the more objects will be generated. The density of objects is to be configured in the box actor properties. Both box and objects needs to have some custom members and methods. The essential thing is to be able to edit “objects” properties in editor. Whether objects are generated automatically upon resizing the box or it is triggered by some manual action of mine is unimportant as long as it happens in level editing mode in editor.
Regards, ’