When subclassing UPhysicsAsset I get linker errors where it can’t export the virtual functions which UPhysicsAsset overrides from UObject and IPreviewMeshProviderInterface.
Please help me understand how to subclass this class. I also need to subclass other engine classes like UBodySetup also and hopefully the answer to this applies to the others.
Hmm… that’s odd. How would I expose the initializer? Would a small modification and a pull request suffice for all further classes I want to subclass to be supported in future releases? I read somewhere that when a user was trying to subclass the capsule component, the issue was that the class itself was missing the ENGINE_API from the necessary member functions. Could that be the same case for these particular functions?
Its a pretty strange, and the types of error messages are vague at best.
Also stepping through the code adding breakpoints to both classes contructors I can confirm that UMyPhysicsAsset calls UPhysicsAsset in it’s super part so it should be constructed!
there is a message that stands out
my local path to project\MyPhysicsAsset.cpp’ is looking for a generated cpp with named ‘PhysicsAsset.gen.cpp’
Perhaps PhysicsAsset needs it’s generated version for this to work?
I have it in my source compiled version of the engine ue_5_3_2_Source\Engine\Intermediate\Build\Win64\UnrealServer\Inc\Engine\UHT\PhysicsAsset.gen.cpp
though the compile should resolve this on it’s own during the build process
Hmm Subclassing UAnimationAsset I see that it works flawlessly without having to manually make overrides and that the Super call also works. The difference between the UAnimationAsset and the UPhysicsAsset is that the same functions used for the UObject Interface are set with the ENGINE_API macro.
UAnimationAsset Header:
ENGINE_API virtual void Serialize(FArchive& Ar) override;
/** Get available Metadata within the animation asset
*/
const TArray<UAnimMetaData*>& GetMetaData() const { return MetaData; }
/** Returns the first metadata of the specified class */
ENGINE_API UAnimMetaData* FindMetaDataByClass(const TSubclassOf<UAnimMetaData> MetaDataClass) const;
/** Templatized version of FindMetaDataByClass that handles casting for you */
template<class T>
T* FindMetaDataByClass() const
{
static_assert(TPointerIsConvertibleFromTo<T, const UAnimMetaData>::Value, "'T' template parameter to FindMetaDataByClass must be derived from UAnimMetaData");
return (T*)FindMetaDataByClass(T::StaticClass());
}
ENGINE_API void AddMetaData(UAnimMetaData* MetaDataInstance);
void EmptyMetaData() { MetaData.Empty(); }
ENGINE_API void RemoveMetaData(UAnimMetaData* MetaDataInstance);
ENGINE_API void RemoveMetaData(TArrayView<UAnimMetaData*> MetaDataInstances);
/** IInterface_PreviewMeshProvider interface */
ENGINE_API virtual void SetPreviewMesh(USkeletalMesh* PreviewMesh, bool bMarkAsDirty = true) override;
ENGINE_API virtual USkeletalMesh* GetPreviewMesh(bool bFindIfNotSet = false) override;
ENGINE_API virtual USkeletalMesh* GetPreviewMesh() const override;
Then the UAnimationAsset also has the same include line so I am sure it must be the lack of ENGINE_API macros on those UObject interface functions.
UAnimationAsset Source:
include UE_INLINE_GENERATED_CPP_BY_NAME(AnimationAsset)
I’ll try to build Unreal Engine from source to try testing it. Otherwise if you could validate my findings it would be helpful. There may be some other differences too. Thanks!
Well the UPhysicsAsset is only ever created from with in the editor from within a skeletal mesh panel. Even if you create an instance “by hand” there are very little you can change about it. You can’t for instance choose the parent class as you can with other blueprint classes.
So this might be an engine limitation (maybe some form of low level optimization), as it is a physics object that may run on different logic (a separate physics thread decoupled from the main game thread).
I’ve tried building the project based on a source version of 5.3.2 and it spits out the same errors
Ah, so… I am overhauling the entire physics system so that I can use a research based physics engine to perform AI training of accurately simulated characters. I am trying to get the base UPhysicsAsset to incorporate with the asset I am already making. I also have the asset editor semi built and the component which goes along with it etc. So there’s more going on behind the scenes. I would like to be able to use the classes in the Physics engine line that inherits from UObject which is the main motivation for solving why I can’t inherit these classes. Though since you modified and build UE5.3.2 already it looks like there’s more to the issue. I’m gonna try looking into it more, gonna grab me a source UE5 now. Thanks.
That’s funny. The fact that I can click on the new class wizard and then make a new class derived from UPhysicsAsset even though MinimalAPI is specified is very confusing. Oh wells, I have UE 5 source available now and so I guess its gonna be a branch for the physics engine I’ll be using. Well lets see if it works when I get back to it after work.
Oh yay! Thank you so much! I figured it out. Looking at the UAnimationAsset I noticed it also had the MinimalAPI flag but was still subclassing. So I added the ENGINE_API macro to the functions that had linker issues in UPhysicsAsset and that solved the export problem! Requires modification of Unreal Engine Source though. But hey hopefully a game with fully simulated ai characters comes in the near future!