TRASH_StaticMeshComponent interfering with loop

Hi!

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

Thank you in advance!

Bump!

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 :confused:

Also a bump, this is happening with a component for me as well and it seems somewhat random.

UPDATE

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.

1 Like

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 :wink:

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

 def isBluprintActor(self,actor):
        asset_class = actor.get_class().get_class()
        class_name = self.system_lib.get_class_display_name(asset_class)
        if class_name == 'BlueprintGeneratedClass':
            return True
        else:
            return False

hope it’s help :slight_smile:

1 Like

Thankyou guys for posting this info - really helpful, there’s no other source of info anywhere else!