I need to change the value “Affect distance field lighting” in StaticMeshComponent inside a Blueprint to optimize our project.
I managed to do it when I get a single index of the mesh array. However, when I use a for loop I change the value of the first 4 ( not always four, sometimes I change only the first or the first two) theTRASH_StaticMeshComponent gets in the loop and I can´t reach the other meshes.
I suppose that Unreal makes a new version of the mesh and the trash version is the one with the old state of the property. But I couldn´t understand how it works.
This is the code the code that I get the error with.
I start the loop at 2 because I don´t need the first two items.
import unreal as ue
selected_actors=ue.EditorLevelLibrary.get_selected_level_actors()
for actor in selected_actors:
children_component=actor.root_component.get_children_components(True)
for component in range(2,len(children_component)):
print children_component[component]
children_component[component].set_editor_property("affect_distance_field_lighting",False)
And this is the log.
The first two got the value changed. But the TRASH_StaticMeshComponent gets in the middle for the others
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.SM_A2e1_A_fachada_06_001' (0x000002D2D289B900) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.SM_A2e1_A_azotea_001' (0x000002D2D289B200) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_36' (0x000002D2BF8E8100) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_35' (0x000002D2BF8E8800) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_34' (0x000002D2BF8EAB00) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_33' (0x000002D2BF8EB200) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_32' (0x000002D2D2897900) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_31' (0x000002D2D2896400) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_30' (0x000002D2AB5B2B00) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_29' (0x000002D2D28B8800) Class 'StaticMeshComponent'>
LogPython: <Object '/Game/Maps/Sub_Levels/Zona_6.Zona_6:PersistentLevel.BP_A2e1_A.TRASH_StaticMeshComponent_28' (0x000002D2D28BB200) Class 'StaticMeshComponent'>
I know that the issue is in the last line of my code. Because when I remove it I get to all the meshes.
I tried to add a delay of a second on the code to see if that compnent got erased after but with no luck. I looked for TRASH_StaticMeshComponent in the Unreal Documentation and the Unreal Python API but I couldn´t find any reference.
I´d like to know what is causing this and how to solve it.
Please let me know if the info is enough to understand the problem
I’m experiencing similar issue where I encounter a SM component as a “TRASH_StaticMeshComponent”. Due to this, I’m not able to edit the editor properties of such components. I’ve no clue why this is happening
Now this is just my case but I have a Blueprint that has 3 components. The Root (SkeletalMesh), Texture Render and then a Plugin class I have. Anytime I call set_editor_property on any of those components, the rest essentially turn into TRASH_. My guess is that after setting a property for some reason this prompts unreal to throw away those references and make them TRASH.
What this allowed me to do was essentially split my logic up and constantly reset my components variable back after setting
def SetAttribute (Component=[],AtrName=''):
for assets in Component:
unreal.log(assets.get_name())
if assets.get_name() == 'NamePlate' and AtrName == 'NamePlate':
owner = assets.get_owner()
name = owner.get_actor_label()
assets.set_editor_property('Text', name)
# break
if assets.get_name() == 'MySkeleton' and AtrName == 'MySkeleton':
ActorPropToSet = assets
owner = assets.get_owner()
name = owner.get_actor_label()
unreal.log(owner)
assets.set_editor_property('Source_Skeleton_Asset_Name', name)
unreal.log(assets.get_name())
# break
def AddActor(actorname, file_path, character, POS=[0,0,0], ROT=[0,0,0]):
SpawnAsset = unreal.EditorAssetLibrary.find_asset_data(file_path + character)
unreal.EditorLevelLibrary.spawn_actor_from_object(SpawnAsset.get_asset(), POS, ROT)
ActorInScene = unreal.EditorLevelLibrary.get_selected_level_actors()
ActorInScene[0].set_folder_path('/Actors')
ActorInScene[0].set_actor_label(actorname)
Comps = ActorInScene[0].get_components_by_class(unreal.ActorComponent)
SetAttribute(Comps,'NamePlate')
Comps = ActorInScene[0].get_components_by_class(unreal.ActorComponent)
SetAttribute(Comps, 'OptitrackSkeleton')
The part where I am getting the components of my actor after setting the attributes is what ended up working for me. Again, seems like after you set a property, Unreal throws away the components and it’s references. For instance, if you were to try and get the owner of the component right after setting the property you will nothing.
Anyway, thought I would share as I imagine others might run into this. Would be great to get some feedback from Epic or anyone that knows more.
Hi,
i have the same issue, i found a workaround
you need to store the path of the meshComponent and on each loop you reload the object
it’s append when i want to update an meshcomponent inside a BluePrint
always when i use set_editor_property all the list is TRASHED
first i loop to save all data
def getSelectedActorData(self):
acorList = []
listActors = self.UUtils.list_selected_actor()
for item in listActors:
# list of actorData
# ActorData contain all information to assign the material
# Label of Actor
# Path = Level path include Blueprint
# type = static or skeletal mesh
# mesh = mesh or Skeletal
#
actorData = {}
asset_class = item.get_class()
#class_name = self.system_lib.get_class_display_name(asset_class)
actor_label = item.get_actor_label()
actorPath = self.getPathActor(item)
actorData['label'] = actor_label
actorData['name'] = item.get_name()
actorData['path'] = actorPath
if (self.isBluprintActor(item)):
# print('------------------BLUE PRINT----------------')
listComp = item.get_components_by_class(unreal.MeshComponent)
for SM_Actor in listComp:
if SM_Actor == None:
continue
typeOk = False
asset_class_bp = SM_Actor.get_class()
class_name_bp = self.system_lib.get_class_display_name(asset_class_bp)
if class_name_bp == 'SkeletalMeshComponent':
# print('---------------------- Skeletal BP--------------')
typeOk = True
actorData['type'] = 'SkeletalMeshComponent'
actorData['mesh'] = SM_Actor.get_editor_property("skeletal_mesh")
# print(SM_Actor.get_parent_components())
if class_name_bp == 'StaticMeshComponent':
# print('---------------------- Static mesh BP --------------')
typeOk = True
actorData['type'] = 'StaticMeshComponent'
actorData['mesh'] = SM_Actor.get_editor_property("static_mesh")
# print(SM_Actor.get_materials())
# print(SM_Actor.get_attach_parent())
# We saveData blue print
if typeOk:
if actorData['mesh'] == None:
continue
fileNameImport = actorData['mesh'].get_editor_property("asset_import_data").get_first_filename()
fileNameImport = unreal.Paths.get_base_filename(fileNameImport)
actorData['fileNameImport'] = fileNameImport
actorData['meshComponent'] = SM_Actor
actorData['meshComponentPath'] = SM_Actor.get_path_name()
actorData['label'] = SM_Actor.get_name()
actorData['name'] = SM_Actor.get_name()
actorData['name'] = actorData['name'].replace('[','')
actorData['name'] = actorData['name'].replace(']','')
actorData['name'] = actorData['name'].replace(':','')
actorData['path'] = unreal.Paths.combine([actorPath, self.getPathBluePrintAsset(SM_Actor)])
actorData['nameAsset'] = actorData['mesh'].get_name()
actorData['pathAsset'] = actorData['mesh'].get_path_name()
# print(actorData['label'])
# print(actorData['path'])
acorList.append(actorData.copy())
else:
SM_Actor = item.get_component_by_class(unreal.MeshComponent)
if SM_Actor == None:
continue
typeOk = False
asset_class_bp = SM_Actor.get_class()
class_name_bp = self.system_lib.get_class_display_name(asset_class_bp)
if class_name_bp == 'SkeletalMeshComponent':
# print('---------------------- Skeletal --------------')
typeOk = True
actorData['type'] = 'SkeletalMeshComponent'
actorData['mesh'] = SM_Actor.get_editor_property("skeletal_mesh")
# print(SM_Actor.get_parent_components())
if class_name_bp == 'StaticMeshComponent':
# print('---------------------- Static mesh --------------')
typeOk = True
actorData['type'] = 'StaticMeshComponent'
actorData['mesh'] = SM_Actor.get_editor_property("static_mesh")
# print(SM_Actor.get_materials())
# print(SM_Actor.get_attach_parent())
# We saveData blue print
if typeOk:
if actorData['mesh'] == None:
continue
fileNameImport = actorData['mesh'].get_editor_property("asset_import_data").get_first_filename()
fileNameImport = unreal.Paths.get_base_filename(fileNameImport)
actorData['name'] = actorData['name'].replace('[', '')
actorData['name'] = actorData['name'].replace(']', '')
actorData['name'] = actorData['name'].replace(':', '')
actorData['meshComponent'] = SM_Actor
actorData['meshComponentPath'] = SM_Actor.get_path_name()
actorData['fileNameImport'] = fileNameImport
actorData['nameAsset'] = actorData['mesh'].get_name()
actorData['pathAsset'] = actorData['mesh'].get_path_name()
acorList.append(actorData.copy())
return acorList
after on my program i reload on each loop my actor
#TO AVOID TRASH component we reload the component on each loop
actor = unreal.AssetRegistryHelpers.get_asset_registry().get_asset_by_object_path(actorData['meshComponentPath']).get_asset()
to detect blueprint i found this maybe is a better way