New 4.9 Get Class Defaults node doesn't have all the variables

56574-arrrrgh.png

Hi guys,

I love some of the new changes in 4.9, but I’m a bit confused about one, and it’s one I sorely need right now. I have a Skeletal Mesh variable in my class defaults for an item the character equips. This tells the character to display the item on them as a skeletal mesh.

Anyway, it doesn’t show up in the new Get Class Defaults node, and I’m very sad about that. Is this a setting I have to toggle, or am I SOL until we get a patch for it?

Thanks!

+1 I have exactly the same problem :frowning:

It doesn’t show e.g. Material, StaticMesh, SkeletalMesh, etc. type variables… And many more…

Bumpy bump? :frowning:

Slavq,

If you aren’t C+±averse (I sure am!) then you can also use ActorClass.GetDefaultObject() in C++, even making it a blueprint node to get whatever custom variables you want. I can’t help much more than that, unfortunately.

(This is what we ended up doing.)

Hope that helps some!

Thanks for the tip! I have a pure blueprint project and I would like to keep it in this state, but well… If there is no possibility doing this from BP, then I’ll watch some tutorials about how to create custom BP node in C++ :slight_smile:

Im curious though, if this issue with Get Class Defaults is caused by some bug or maybe it’s by-design…

It appears to be by-design. The only issue we ran into making a custom node that does the exact same thing is a crash when you return None on a Skeletal Mesh node, but that was an easy fix - you just have to catch the exception.

After checking some tutorials, I’ve managed to implement that, even when I’m a total noob with C++ :slight_smile: And I get this crash on SkeletalMesh value too. Could you tell me what exactly I should add (some line of code? :stuck_out_tongue: ) to prevent this crash?

Thanks, I’ve managed to get it working :slight_smile: You’re my hero!

If it’s the same issue we had initially, you probably need to check if the return value is valid.

In C++, something like “if thing == null, return null”, and I would recommend doing an IsValid check in your blueprint as well. There’s a node called “IsValid” with a ? icon next to it. Just route your return value through that. If it’s valid (not null) then do what you want to do, if it is, do nothing.

Hope that helps!

Hi Zaggoth,

The GetClassDefaults node does not currently expose object reference values by design; it’s current use is intended for exposing value types only. This is because Blueprints currently cannot enforce the read-only state of objects owned by the class default object that might be referenced through the return value, and the class default object’s state MUST be treated as read-only. Consider a situation where in one function you use some value in the default object as a basis for initialization; there is nothing in place that can currently prevent another event or function from mutating that object at runtime, which can result in potentially unpredictable behavior that can be difficult to debug. Objects would also not be instanced on access, so it would result in the “template” reference being used directly in all cases, so you wouldn’t want to do things like pass a default component reference in to an AttachTo node to parent it to another component, for example.

We are looking at potentially being able to expose object references as “read-only” meaning the Blueprint VM/compiler would not allow you to modify the state of the object that’s referenced by the return value. Unfortunately that is not something that’s on the roadmap yet for an upcoming release, but we are aware of this current limitation.

Without seeing the full use case here it’s a bit difficult to suggest an alternative, but assuming ‘GearMeshOnCharacter’ is a SkeletalMeshComponent that’s defined in the Blueprint class and set to a default value, I might suggest storing the SkeletalMesh Asset ID in the class defaults instead (choose ‘AssetID’ rather than ‘Reference’ for the ‘SkeletalMesh’ type when choosing the variable type). That way you can pull the asset ID value (rather than a component template reference) from the class defaults and set it to a SkeletalMeshComponent that you instance at runtime via an AddSkeletalMeshComponent node, and then you can set the skeletal mesh to that asset:

Does something like that sound like it might be a reasonable alternative?

Also as a side note, exposing a direct reference to the class default object through C++ to Blueprints is not recommended nor is it officially supported. There are various risks with doing that - basically you’ll need to avoid any potential side effects that might mutate the CDO state. So, just be careful with that. =)

Hope this helps!

There is also however another issue not mentioned anywhere as far as I can see. I can store and expose through class defaults an array of CLASS of a given object (not references nor assetID). But I cannot expose a single class that way. Is there any reason for such behaviour? Because right now I’m making an array of 1 element and all it does is pain in working with such work-around.

I believe it could be looked into in the future. Or is it an overlook that an array is visible at all?

Hi vipeout,

That issue is being addressed for v4.10.

Thanks!

Hiding your Vars inside a Struct will help, the struct gets exportet by the Get Class Defaults

I’ve just tried that and I can confirm that this works. Thanks for this workaround, will be useful! +1

While that can be a workaround, it’s risky for the reasons I outline above. So if you do go this route, be sure you’re not doing anything to mutate the object, or otherwise using the object reference directly for anything other than accessing its defaults.

I’ve used that AssetID workaround as well and it works fine. Except for one problem. When I have an array of assetID’s and try to load the assetID’s in a for loop, only the first asset gets loaded. Strange thing is that when the for loop reaches the next index of the array, the previous object is loaded instead of the one that is actually in the array at the position of the index. Which seems like very strange behavior. Does anyone know why this is?

Issues that I’ve run into when using for loops and storing variables:

  • You should store your asset IDs when they come out of the loop as references in a reference array (load them, and then store them)
  • With your new loaded asset array, you can call them individually or again with new for loops, unless you use your loaded assets immediately.
  • Don’t forget to use the “completed” switch on a for loop. What seems to be happening is that you’re assigning the loaded item “on top” of the previous loaded item.

These are some solution I can think of, having not seen your actual code. If you provide a ScreenShot of the BP’s, maybe I can help more.

I have posted a very simple solution here: https://answers.unrealengine.com/questions/299539/get-class-defaults-node-does-not-provide-texture2d.html?childToView=896116#answer-896116

Cheers,
Phoenix-Storms