Spawning And Modifying Objects (Python) (Legacy)

A python snippet for editing assets, including spawning new instances of subobjects.

Updated over 3 years ago Edit Page Revisions

Python snippet: editing assets.

import unreal, sys, six, json, re, os
from enum import Enum, auto
from collections import defaultdict, namedtuple

# To Run: Open the Unreal editor.
# Open the Output Log (Window -> Developer Tools -> Output Log)
# enter the command "py <file path>".  So like "py C:/PythonScripts/SampleUnrealPythonScript.py"
# Make sure you use forward slashes.

def convert_area_attack_on_monster_template(InputMonsterTemplate):
  if InputMonsterTemplate is None:
    return

  print (InputMonsterTemplate.get_name())

  uniqueEntryID = 0
  didSomething = False
  assetNameBase = "NewAttackArea"
  ListOfAttacks = list(InputMonsterTemplate.get_editor_property('AttackList')) 
  #NOTE: due to editory bug we have to copy the TArray to a list, edit it, then set it back to the original object explicitly.

  for IteratedAttack in ListOfAttacks:
    if IteratedAttack.get_editor_property("AreaEffect") is not None:
      #ignore entries that are already converted
      print ("Skipping attack that already has an area")
      continue

    OldAttackArea = IteratedAttack.get_editor_property("MyOldAreaVariable")

    if OldAttackArea is None:
      print ("No attack area picked")
      continue;

    if OldAttackArea.get_class() == unreal.OldAttackArea_BreathWeapon.static_class():
      OldAngle = OldAttackArea.get_editor_property("Angle")
      if len(OldAngle) > 0:
        packagePath = IteratedAttack.get_path_name()
        print (packagePath)
        newObjectName = assetNameBase + str(uniqueEntryID)
        uniqueEntryID += 1
        newAreaInstance = unreal.AttackArea_Cone(IteratedAttack, newObjectName);
        newAreaInstance.modify(True)
        newScheduleInstance.set_editor_property("ConeWidth", OldAngle)
        IteratdAttack.set_editor_property("NewAreaVariable", newScheduleInstance)
        didSomething = True

  if didSomething:
    InputMonsterTemplate.modify(True)
    # Save the edited list/TArray.
    InputMonsterTemplate.set_editor_property('Attacks', ListOfAttacks)
    print ("Saving new area edits")
  else:
    print ("No changes")

print("Starting")

# choose selected assets

selectedAssets = unreal.EditorUtilityLibrary.get_selected_assets()

#if you want all assets of a type in the project:
# asset_reg = unreal.AssetRegistryHelpers.get_asset_registry()
# for asset in asset_reg.get_assets_by_class('MonsterTemplate', True):
# IteratedMonster = unreal.AssetRegistryHelpers.get_asset(asset)

if len(selectedAssets) > 0:
  for asset in selectedAssets:
    if asset.get_class() is unreal.MonsterTemplate.static_class():
      convert_area_attack_on_monster_template(asset)
      print("Done")
    else:
      print("No assets selected")

#Creating a new top-level asset:
#AssetTools = unreal.AssetToolsHelpers.get_asset_tools()
#newMonsterClass = unreal.MonsterTemplate.static_class()
#factory = unreal.BlueprintFactory  # <-- There are dozens of prepared factories.  Check the documentation index.  If picking a UObject, set it to none.
# packagePath = "/Game/Blueprints/MonsterFolder"
#newMonsterInstance = AssetTools.create_asset(newObjectName, packagePath, newMonsterClass, factory)