I was able add a componenet using the AddComponent(…) function, although I have no idea if it works or is “equivalent” to the previous Components.Add() call. But here’s what I did.
It built, but whether it works the way the Documentation writer intended is another story (maybe yes, maybe no, I don’t know). I had to do the same thing for the Sphere1 component mentioned in the previously mentioned Document.
PS, you don’t need to use the “this” pointer, you could just make a call to AddComponent directly, I only used it to get a grasp on IntelliSense.
PPS: I’m not up and up on the proper way to init m_FTransform, the default constructor inits it with “garbage values”, which I assume is not zeroes, so that might cause some issue with placement of the component in the engine/editor. I’ll see about getting it filled with zeroes, I think that’s what we’d want.
EDIT: This should do it
PS, if you’re wondering why i used 0.0 instead of 0, it’s because 0 is an INT and 0.0 is a floating point value. No need for implicit conversions here.
Thanks for the catch on this, I’ll make sure to email so we get it fixed up :).
We recently changed away from requiring adding things directly to the components array and removed it as you found out. When you create components in the constructor as in the example on the documentation, those components will automatically be added/registered with the actor that is its outer (the first parameter to the CreateDefaultSubobject call). So it should work as written, you just don’t have to manually add it to a components array anymore. An important thing to note though is that you should assign components you make this way to UPROPERTY variables, as the example does, because without the components array that used to exist keeping a reference to them, they would otherwise be garbage collected.
definitely less useful, but would it do the trick?
I’m curious, would they be garbage collected even if you kept a pointer/reference to them in your class? I’m familiar with garbage collection happening when no references to the heap memory location is on the stack, does this mean that Actors “live” on the heap themselves? I guess that makes sense, you can’t always tell what actors are needed before runtime.
Anyway, I hope you understand this leaves a bit of a gap in the usefulness of the tutorial. Sure, we know how to add components in the constructor, but what if we wanted to add/remove them dynamically during runtime? Would a call to PCIP.CreateDefaultSubObject<type>(this, “name”) be enough in a regular member function too? I’ll try out a couple test builds and report what I find, but some confirmation would be nice. If this thread gets some more love I’ll work on getting it’s SEO spot up on Google.
The components array itself is gone now, but yes, if you call CreateDefaultSubobject in the constructor, it should do the equivalent of what the components array used to do for you automatically. You do need to save a reference to it, so you want something more like your first code snippet there instead of the second one. As long as you have a UPROPERTY pointer to it in your class, it shouldn’t get garbage collected.
I agree with you re: the tutorial, but thankfully due to your report, I confirmed we already entered a bug in our database to get that fixed up. Thanks again for the find! You can add and remove components dynamically at run-time, though I’m pretty sure the syntax differs and I don’t recall it off the top of my head. I’m actually at home right now and don’t have the full source downloaded on this PC yet, so I’ll have to wait until I’m back in the office tomorrow to get you a better answer for that particular part of your question though.
Quick follow-up on this now that I’m back at the office:
If you want to create a component during run-time, you’d want to do something like this (example of adding another static mesh component to an actor at run-time):
SampleMeshComponent = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass(), this);
// Set whatever additional variables, etc. on the component you want here. For a static mesh component, you'd probably want to give it an actual mesh to use (SampleMeshComponent->SetStaticMesh(SomeUStaticMeshAssetHere))
// Attach the component to whichever scene component you want it attached to. For this example, attached to the root component of the actor.
// Register the component
Also, there are some templated helper functions NewObject and NewNamedObject you can use instead of ConstructObject, if you prefer. If you want to destroy the component later, you can just call DestroyComponent() on it.
Sorry, not trying to high-jack your thread just to be the grammar police, but, the word you spelled (and Im guessing how you pronounce it) are wrong; its “deprecated” and is pronounced differently as well. I worked with a guy that would always tell me things were “depreciated” and it confused the hell out of me
For the Brightness member variable, it looks like it was also renamed to “Intensity” so you could just do: PointLight1->Intensity= DesiredBrightness; or you could use the SetBrightness() function like Bleakwise mentioned. Though if you look at the source code of that function you’ll see it just sets the Intensity variable.
Yes, without some form of property reference the garbage collection system will not identify it as referenced and clean it up.
The purpose of the CreateDefaultSubObject is to properly set up the sub object’s relationship to the class such that when you instantiate an instance of the class from the default object you get a unique copy of the sub object rather than a reference to the same sub object.
Thanks to everyone for pointing out the code fixes and helping each other out. The tutorial has been updated to include these changes! Going over it just now, I noticed a few more Brightness -> Intensity changes that needed to be made, but those are cleaned up and should be fixed in the next version of the tutorial. Thanks again for the feedback - keep it coming!