Package/asset naming woes

I’m quite confused by how package and asset naming works. This is what I’ve got right now:

  1. Package is created, named /Game/MyAssets/Textures/turret4Diffuse
  2. Texture2D is created with package as outer
  3. Texture saves into /Game/MyAssets/Textures/ as “Texture2D_8” or similar. I actually want it to be named “turret4Diffuse” in the content browser.

If I try to rename the package or the texture, I get:

Fatal error: [File:D:\BuildFarm\buildmachine_++UE4+Release-4.11\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp] [Line: 168] 
Renaming an object (Texture2D /Game/MyAssets/Textures/turret4Diffuse.Texture2D_8) on top of an existing object (Texture2D /Game/MyAssets/Textures/turret4Diffuse.turret_4DiffuseTex2D) is not allowed

I would love to know what’s going on and how to set the name and path properly. Does the package need the path, or the inner object?

Also, if I add “Package” to the end of my package name then try to rename the texture (without “Package”) I get:

Renaming an object (Texture2D /Game/MyAssets/Textures/turret4DiffusePackage.Texture2D_8) on top of an existing object (Texture2D /Game/MyAssets/Textures/turret4DiffusePackage.turret_4Diffuse) is not allowed

So the last part of the path before the period is the package name, and the part after is the asset display name. Why can’t I rename the asset?

Should I be saving this as one texture per package, or packaging multiple related textures together?

UE4 uses only one asset per package, and the asset must be named the same as the package. So you would create the Package at “/Game/MyAssets/Textures/turret4Diffuse” and then create the texture object naming it “turret4Diffuse” and passing the UPackage* as it’s outer object. Then you want to notify the asset registry of your new texture asset using FAssetRegistryModule::AssetCreated() and passing the texture object, then mark it dirty using the Package->SetDirtyFlag(true). Now you have a texture asset at “/Game/MyAssets/Textures/turret4Diffuse.turret4Diffuse”, which you can see in the content browser. You might also want to call PreEditChange and PostEditChange on the texture object while modifying it to get it to update in the content browser.

The way I do it is use a factory to create my asset although it’s not entirely necessary for all asset types, it sets up some default data properly. In your case you’d want to NewObject() a UTexture2dFactoryNew and make the texture object by calling FactoryCreateNew() on it. It works basically the same as NewObject, just with extra initialization based on the asset type.

Ah, thank you! That’s the answer I was looking for. I have definitely left a couple of those steps out.

Yeah, that’s how I’m making the texture, then writing to the source and rebuilding the platform data.