1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
import unreal as unreal; ue = unreal import subprocess as subprocess import os as os
try: import typing except Exception as E: print(E)
def DoWinCopy(inCopy:str) : """Copy to windows clipboard""" subprocess.run(['clip.exe'], input=str(inCopy).strip().encode('utf-16'), check=True)
class SelectionHelper (object) : """Help to get current Selection @ World and @ Content""" __projectContentPath = unreal.Paths.project_content_dir() @classmethod def GetSelectedAssets (cls) : return unreal.EditorUtilityLibrary.get_selected_assets()
@classmethod def GetSelectedActors (cls) : return unreal.EditorLevelLibrary.get_selected_level_actors()
@classmethod def GetFullPathByObject (cls, inUObject: ue.Object) -> str : return unreal.SystemLibrary.get_path_name(inUObject)
@classmethod def ConvertPackagePathToFilePath (cls, inPackagePath: str) -> str : """Convert '/Game/StarterContent/SomeName' to 'Drive:/Project/Content/StarterContent/SomeName'""" fileSysPath = os.path.join(cls.__projectContentPath,inPackagePath.replace("/Game/","")) return fileSysPath
@classmethod def ConvertFilePathToPackagePath (cls, inFilePath: str) -> str : """Convert 'Drive:/Project/Content/StarterContent/SomeName(.uasset)' to '/Game/StarterContent/SomeName'""" return inFilePath.replace("\\","/").replace(".uasset","").replace(cls.__projectContentPath,"/Game/")
class ReferenceHelper (object): __assetRegistryInstance: ue.AssetRegistry = unreal.AssetRegistryHelpers.get_asset_registry() __referenceOptions = unreal.AssetRegistryDependencyOptions() __referenceOptions.include_hard_management_references = True __referenceOptions.include_hard_package_references = True __referenceOptions.include_soft_management_references = True __referenceOptions.include_soft_package_references = True
@classmethod def GetReferencersPathByPackagePath (cls, inPackagePath: str) : """Ref to https://docs.unrealengine.com/4.27/en-US/PythonAPI/class/AssetRegistry.html""" allReferencersPackage : list[str] = cls.__assetRegistryInstance.get_referencers(inPackagePath,cls.__referenceOptions) return allReferencersPackage
@classmethod def GetDependenciesPathByPackagePath (cls, inPackagePath: str) : """Ref to https://docs.unrealengine.com/4.27/en-US/PythonAPI/class/AssetRegistry.html""" allDependenciesPackage : list[str] = cls.__assetRegistryInstance.get_dependencies(inPackagePath,cls.__referenceOptions) return allDependenciesPackage
@classmethod def GetAllReferencersPathFromSelectedAssets (cls) : """Get all referenced assets path with current selection in AssetContent""" assets = SelectionHelper.GetSelectedAssets() assetPaths: set[str] = set() for asset in assets: path = unreal.Paths.get_base_filename(asset.get_path_name(),remove_path=False) assetPaths.add(path) referencedPaths: list[str] = unreal.EditorAssetLibrary.find_package_referencers_for_asset(path) assetPaths.update(referencedPaths) return assetPaths
@classmethod def GetAllDependenciesPath (cls, assetArray , bDeep=False, maxDeep = 10) : """Get all referenced assets path with input array of assets object""" assetsPath: set[str] = set()
MakeValidPath: typing.Callable[[list[str]], typing.Iterable[str]] = \ lambda inPaths : \ (str(name) if not (str(name).startswith("/Script/") or str(name).startswith("/Engine/")) else None \ for name in inPaths) def DeepLoop (inAssets: str, deepCount=0): """recursion to find all paths""" if deepCount > maxDeep: return deepCount+=1 insideAssetsPath:set[str] = set() insideDependenciesPath: list[str] = cls.GetDependenciesPathByPackagePath(inAssets) insideAssetsPath.update(MakeValidPath (insideDependenciesPath)) insideAssetsPath.add(inAssets) insideAssetsPath.discard(None)
for diffAssetsPath in insideAssetsPath: if not diffAssetsPath in assetsPath: assetsPath.add(diffAssetsPath) DeepLoop(diffAssetsPath,deepCount) assetsPath.update(insideAssetsPath) for asset in assetArray: path = unreal.Paths.get_base_filename(asset.get_path_name(),remove_path=False) DependenciesPath: list[str] = cls.GetDependenciesPathByPackagePath(path) if isinstance(DependenciesPath, type(None)): continue assetsPath.update(MakeValidPath(DependenciesPath)) assetsPath.add(path) assetsPath.discard(None) if bDeep: for subAsset in assetsPath.copy(): DeepLoop(subAsset)
return assetsPath
@classmethod def GetAllDependenciesPathFromSelectedAssets (cls, bDeep=False, maxDeep = 10) : """Get all referenced assets path with current selection in AssetContent""" assets = SelectionHelper.GetSelectedAssets() return cls.GetAllDependenciesPath(assets, bDeep, maxDeep)
@classmethod def GetAllDependenciesPathFromSelectedMeshActors (cls, bDeep=False, maxDeep = 10) : """Get all referenced assets path with current selection in AssetContent"""
assets: set[ue.Object] = set() allActors = SelectionHelper.GetSelectedActors() for actor in allActors: staticMeshComponents: list[ue.StaticMeshComponent] = actor.get_components_by_class(ue.StaticMeshComponent) skeletalMeshComponents: list[ue.SkeletalMeshComponent] = actor.get_components_by_class(ue.SkeletalMeshComponent) if len(staticMeshComponents) > 0: for comp in staticMeshComponents: assets.add(comp.static_mesh) if len(skeletalMeshComponents) >0 : for comp in skeletalMeshComponents: assets.add(comp.skeletal_mesh)
return cls.GetAllDependenciesPath(assets, bDeep, maxDeep)
def RunScript(bViewActor=True,bDoCopy=True): """Choose from current ViewportActors or Assets in ContentBrowser""" method = ReferenceHelper.GetAllDependenciesPathFromSelectedMeshActors \ if bViewActor else ReferenceHelper.GetAllDependenciesPathFromSelectedAssets result = list(method(bDeep=True,maxDeep=10));result.sort()
unreal.EditorAssetLibrary.sync_browser_to_objects(result) if bDoCopy: DoWinCopy(result)
if __name__ == "__main__": RunScript(bViewActor=True,bDoCopy=True)
|