└── UnrealProject └── UnrealPythonLibrary ├── .gitignore ├── Config ├── DefaultEditor.ini ├── DefaultEngine.ini └── DefaultGame.ini ├── Plugins └── UnrealPythonLibraryPlugin │ ├── Content │ └── Python │ │ ├── AppendPaths.py │ │ ├── PythonLibraries │ │ ├── AssetFunctions.py │ │ ├── EditorFunctions.py │ │ ├── Examples.py │ │ ├── PythonHelpers.py │ │ ├── QtFunctions.py │ │ ├── SequencerFunctions.py │ │ └── WorldFunctions.py │ │ └── QtWindows │ │ ├── QtWindowOne.py │ │ ├── QtWindowOne.ui │ │ ├── QtWindowThree.py │ │ ├── QtWindowThree.ui │ │ ├── QtWindowTwo.py │ │ └── QtWindowTwo.ui │ ├── Resources │ └── Icon128.png │ ├── Source │ └── UnrealPythonLibraryPlugin │ │ ├── Private │ │ ├── CppLib.cpp │ │ ├── UnrealPythonLibraryPlugin.cpp │ │ └── UnrealPythonLibraryPluginBPLibrary.cpp │ │ ├── Public │ │ ├── CppLib.h │ │ ├── UnrealPythonLibraryPlugin.h │ │ └── UnrealPythonLibraryPluginBPLibrary.h │ │ └── UnrealPythonLibraryPlugin.Build.cs │ └── UnrealPythonLibraryPlugin.uplugin └── UnrealPythonLibrary.uproject /UnrealProject/UnrealPythonLibrary/.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2015 user specific files 2 | .vs/ 3 | 4 | # Visual Studio 2015 database file 5 | *.VC.db 6 | 7 | # Compiled Object files 8 | *.slo 9 | *.lo 10 | *.o 11 | *.obj 12 | 13 | # Precompiled Headers 14 | *.gch 15 | *.pch 16 | 17 | # Compiled Dynamic libraries 18 | *.so 19 | *.dylib 20 | *.dll 21 | 22 | # Fortran module files 23 | *.mod 24 | 25 | # Compiled Static libraries 26 | *.lai 27 | *.la 28 | *.a 29 | *.lib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.ipa 36 | 37 | # These project files can be generated by the engine 38 | *.xcodeproj 39 | *.xcworkspace 40 | *.sln 41 | *.suo 42 | *.opensdf 43 | *.sdf 44 | *.VC.db 45 | *.VC.opendb 46 | 47 | # Precompiled Assets 48 | SourceArt/**/*.png 49 | SourceArt/**/*.tga 50 | 51 | # Binary Files 52 | Binaries/* 53 | Plugins/*/Binaries/* 54 | 55 | # Builds 56 | Build/* 57 | 58 | # Whitelist PakBlacklist-.txt files 59 | !Build/*/ 60 | Build/*/** 61 | !Build/*/PakBlacklist*.txt 62 | 63 | # Don't ignore icon files in Build 64 | !Build/**/*.ico 65 | 66 | # Built data for maps 67 | *_BuiltData.uasset 68 | 69 | # Configuration files generated by the Editor 70 | Saved/* 71 | 72 | # Compiled source files for the engine to use 73 | Intermediate/* 74 | Plugins/*/Intermediate/* 75 | 76 | # Cache files for the editor to use 77 | DerivedDataCache/* 78 | 79 | # Python 80 | *.pyc 81 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Config/DefaultEditor.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexQuevillon/UnrealPythonLibrary/d9c2348553aaacbc173e81b1b3ddc977b0bb3c37/UnrealProject/UnrealPythonLibrary/Config/DefaultEditor.ini -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | [URL] 2 | 3 | [/Script/HardwareTargeting.HardwareTargetingSettings] 4 | TargetedHardwareClass=Desktop 5 | AppliedTargetedHardwareClass=Desktop 6 | DefaultGraphicsPerformance=Maximum 7 | AppliedDefaultGraphicsPerformance=Maximum 8 | 9 | [/Script/PythonScriptPlugin.PythonScriptPluginSettings] 10 | +StartupScripts=AppendPaths.py 11 | bDeveloperMode=True 12 | 13 | [/Script/Engine.PhysicsSettings] 14 | DefaultGravityZ=-980.000000 15 | DefaultTerminalVelocity=4000.000000 16 | DefaultFluidFriction=0.300000 17 | SimulateScratchMemorySize=262144 18 | RagdollAggregateThreshold=4 19 | TriangleMeshTriangleMinAreaThreshold=5.000000 20 | bEnableShapeSharing=False 21 | bEnablePCM=True 22 | bEnableStabilization=False 23 | bWarnMissingLocks=True 24 | bEnable2DPhysics=False 25 | PhysicErrorCorrection=(PingExtrapolation=0.100000,PingLimit=100.000000,ErrorPerLinearDifference=1.000000,ErrorPerAngularDifference=1.000000,MaxRestoredStateError=1.000000,MaxLinearHardSnapDistance=400.000000,PositionLerp=0.000000,AngleLerp=0.400000,LinearVelocityCoefficient=100.000000,AngularVelocityCoefficient=10.000000,ErrorAccumulationSeconds=0.500000,ErrorAccumulationDistanceSq=15.000000,ErrorAccumulationSimilarity=100.000000) 26 | LockedAxis=Invalid 27 | DefaultDegreesOfFreedom=Full3D 28 | BounceThresholdVelocity=200.000000 29 | FrictionCombineMode=Average 30 | RestitutionCombineMode=Average 31 | MaxAngularVelocity=3600.000000 32 | MaxDepenetrationVelocity=0.000000 33 | ContactOffsetMultiplier=0.020000 34 | MinContactOffset=2.000000 35 | MaxContactOffset=8.000000 36 | bSimulateSkeletalMeshOnDedicatedServer=True 37 | DefaultShapeComplexity=CTF_UseSimpleAndComplex 38 | bDefaultHasComplexCollision=True 39 | bSuppressFaceRemapTable=False 40 | bSupportUVFromHitResults=False 41 | bDisableActiveActors=False 42 | bDisableKinematicStaticPairs=False 43 | bDisableKinematicKinematicPairs=False 44 | bDisableCCD=False 45 | bEnableEnhancedDeterminism=False 46 | MaxPhysicsDeltaTime=0.033333 47 | bSubstepping=False 48 | bSubsteppingAsync=False 49 | MaxSubstepDeltaTime=0.016667 50 | MaxSubsteps=6 51 | SyncSceneSmoothingFactor=0.000000 52 | InitialAverageFrameRate=0.016667 53 | PhysXTreeRebuildRate=10 54 | DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,MBPBounds=(Min=(X=0.000000,Y=0.000000,Z=0.000000),Max=(X=0.000000,Y=0.000000,Z=0.000000),IsValid=0),MBPNumSubdivs=2) 55 | 56 | 57 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Config/DefaultGame.ini: -------------------------------------------------------------------------------- 1 | [/Script/EngineSettings.GeneralProjectSettings] 2 | ProjectID=D423854546D458628D430EA862A2F2DB 3 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/AppendPaths.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'PythonLibraries')) 4 | sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'QtWindows')) -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/PythonLibraries/AssetFunctions.py: -------------------------------------------------------------------------------- 1 | # unreal.AssetToolsHelpers 2 | # https://api.unrealengine.com/INT/PythonAPI/class/AssetToolsHelpers.html 3 | 4 | # unreal.AssetTools 5 | # https://api.unrealengine.com/INT/PythonAPI/class/AssetTools.html 6 | 7 | # unreal.EditorAssetLibrary 8 | # https://api.unrealengine.com/INT/PythonAPI/class/EditorAssetLibrary.html 9 | # All operations can be slow. The editor should not be in play in editor mode. It will not work on assets of the type level. 10 | # Possible Directory Paths: 11 | # '/Game/MyFolder' 12 | # '/Game/MyFolder/' 13 | # Possible Asset Paths: 14 | # '/Game/MyFolder/MyAsset.MyAsset' 15 | # '/Game/MyFolder/MyAsset' 16 | 17 | # unreal.AssetRenameData 18 | # https://api.unrealengine.com/INT/PythonAPI/class/AssetRenameData.html 19 | 20 | # unreal.Package 21 | # https://api.unrealengine.com/INT/PythonAPI/class/Package.html 22 | 23 | # unreal.EditorLoadingAndSavingUtils 24 | # https://api.unrealengine.com/INT/PythonAPI/class/EditorLoadingAndSavingUtils.html 25 | 26 | # unreal.AssetImportTask 27 | # https://api.unrealengine.com/INT/PythonAPI/class/AssetImportTask.html 28 | 29 | # unreal.AssetTools 30 | # https://api.unrealengine.com/INT/PythonAPI/class/AssetTools.html 31 | 32 | # unreal.FbxImportUI 33 | # https://api.unrealengine.com/INT/PythonAPI/class/FbxImportUI.html 34 | 35 | # unreal.FbxMeshImportData 36 | # https://api.unrealengine.com/INT/PythonAPI/class/FbxMeshImportData.html 37 | 38 | # unreal.FbxStaticMeshImportData 39 | # https://api.unrealengine.com/INT/PythonAPI/class/FbxStaticMeshImportData.html 40 | 41 | # unreal.FbxSkeletalMeshImportData 42 | # https://api.unrealengine.com/INT/PythonAPI/class/FbxSkeletalMeshImportData.html 43 | 44 | # unreal.FbxAssetImportData 45 | # https://api.unrealengine.com/INT/PythonAPI/class/FbxAssetImportData.html 46 | 47 | # unreal.FbxAnimSequenceImportData 48 | # https://api.unrealengine.com/INT/PythonAPI/class/FbxAnimSequenceImportData.html 49 | 50 | # unreal.FBXAnimationLengthImportType 51 | # https://api.unrealengine.com/INT/PythonAPI/class/FBXAnimationLengthImportType.html 52 | 53 | # unreal.LinearColor 54 | # https://api.unrealengine.com/INT/PythonAPI/class/LinearColor.html 55 | 56 | # unreal.Factory 57 | # https://api.unrealengine.com/INT/PythonAPI/class/Factory.html 58 | 59 | import unreal 60 | 61 | # asset_path: str : Path of asset to create 62 | # unique_name: bool : If True, will add a number at the end of the asset name until unique 63 | # asset_class: obj unreal.Class : The asset class 64 | # asset_factory: obj unreal.Factory : The associated factory of the class. 65 | # return: obj : The created asset 66 | def createGenericAsset(asset_path='', unique_name=True, asset_class=None, asset_factory=None): 67 | if unique_name: 68 | asset_path, asset_name = unreal.AssetToolsHelpers.get_asset_tools().create_unique_asset_name(base_package_name=asset_path, suffix='') 69 | if not unreal.EditorAssetLibrary.does_asset_exist(asset_path=asset_path): 70 | path = asset_path.rsplit('/', 1)[0] 71 | name = asset_path.rsplit('/', 1)[1] 72 | return unreal.AssetToolsHelpers.get_asset_tools().create_asset(asset_name=name, package_path=path, asset_class=asset_class, factory=asset_factory) 73 | return unreal.load_asset(asset_path) 74 | 75 | 76 | # paths: List of str : Asset paths 77 | def showAssetsInContentBrowser(paths=[]): 78 | unreal.EditorAssetLibrary.sync_browser_to_objects(asset_paths=paths) 79 | 80 | 81 | # paths: List of str : Asset paths 82 | def openAssets(paths=[]): 83 | loaded_assets = [getPackageFromPath(x) for x in paths] 84 | unreal.AssetToolsHelpers.get_asset_tools().open_editor_for_assets(assets=loaded_assets) 85 | 86 | 87 | # path: str : Directory path 88 | # return: bool : True if the operation succeeds 89 | def createDirectory(path=''): 90 | return unreal.EditorAssetLibrary.make_directory(directory_path=path) 91 | 92 | 93 | # from_dir: str : Directory path to duplicate 94 | # to_dir: str : Duplicated directory path 95 | # return: bool : True if the operation succeeds 96 | def duplicateDirectory(from_dir='', to_dir=''): 97 | return unreal.EditorAssetLibrary.duplicate_directory(source_directory_path=from_dir, destination_directory_path=to_dir) 98 | 99 | 100 | # path: str : Directory path 101 | # return: bool : True if the operation succeeds 102 | def deleteDirectory(path=''): 103 | return unreal.EditorAssetLibrary.delete_directory(directory_path=path) 104 | 105 | 106 | # path: str : Directory path 107 | # return: bool : True if the directory exists 108 | def directoryExist(path=''): 109 | return unreal.EditorAssetLibrary.does_directory_exist(directory_path=path) 110 | 111 | 112 | # from_dir: str : Directory path to rename 113 | # to_dir: str : Renamed directory path 114 | # return: bool : True if the operation succeeds 115 | def renameDirectory(from_dir='', to_dir=''): 116 | return unreal.EditorAssetLibrary.rename_directory(source_directory_path=from_dir, destination_directory_path=to_dir) 117 | 118 | 119 | # from_path str : Asset path to duplicate 120 | # to_path: str : Duplicated asset path 121 | # return: bool : True if the operation succeeds 122 | def duplicateAsset(from_path='', to_path=''): 123 | return unreal.EditorAssetLibrary.duplicate_asset(source_asset_path=from_path, destination_asset_path=to_path) 124 | 125 | 126 | # path: str : Asset path 127 | # return: bool : True if the operation succeeds 128 | def deleteAsset(path=''): 129 | return unreal.EditorAssetLibrary.delete_asset(asset_path_to_delete=path) 130 | 131 | 132 | # path: str : Asset path 133 | # return: bool : True if the asset exists 134 | def assetExist(path=''): 135 | return unreal.EditorAssetLibrary.does_asset_exist(asset_path=path) 136 | 137 | 138 | # from_path: str : Asset path to rename 139 | # to_path: str : Renamed asset path 140 | # return: bool : True if the operation succeeds 141 | def renameAsset(from_path='', to_path=''): 142 | return unreal.EditorAssetLibrary.rename_asset(source_asset_path=from_path, destination_asset_path=to_path) 143 | 144 | 145 | # Note: This function will also work on assets of the type level. (But might be really slow if the level is huge) 146 | # from_path: str : Asset path to duplicate 147 | # to_path: str : Duplicate asset path 148 | # show_dialog: bool : True if you want to show the confirm pop-up 149 | # return: bool : True if the operation succeeds 150 | def duplicateAssetDialog(from_path='', to_path='', show_dialog=True): 151 | splitted_path = to_path.rsplit('/', 1) 152 | asset_path = splitted_path[0] 153 | asset_name = splitted_path[1] 154 | if show_dialog: 155 | return unreal.AssetToolsHelpers.get_asset_tools().duplicate_asset_with_dialog(asset_name=asset_name, package_path=asset_path, original_object=getPackageFromPath(from_path)) 156 | else: 157 | return unreal.duplicate_asset.get_asset_tools().duplicate_asset(asset_name=asset_name, package_path=asset_path, original_object=getPackageFromPath(from_path)) 158 | 159 | 160 | # Note: This function will also work on assets of the type level. (But might be really slow if the level is huge) 161 | # from_path: str : Asset path to rename 162 | # to_path: str : Renamed asset path 163 | # show_dialog: bool : True if you want to show the confirm pop-up 164 | # return: bool : True if the operation succeeds 165 | def renameAssetDialog(from_path='', to_path='', show_dialog=True): 166 | splitted_path = to_path.rsplit('/', 1) 167 | asset_path = splitted_path[0] 168 | asset_name = splitted_path[1] 169 | rename_data = unreal.AssetRenameData(asset=getPackageFromPath(from_path), new_package_path=asset_path, new_name=asset_name) 170 | if show_dialog: 171 | return unreal.AssetToolsHelpers.get_asset_tools().rename_assets_with_dialog(assets_and_names=[rename_data]) 172 | else: 173 | return unreal.AssetToolsHelpers.get_asset_tools().rename_assets(assets_and_names=[rename_data]) 174 | 175 | 176 | # path: str : Asset path 177 | # return: bool : True if the operation succeeds 178 | def saveAsset(path='', force_save=True): 179 | return unreal.EditorAssetLibrary.save_asset(asset_to_save=path, only_if_is_dirty = not force_save) 180 | 181 | 182 | # path: str : Directory path 183 | # return: bool : True if the operation succeeds 184 | def saveDirectory(path='', force_save=True, recursive=True): 185 | return unreal.EditorAssetLibrary.save_directory(directory_path=path, only_if_is_dirty=not force_save, recursive=recursive) 186 | 187 | 188 | # path: str : Asset path 189 | # return: obj : The loaded asset 190 | def getPackageFromPath(path): 191 | return unreal.load_package(name=path) 192 | 193 | 194 | # return: obj List : The assets that need to be saved 195 | def getAllDirtyPackages(): 196 | packages = [] 197 | for x in unreal.EditorLoadingAndSavingUtils.get_dirty_content_packages(): 198 | packages.append(x) 199 | for x in unreal.EditorLoadingAndSavingUtils.get_dirty_map_packages(): 200 | packages.append(x) 201 | return packages 202 | 203 | 204 | # show_dialog: bool : True if you want to see the confirm pop-up 205 | # return: bool : True if the operation succeeds 206 | def saveAllDirtyPackages(show_dialog=False): 207 | if show_dialog: 208 | return unreal.EditorLoadingAndSavingUtils.save_dirty_packages_with_dialog(save_map_packages=True, save_content_packages=True) 209 | else: 210 | return unreal.EditorLoadingAndSavingUtils.save_dirty_packages(save_map_packages=True, save_content_packages=True) 211 | 212 | 213 | # show_dialog: bool : True if you want to see the confirm pop-up 214 | # return: bool : True if the operation succeeds 215 | def savePackages(packages=[], show_dialog=False): 216 | if show_dialog: 217 | return unreal.EditorLoadingAndSavingUtils.save_packages_with_dialog(packages_to_save=packages, only_dirty=False) # only_dirty=False : 218 | else: # looks like that it's not 219 | return unreal.EditorLoadingAndSavingUtils.save_packages(packages_to_save=packages, only_dirty=False) # working properly at the moment 220 | 221 | 222 | # filename: str : Windows file fullname of the asset you want to import 223 | # destination_path: str : Asset path 224 | # option: obj : Import option object. Can be None for assets that does not usually have a pop-up when importing. (e.g. Sound, Texture, etc.) 225 | # return: obj : The import task object 226 | def buildImportTask(filename='', destination_path='', options=None): 227 | task = unreal.AssetImportTask() 228 | task.set_editor_property('automated', True) 229 | task.set_editor_property('destination_name', '') 230 | task.set_editor_property('destination_path', destination_path) 231 | task.set_editor_property('filename', filename) 232 | task.set_editor_property('replace_existing', True) 233 | task.set_editor_property('save', True) 234 | task.set_editor_property('options', options) 235 | return task 236 | 237 | 238 | # tasks: obj List : The import tasks object. You can get them from buildImportTask() 239 | # return: str List : The paths of successfully imported assets 240 | def executeImportTasks(tasks=[]): 241 | unreal.AssetToolsHelpers.get_asset_tools().import_asset_tasks(tasks) 242 | imported_asset_paths = [] 243 | for task in tasks: 244 | for path in task.get_editor_property('imported_object_paths'): 245 | imported_asset_paths.append(path) 246 | return imported_asset_paths 247 | 248 | 249 | # return: obj : Import option object. The basic import options for importing a static mesh 250 | def buildStaticMeshImportOptions(): 251 | options = unreal.FbxImportUI() 252 | # unreal.FbxImportUI 253 | options.set_editor_property('import_mesh', True) 254 | options.set_editor_property('import_textures', False) 255 | options.set_editor_property('import_materials', False) 256 | options.set_editor_property('import_as_skeletal', False) # Static Mesh 257 | # unreal.FbxMeshImportData 258 | options.static_mesh_import_data.set_editor_property('import_translation', unreal.Vector(0.0, 0.0, 0.0)) 259 | options.static_mesh_import_data.set_editor_property('import_rotation', unreal.Rotator(0.0, 0.0, 0.0)) 260 | options.static_mesh_import_data.set_editor_property('import_uniform_scale', 1.0) 261 | # unreal.FbxStaticMeshImportData 262 | options.static_mesh_import_data.set_editor_property('combine_meshes', True) 263 | options.static_mesh_import_data.set_editor_property('generate_lightmap_u_vs', True) 264 | options.static_mesh_import_data.set_editor_property('auto_generate_collision', True) 265 | return options 266 | 267 | 268 | # return: obj : Import option object. The basic import options for importing a skeletal mesh 269 | def buildSkeletalMeshImportOptions(): 270 | options = unreal.FbxImportUI() 271 | # unreal.FbxImportUI 272 | options.set_editor_property('import_mesh', True) 273 | options.set_editor_property('import_textures', True) 274 | options.set_editor_property('import_materials', True) 275 | options.set_editor_property('import_as_skeletal', True) # Skeletal Mesh 276 | # unreal.FbxMeshImportData 277 | options.skeletal_mesh_import_data.set_editor_property('import_translation', unreal.Vector(0.0, 0.0, 0.0)) 278 | options.skeletal_mesh_import_data.set_editor_property('import_rotation', unreal.Rotator(0.0, 0.0, 0.0)) 279 | options.skeletal_mesh_import_data.set_editor_property('import_uniform_scale', 1.0) 280 | # unreal.FbxSkeletalMeshImportData 281 | options.skeletal_mesh_import_data.set_editor_property('import_morph_targets', True) 282 | options.skeletal_mesh_import_data.set_editor_property('update_skeleton_reference_pose', False) 283 | return options 284 | 285 | 286 | # skeleton_path: str : Skeleton asset path of the skeleton that will be used to bind the animation 287 | # return: obj : Import option object. The basic import options for importing an animation 288 | def buildAnimationImportOptions(skeleton_path=''): 289 | options = unreal.FbxImportUI() 290 | # unreal.FbxImportUI 291 | options.set_editor_property('import_animations', True) 292 | options.skeleton = unreal.load_asset(skeleton_path) 293 | # unreal.FbxMeshImportData 294 | options.anim_sequence_import_data.set_editor_property('import_translation', unreal.Vector(0.0, 0.0, 0.0)) 295 | options.anim_sequence_import_data.set_editor_property('import_rotation', unreal.Rotator(0.0, 0.0, 0.0)) 296 | options.anim_sequence_import_data.set_editor_property('import_uniform_scale', 1.0) 297 | # unreal.FbxAnimSequenceImportData 298 | options.anim_sequence_import_data.set_editor_property('animation_length', unreal.FBXAnimationLengthImportType.FBXALIT_EXPORTED_TIME) 299 | options.anim_sequence_import_data.set_editor_property('remove_redundant_keys', False) 300 | return options 301 | 302 | 303 | 304 | 305 | # Cpp ######################################################################################################################################################################################## 306 | 307 | 308 | 309 | 310 | # return: str List : The asset paths that are currently selected 311 | def getSelectedAssets(): 312 | return unreal.CppLib.get_selected_assets() 313 | 314 | 315 | # asset_paths: str List : The asset paths to select 316 | def setSelectedAssets(asset_paths=[]): 317 | unreal.CppLib.set_selected_assets(asset_paths) 318 | 319 | 320 | # return: str List : The folder paths that are currently selected 321 | def getSelectedFolders(): 322 | return unreal.CppLib.get_selected_folders() 323 | 324 | 325 | # folder_paths: str List : The asset paths to select 326 | def setSelectedFolders(folder_paths=[]): 327 | unreal.CppLib.set_selected_folders(folder_paths) 328 | 329 | 330 | # return: obj List : The asset objects that are currently opened in the editor 331 | def getAllOpenedAssets(): 332 | return unreal.CppLib.get_assets_opened_in_editor() 333 | 334 | 335 | # asset_objects: obj List : The asset objects to close 336 | def closeAssets(asset_objects=[]): 337 | unreal.CppLib.close_editor_for_assets(asset_objects) 338 | 339 | 340 | # Note: If the directory already exists, might need to restart Unreal, 341 | # but it's not needed if the color is applied before creating the folder. 342 | # path: str : Directory path 343 | # color: obj unreal.LinearColor : The color to apply 344 | def setDirectoryColor(path='', color=None): 345 | unreal.CppLib.set_folder_color(path, color) 346 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/PythonLibraries/EditorFunctions.py: -------------------------------------------------------------------------------- 1 | # unreal.SystemLibrary 2 | # https://api.unrealengine.com/INT/PythonAPI/class/SystemLibrary.html 3 | 4 | import unreal 5 | import random 6 | 7 | 8 | # active_viewport_only: bool : If True, will only affect the active viewport 9 | # actor: obj unreal.Actor : The actor you want to snap to 10 | def focusViewportOnActor(active_viewport_only=True, actor=None): 11 | command = 'CAMERA ALIGN' 12 | if active_viewport_only: 13 | command += ' ACTIVEVIEWPORTONLY' 14 | if actor: 15 | command += ' NAME=' + actor.get_name() 16 | executeConsoleCommand(command) 17 | 18 | 19 | 20 | 21 | # Cpp ######################################################################################################################################################################################## 22 | 23 | 24 | 25 | 26 | # Note: This is the real Python function but it does not work in editor : unreal.SystemLibrary.execute_console_command(unreal.EditorLevelLibrary.get_editor_world(), 'stat unit') 27 | # console_command: str : The console command 28 | def executeConsoleCommand(console_command=''): 29 | unreal.CppLib.execute_console_command(console_command) 30 | 31 | 32 | # return: int : The index of the active viewport 33 | def getActiveViewportIndex(): 34 | return unreal.CppLib.get_active_viewport_index() 35 | 36 | # viewport_index: int : The index of the viewport you want to affect 37 | # location: obj unreal.Vector : The viewport location 38 | # rotation: obj unreal.Rotator : The viewport rotation 39 | def setViewportLocationAndRotation(viewport_index=1, location=unreal.Vector(), rotation=unreal.Rotator()): 40 | unreal.CppLib.set_viewport_location_and_rotation(viewport_index, location, rotation) 41 | 42 | # viewport_index: int : The index of the viewport you want to affect 43 | # actor: obj unreal.Actor : The actor you want to snap to 44 | def snapViewportToActor(viewport_index=1, actor=None): 45 | setViewportLocationAndRotation(viewport_index, actor.get_actor_location(), actor.get_actor_rotation()) 46 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/PythonLibraries/Examples.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import AssetFunctions 3 | import EditorFunctions 4 | import PythonHelpers 5 | import QtFunctions 6 | import WorldFunctions 7 | 8 | 9 | 10 | def showAssetsInContentBrowser_EXAMPLE(): 11 | paths = ['/Game/Textures/MyTexture', '/Game/SkeletalMeshes/MySkeletalMesh', '/Game/Sounds/MySound'] 12 | AssetFunctions.showAssetsInContentBrowser(paths) 13 | 14 | def openAssets_EXAMPLE(): 15 | paths = ['/Game/Textures/MyTexture', '/Game/SkeletalMeshes/MySkeletalMesh', '/Game/Sounds/MySound'] 16 | AssetFunctions.openAssets(paths) 17 | 18 | def createDirectory_EXAMPLE(): 19 | operation_succeeded = AssetFunctions.createDirectory('/Game/MyDirectory') 20 | print operation_succeeded 21 | 22 | def duplicateDirectory_EXAMPLE(): 23 | operation_succeeded = AssetFunctions.duplicateDirectory('/Game/MyDirectory', '/Game/MyDirectory_Duplicated') 24 | print operation_succeeded 25 | 26 | def deleteDirectory_EXAMPLE(): 27 | operation_succeeded = AssetFunctions.deleteDirectory('/Game/MyDirectory') 28 | print operation_succeeded 29 | 30 | def directoryExist_EXAMPLE(): 31 | exist = AssetFunctions.directoryExist('/Game/MyDirectory') 32 | print exist 33 | 34 | def renameDirectory_EXAMPLE(): 35 | operation_succeeded = AssetFunctions.renameDirectory('/Game/MyDirectory', '/Game/MyDirectory_Renamed') 36 | print operation_succeeded 37 | 38 | def duplicateAsset_EXAMPLE(): 39 | operation_succeeded = AssetFunctions.duplicateAsset('/Game/MyAsset', '/Game/MyAsset_Duplicated') 40 | print operation_succeeded 41 | 42 | def deleteAsset_EXAMPLE(): 43 | operation_succeeded = AssetFunctions.deleteAsset('/Game/MyAsset') 44 | print operation_succeeded 45 | 46 | def assetExist_EXAMPLE(): 47 | exist = AssetFunctions.assetExist('/Game/MyAsset') 48 | print exist 49 | 50 | def renameAsset_EXAMPLE(): 51 | operation_succeeded = AssetFunctions.renameAsset('/Game/MyAsset', '/Game/MyAsset_Renamed') 52 | print operation_succeeded 53 | 54 | def duplicateAssetDialog_EXAMPLE(): 55 | operation_succeeded = AssetFunctions.duplicateAssetDialog('/Game/MyAsset', '/Game/MyAsset_Duplicated', True) 56 | print operation_succeeded 57 | 58 | def renameAssetDialog_EXAMPLE(): 59 | operation_succeeded = AssetFunctions.duplicateAssetDialog('/Game/MyAsset', '/Game/MyAsset_Renamed', True) 60 | print operation_succeeded 61 | 62 | def saveAsset_EXAMPLE(): 63 | operation_succeeded = AssetFunctions.saveAsset('/Game/MyAsset', True) 64 | print operation_succeeded 65 | 66 | def saveDirectory_EXAMPLE(): 67 | operation_succeeded = AssetFunctions.saveDirectory('/Game/MyDirectory', True, True) 68 | print operation_succeeded 69 | 70 | def importMyAssets_EXAMPLE(): 71 | texture_task = AssetFunctions.buildImportTask('C:/Path/To/Assets/Texture.TGA', '/Game/Textures') 72 | sound_task = AssetFunctions.buildImportTask('C:/Path/To/Assets/Sound.WAV', '/Game/Sounds') 73 | static_mesh_task = AssetFunctions.buildImportTask('C:/Path/To/Assets/StaticMesh.FBX', '/Game/StaticMeshes', AssetFunctions.buildStaticMeshImportOptions()) 74 | skeletal_mesh_task = AssetFunctions.buildImportTask('C:/Path/To/Assets/SkeletalMesh.FBX', '/Game/SkeletalMeshes', AssetFunctions.buildSkeletalMeshImportOptions()) 75 | animation_task = AssetFunctions.buildImportTask('C:/Path/To/Assets/Animation.FBX', '/Game/Animations', AssetFunctions.buildAnimationImportOptions('/Game/SkeletalMeshes/SkeletalMesh')) 76 | print AssetFunctions.executeImportTasks([texture_task, sound_task, static_mesh_task, skeletal_mesh_task]) 77 | # Not executing the animation_task at the same time of the skeletal_mesh_task because it look like it does not work if it's the case. Pretty sure it's not normal. 78 | print AssetFunctions.executeImportTasks([animation_task]) 79 | 80 | def spawnBlueprintActor_EXAMPLE(): 81 | path = '/Game/MyBlueprint' 82 | location = unreal.Vector(1000.0, 400.0, 0.0) 83 | rotation = unreal.Rotator(90.0, 0.0, 0.0) 84 | scale = unreal.Vector(1.0, 1.0, 5.0) 85 | properties = {'tags': ['MyFirstTag', 'MySecondTag'], 'hidden': False} 86 | print WorldFunctions.spawnBlueprintActor(path, location, rotation, scale, None, properties) 87 | 88 | def executeSlowTask_EXAMPLE(): 89 | quantity_steps_in_slow_task = 1000 90 | with unreal.ScopedSlowTask(quantity_steps_in_slow_task, 'My Slow Task Text ...') as slow_task: 91 | slow_task.make_dialog(True) 92 | for x in range(quantity_steps_in_slow_task): 93 | if slow_task.should_cancel_EXAMPLE(): 94 | break 95 | slow_task.enter_progress_frame(1, 'My Slow Task Text ... ' + str(x) + ' / ' + str(quantity_steps_in_slow_task)) 96 | # Execute slow logic here 97 | print 'Executing Slow Task' 98 | 99 | def cast_EXAMPLE(): 100 | obj = unreal.load_asset('/Game/Textures/MyTexture') 101 | if PythonHelpers.cast(obj, unreal.Texture2D): 102 | print 'Cast Succeeded' 103 | else: 104 | print 'Cast Failed' 105 | 106 | def spawnQtWindow_EXAMPLE(): 107 | import QtWindowOne 108 | print QtFunctions.spawnQtWindow(QtWindowOne.QtWindowOne) 109 | 110 | def getAllActors_EXAMPLE(): 111 | print WorldFunctions.getAllActors(False, unreal.StaticMeshActor, 'MyTag', None) 112 | 113 | def getSelectedActors_EXAMPLE(): 114 | print getSelectedActors() 115 | 116 | def selectActors_EXAMPLE(): 117 | all_actors = getAllActors() 118 | actors_to_select = [] 119 | for x in range(len(all_actors)): 120 | if x % 2: 121 | actors_to_select.append(all_actors[x]) 122 | 123 | def clearActorSelection_EXAMPLE(): 124 | selectActors() 125 | 126 | def focusAllViewportsOnSelectedActors_EXAMPLE(): 127 | focusViewportOnActor(False) 128 | 129 | def focusActiveViewportOnRandomActor_EXAMPLE(): 130 | actors_in_world = unreal.GameplayStatics.get_all_actors_of_class(unreal.EditorLevelLibrary.get_editor_world(), unreal.Actor) 131 | random_actor_in_world = actors_in_world[random.randrange(len(actors_in_world))] 132 | focusViewportOnActor(True, random_actor_in_world) 133 | 134 | def createGenericAsset_EXAMPLE(): 135 | base_path = '/Game/GenericAssets/' 136 | generic_assets = [ 137 | [base_path + 'sequence', unreal.LevelSequence, unreal.LevelSequenceFactoryNew()], 138 | [base_path + 'material', unreal.Material, unreal.MaterialFactoryNew()], 139 | [base_path + 'world', unreal.World, unreal.WorldFactory()], 140 | [base_path + 'particle_system', unreal.ParticleSystem, unreal.ParticleSystemFactoryNew()], 141 | [base_path + 'paper_flipbook', unreal.PaperFlipbook, unreal.PaperFlipbookFactory()], 142 | [base_path + 'data_table', unreal.DataTable, unreal.DataTableFactory()], # Will not work 143 | ] 144 | for asset in generic_assets: 145 | print createGenericAsset(asset[0], True, asset[1], asset[2]) 146 | 147 | 148 | 149 | 150 | # Cpp ######################################################################################################################################################################################## 151 | 152 | 153 | 154 | 155 | def getSelectedAssets_EXAMPLE(): 156 | print AssetFunctions.getSelectedAssets() 157 | 158 | def setSelectedAssets_EXAMPLE(): 159 | asset_paths = ['/Game/Textures/TX_LightSpotMove', '/Game/SkeletalMeshes/TutorialTPP_Mat', '/Game/Sounds/S_CompileSuccess', '/Game/Map/MyNewLevel'] 160 | AssetFunctions.setSelectedAssets(asset_paths) 161 | 162 | def getSelectedFolders_EXAMPLE(): 163 | print AssetFunctions.getSelectedFolders() 164 | 165 | def setSelectedFolders_EXAMPLE(): 166 | folder_paths = ['/Game/Textures', '/Game/SkeletalMeshes', '/Game/Sounds', '/Game/Map'] 167 | AssetFunctions.setSelectedFolders(folder_paths) 168 | 169 | def getAllOpenedAssets_EXAMPLE(): 170 | print AssetFunctions.getAllOpenedAssets() 171 | 172 | def closeAssets_EXAMPLE(): 173 | asset_objects = AssetFunctions.getAllOpenedAssets() 174 | AssetFunctions.closeAssets(asset_objects) 175 | 176 | def setDirectoryColor_EXAMPLE(): 177 | base_path = '/Game/PythonGenerated/' 178 | path = base_path + 'BasicLinearColor' 179 | color = unreal.LinearColor(0, 1, 1, 1) 180 | AssetFunctions.setDirectoryColor(path, color) 181 | AssetFunctions.createDirectory(path) # Note: Only call this line if the folder is not already created 182 | 183 | def setDirectoryColorGradient_EXAMPLE(): 184 | base_path = '/Game/PythonGenerated/' 185 | for x in range(100, 400): 186 | # Get Gradient Color 187 | z = x - 100 188 | if z < 100: 189 | r = 1.0 - z / 100.0 190 | g = 0.0 + z / 100.0 191 | b = 0.0 192 | elif z < 200: 193 | r = 0.0 194 | g = 1.0 - (z - 100) / 100.0 195 | b = 0.0 + (z - 100) / 100.0 196 | else: 197 | r = 0.0 + (z - 200) / 100.0 198 | g = 0.0 199 | b = 1.0 - (z - 200) / 100.0 200 | color = unreal.LinearColor(r, g, b, 1) 201 | # Set Directory Color 202 | path = base_path + str(x) 203 | AssetFunctions.setDirectoryColor(path, color) 204 | AssetFunctions.createDirectory(path) # Note: Only call this line if the folder is not already created 205 | 206 | def executeConsoleCommand_EXAMPLE(): 207 | console_commands = ['r.ScreenPercentage 0.1', 'r.Color.Max 6', 'stat fps', 'stat unit'] 208 | for x in console_commands: 209 | EditorFunctions.executeConsoleCommand(x) 210 | 211 | def getAllProperties_EXAMPLE(): 212 | obj = unreal.Actor() 213 | object_class = obj.get_class() 214 | for x in PythonHelpers.getAllProperties(object_class): 215 | y = x 216 | while len(y) < 50: 217 | y = ' ' + y 218 | print y + ' : ' + str(obj.get_editor_property(x)) 219 | 220 | def setViewportLocationAndRotation_EXAMPLE(): 221 | viewport_index = getActiveViewportIndex() 222 | setViewportLocationAndRotation(viewport_index, unreal.Vector(0.0, 0.0, 0.0), unreal.Rotator(0.0, 90.0, 0.0)) 223 | 224 | def snapViewportToActor_EXAMPLE(): 225 | actors_in_world = unreal.GameplayStatics.get_all_actors_of_class(unreal.EditorLevelLibrary.get_editor_world(), unreal.Actor) 226 | random_actor_in_world = actors_in_world[random.randrange(len(actors_in_world))] 227 | viewport_index = getActiveViewportIndex() 228 | snapViewportToActor(viewport_index, random_actor_in_world) 229 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/PythonLibraries/PythonHelpers.py: -------------------------------------------------------------------------------- 1 | # unreal._ObjectBase 2 | # https://api.unrealengine.com/INT/PythonAPI/class/_ObjectBase.html 3 | 4 | import unreal 5 | 6 | 7 | 8 | # object_to_cast: obj unreal.Object : The object you want to cast 9 | # object_class: obj unreal.Class : The class you want to cast the object into 10 | def cast(object_to_cast=None, object_class=None): 11 | try: 12 | return object_class.cast(object_to_cast) 13 | except: 14 | return None 15 | 16 | 17 | 18 | 19 | # Cpp ######################################################################################################################################################################################## 20 | 21 | 22 | 23 | 24 | # Note: Also work using the command : help(unreal.StaticMesh) 25 | # unreal_class: obj : The class you want to know the properties 26 | # return: str List : The available properties (formatted the way you can directly use them to get their values) 27 | def getAllProperties(unreal_class=None): 28 | return unreal.CppLib.get_all_properties(unreal_class) 29 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/PythonLibraries/QtFunctions.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import sys 3 | sys.path.append('C:/Python27/Lib/site-packages') 4 | from PySide import QtGui 5 | 6 | # This function will receive the tick from Unreal 7 | def __QtAppTick__(delta_seconds): 8 | for window in opened_windows: 9 | window.eventTick(delta_seconds) 10 | 11 | # This function will be called when the application is closing. 12 | def __QtAppQuit__(): 13 | unreal.unregister_slate_post_tick_callback(tick_handle) 14 | 15 | # This function is called by the windows when they are closing. (Only if the connection is properly made.) 16 | def __QtWindowClosed__(window=None): 17 | if window in opened_windows: 18 | opened_windows.remove(window) 19 | 20 | # This part is for the initial setup. Need to run once to spawn the application. 21 | unreal_app = QtGui.QApplication.instance() 22 | if not unreal_app: 23 | unreal_app = QtGui.QApplication(sys.argv) 24 | tick_handle = unreal.register_slate_post_tick_callback(__QtAppTick__) 25 | unreal_app.aboutToQuit.connect(__QtAppQuit__) 26 | existing_windows = {} 27 | opened_windows = [] 28 | 29 | 30 | 31 | 32 | 33 | # desired_window_class: class QtGui.QWidget : The window class you want to spawn 34 | # return: The new or existing window 35 | def spawnQtWindow(desired_window_class=None): 36 | window = existing_windows.get(desired_window_class, None) 37 | if not window: 38 | window = desired_window_class() 39 | existing_windows[desired_window_class] = window 40 | window.aboutToClose = __QtWindowClosed__ 41 | if window not in opened_windows: 42 | opened_windows.append(window) 43 | window.show() 44 | window.activateWindow() 45 | return window 46 | 47 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/PythonLibraries/SequencerFunctions.py: -------------------------------------------------------------------------------- 1 | # unreal.MovieSceneSequence 2 | # https://api.unrealengine.com/INT/PythonAPI/class/MovieSceneSequence.html 3 | 4 | # unreal.LevelSequence 5 | # https://api.unrealengine.com/INT/PythonAPI/class/LevelSequence.html 6 | 7 | # unreal.SequencerBindingProxy 8 | # https://api.unrealengine.com/INT/PythonAPI/class/SequencerBindingProxy.html 9 | 10 | import unreal 11 | 12 | 13 | 14 | # sequence_path: str : The level sequence asset path 15 | # actor: obj unreal.Actor : The actor you want to add into (or get from) the sequence asset 16 | # return: obj unreal.SequencerBindingProxy : The actor binding 17 | def getOrAddPossessableInSequenceAsset(sequence_path='', actor=None): 18 | sequence_asset = unreal.LevelSequence.cast(unreal.load_asset(sequence_path)) 19 | possessable = sequence_asset.add_possessable(object_to_possess=actor) 20 | return possessable 21 | 22 | 23 | # animation_path: str : The animation asset path 24 | # possessable: obj unreal.SequencerBindingProxy : The actor binding you want to add the animation on 25 | # return: obj unreal.SequencerBindingProxy : The actor binding 26 | def addSkeletalAnimationTrackOnPossessable(animation_path='', possessable=None): 27 | # Get Animation 28 | animation_asset = unreal.AnimSequence.cast(unreal.load_asset(animation_path)) 29 | params = unreal.MovieSceneSkeletalAnimationParams() 30 | params.set_editor_property('Animation', animation_asset) 31 | # Add track 32 | animation_track = possessable.add_track(track_type=unreal.MovieSceneSkeletalAnimationTrack) 33 | # Add section 34 | animation_section = animation_track.add_section() 35 | animation_section.set_editor_property('Params', params) 36 | animation_section.set_range(0, animation_asset.get_editor_property('sequence_length')) 37 | 38 | 39 | def addSkeletalAnimationTrackOnActor_EXAMPLE(): 40 | sequence_path = '/Game/ExampleAssets/Sequences/SEQ_Test' 41 | animation_path = '/Game/ExampleAssets/Animations/AN_Tutorial_Idle' 42 | actor_in_world = unreal.GameplayStatics.get_all_actors_of_class(unreal.EditorLevelLibrary.get_editor_world(), unreal.SkeletalMeshActor)()[0] 43 | possessable_in_sequence = getOrAddPossessableInSequenceAsset(sequence_path, actor_in_world) 44 | addSkeletalAnimationTrackOnPossessable(animation_path, possessable_in_sequence) 45 | 46 | 47 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/PythonLibraries/WorldFunctions.py: -------------------------------------------------------------------------------- 1 | # unreal.EditorLevelLibrary 2 | # https://api.unrealengine.com/INT/PythonAPI/class/EditorLevelLibrary.html 3 | 4 | # unreal.GameplayStatics 5 | # https://api.unrealengine.com/INT/PythonAPI/class/GameplayStatics.html 6 | 7 | # unreal.Actor 8 | # https://api.unrealengine.com/INT/PythonAPI/class/Actor.html 9 | 10 | import unreal 11 | import PythonHelpers 12 | 13 | 14 | # use_selection: bool : True if you want to get only the selected actors 15 | # actor_class: class unreal.Actor : The class used to filter the actors. Can be None if you do not want to use this filter 16 | # actor_tag: str : The tag used to filter the actors. Can be None if you do not want to use this filter 17 | # world: obj unreal.World : The world you want to get the actors from. If None, will get the actors from the currently open world. 18 | # return: obj List unreal.Actor : The actors 19 | def getAllActors(use_selection=False, actor_class=None, actor_tag=None, world=None): 20 | world = world if world is not None else unreal.EditorLevelLibrary.get_editor_world() # Make sure to have a valid world 21 | if use_selection: 22 | selected_actors = getSelectedActors() 23 | class_actors = selected_actors 24 | if actor_class: 25 | class_actors = [x for x in selected_actors if PythonHelpers.cast(x, actor_class)] 26 | tag_actors = class_actors 27 | if actor_tag: 28 | tag_actors = [x for x in selected_actors if x.actor_has_tag(actor_tag)] 29 | return [x for x in tag_actors] 30 | elif actor_class: 31 | actors = unreal.GameplayStatics.get_all_actors_of_class(world, actor_class) 32 | tag_actors = actors 33 | if actor_tag: 34 | tag_actors = [x for x in actors if x.actor_has_tag(actor_tag)] 35 | return [x for x in tag_actors] 36 | elif actor_tag: 37 | tag_actors = unreal.GameplayStatics.get_all_actors_with_tag(world, actor_tag) 38 | return [x for x in tag_actors] 39 | else: 40 | actors = unreal.GameplayStatics.get_all_actors_of_class(world, unreal.Actor) 41 | return [x for x in actors] 42 | 43 | 44 | # path: str : Blueprint class path 45 | # actor_location: obj unreal.Vector : The actor location 46 | # actor_rotation: obj unreal.Rotator : The actor rotation 47 | # actor_location: obj unreal.Vector : The actor scale 48 | # world: obj unreal.World : The world in which you want to spawn the actor. If None, will spawn in the currently open world. 49 | # properties: dict : The properties you want to set before the actor is spawned. These properties will be taken into account in the Construction Script 50 | # return: obj unreal.Actor : The spawned actor 51 | def spawnBlueprintActor(path='', actor_location=None, actor_rotation=None, actor_scale=None, world=None, properties={}): 52 | actor_class = unreal.EditorAssetLibrary.load_blueprint_class(path) 53 | actor_transform = unreal.Transform(actor_location, actor_rotation, actor_scale) 54 | world = world if world is not None else unreal.EditorLevelLibrary.get_editor_world() # Make sure to have a valid world 55 | # Begin Spawn 56 | actor = unreal.GameplayStatics.begin_spawning_actor_from_class(world_context_object=world, actor_class=actor_class, spawn_transform=actor_transform, no_collision_fail=True) 57 | # Edit Properties 58 | for x in properties: 59 | actor.set_editor_property(x, properties[x]) 60 | # Complete Spawn 61 | unreal.GameplayStatics.finish_spawning_actor(actor=actor, spawn_transform=actor_transform) 62 | return actor 63 | 64 | 65 | # return: obj List unreal.Actor : The selected actors in the world 66 | def getSelectedActors(): 67 | return unreal.EditorLevelLibrary.get_selected_level_actors() 68 | 69 | 70 | # Note: Will always clear the selection before selecting. 71 | # actors_to_select: obj List unreal.Actor : The actors to select. 72 | def selectActors(actors_to_select=[]): 73 | unreal.EditorLevelLibrary.set_selected_level_actors(actors_to_select) 74 | 75 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/QtWindows/QtWindowOne.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import sys 3 | sys.path.append('C:/Python27/Lib/site-packages') 4 | from PySide import QtGui, QtUiTools 5 | 6 | WINDOW_NAME = 'Qt Window One' 7 | UI_FILE_FULLNAME = __file__.replace('.py', '.ui') 8 | 9 | class QtWindowOne(QtGui.QWidget): 10 | def __init__(self, parent=None): 11 | super(QtWindowOne, self).__init__(parent) 12 | self.aboutToClose = None # This is used to stop the tick when the window is closed 13 | self.widget = QtUiTools.QUiLoader().load(UI_FILE_FULLNAME) 14 | self.widget.setParent(self) 15 | self.setWindowTitle(WINDOW_NAME) 16 | self.setGeometry(100, 100, self.widget.width(), self.widget.height()) 17 | self.initialiseWidget() 18 | 19 | def closeEvent(self, event): 20 | if self.aboutToClose: 21 | self.aboutToClose(self) 22 | event.accept() 23 | 24 | def eventTick(self, delta_seconds): 25 | self.myTick(delta_seconds) 26 | 27 | 28 | ########################################## 29 | 30 | 31 | def initialiseWidget(self): 32 | self.time_while_this_window_is_open = 0.0 33 | self.random_actor = None 34 | self.random_actor_is_going_up = True 35 | self.widget.button_MoveRandom.clicked.connect(self.moveRandomActorInScene) 36 | 37 | def moveRandomActorInScene(self): 38 | import random 39 | import WorldFunctions 40 | all_actors = WorldFunctions.getAllActors(use_selection = False, actor_class = unreal.StaticMeshActor, actor_tag = None) 41 | rand = random.randrange(0, len(all_actors)) 42 | self.random_actor = all_actors[rand] 43 | 44 | def myTick(self, delta_seconds): 45 | # Set Time 46 | self.time_while_this_window_is_open += delta_seconds 47 | self.widget.lbl_Seconds.setText("%.1f Seconds" % self.time_while_this_window_is_open) 48 | # Affect Actor 49 | if self.random_actor: 50 | actor_location = self.random_actor.get_actor_location() 51 | speed = 300.0 * delta_seconds 52 | if self.random_actor_is_going_up: 53 | if actor_location.z > 1000.0: 54 | self.random_actor_is_going_up = False 55 | else: 56 | speed = -speed 57 | if actor_location.z < 0.0: 58 | self.random_actor_is_going_up = True 59 | self.random_actor.add_actor_world_offset(unreal.Vector(0.0, 0.0, speed), False, False) -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/QtWindows/QtWindowOne.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 297 10 | 120 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | QWidget#Form { 18 | background-color:#262626; 19 | color:white; 20 | } 21 | 22 | 23 | 24 | 25 | 26 | 27 | 20 28 | 29 | 30 | 31 | color:white; 32 | 33 | 34 | Window One 35 | 36 | 37 | Qt::AlignCenter 38 | 39 | 40 | 41 | 42 | 43 | 44 | Qt::Vertical 45 | 46 | 47 | 48 | 20 49 | 40 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Qt::Horizontal 60 | 61 | 62 | 63 | 40 64 | 20 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 10 74 | 75 | 76 | 77 | color: white; 78 | 79 | 80 | Time While This Window Is Open: 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 10 89 | 90 | 91 | 92 | color: white; 93 | 94 | 95 | 0 Seconds 96 | 97 | 98 | 99 | 100 | 101 | 102 | Qt::Horizontal 103 | 104 | 105 | 106 | 40 107 | 20 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Qt::Vertical 118 | 119 | 120 | 121 | 20 122 | 40 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | Move Random Actor In Scene 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/QtWindows/QtWindowThree.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import sys 3 | sys.path.append('C:/Python27/Lib/site-packages') 4 | from PySide import QtGui, QtUiTools 5 | 6 | WINDOW_NAME = 'Qt Window Three' 7 | UI_FILE_FULLNAME = __file__.replace('.py', '.ui') 8 | 9 | class QtWindowThree(QtGui.QWidget): 10 | def __init__(self, parent=None): 11 | super(QtWindowThree, self).__init__(parent) 12 | self.aboutToClose = None # This is used to stop the tick when the window is closed 13 | self.widget = QtUiTools.QUiLoader().load(UI_FILE_FULLNAME) 14 | self.widget.setParent(self) 15 | self.setWindowTitle(WINDOW_NAME) 16 | self.setGeometry(100, 500, self.widget.width(), self.widget.height()) 17 | self.initialiseWidget() 18 | 19 | def closeEvent(self, event): 20 | if self.aboutToClose: 21 | self.aboutToClose(self) 22 | event.accept() 23 | 24 | def eventTick(self, delta_seconds): 25 | self.myTick(delta_seconds) 26 | 27 | 28 | ########################################## 29 | 30 | 31 | def initialiseWidget(self): 32 | self.time_while_this_window_is_open = 0.0 33 | self.random_actor = None 34 | self.random_actor_is_growing = True 35 | self.widget.button_ScaleRandom.clicked.connect(self.scaleRandomActorInScene) 36 | 37 | def scaleRandomActorInScene(self): 38 | import random 39 | import WorldFunctions 40 | all_actors = WorldFunctions.getAllActors(use_selection = False, actor_class = unreal.StaticMeshActor, actor_tag = None) 41 | rand = random.randrange(0, len(all_actors)) 42 | self.random_actor = all_actors[rand] 43 | 44 | def myTick(self, delta_seconds): 45 | # Set Time 46 | self.time_while_this_window_is_open += delta_seconds 47 | self.widget.lbl_Seconds.setText("%.1f Seconds" % self.time_while_this_window_is_open) 48 | # Affect Actor 49 | if self.random_actor: 50 | actor_scale = self.random_actor.get_actor_scale3d() 51 | speed = 1.0 * delta_seconds 52 | if self.random_actor_is_growing: 53 | if actor_scale.z > 4.0: 54 | self.random_actor_is_growing = False 55 | else: 56 | speed = -speed 57 | if actor_scale.z < 0.5: 58 | self.random_actor_is_growing = True 59 | self.random_actor.set_actor_scale3d(unreal.Vector(actor_scale.x + speed, actor_scale.y + speed, actor_scale.z + speed)) 60 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/QtWindows/QtWindowThree.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 676 10 | 185 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | QWidget#Form { 18 | background-color:#808080; 19 | color:white; 20 | } 21 | 22 | 23 | 24 | 25 | 26 | 27 | 20 28 | 29 | 30 | 31 | color:white; 32 | 33 | 34 | Window Three 35 | 36 | 37 | Qt::AlignCenter 38 | 39 | 40 | 41 | 42 | 43 | 44 | Qt::Vertical 45 | 46 | 47 | 48 | 20 49 | 40 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Qt::Horizontal 60 | 61 | 62 | 63 | 40 64 | 20 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 10 74 | 75 | 76 | 77 | color: white; 78 | 79 | 80 | Time While This Window Is Open: 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 10 89 | 90 | 91 | 92 | color: white; 93 | 94 | 95 | 0 Seconds 96 | 97 | 98 | 99 | 100 | 101 | 102 | Qt::Horizontal 103 | 104 | 105 | 106 | 40 107 | 20 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Qt::Vertical 118 | 119 | 120 | 121 | 20 122 | 40 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | Scale Random Actor In Scene 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/QtWindows/QtWindowTwo.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import sys 3 | sys.path.append('C:/Python27/Lib/site-packages') 4 | from PySide import QtGui, QtUiTools 5 | 6 | WINDOW_NAME = 'Qt Window Two' 7 | UI_FILE_FULLNAME = __file__.replace('.py', '.ui') 8 | 9 | class QtWindowTwo(QtGui.QWidget): 10 | def __init__(self, parent=None): 11 | super(QtWindowTwo, self).__init__(parent) 12 | self.aboutToClose = None # This is used to stop the tick when the window is closed 13 | self.widget = QtUiTools.QUiLoader().load(UI_FILE_FULLNAME) 14 | self.widget.setParent(self) 15 | self.setWindowTitle(WINDOW_NAME) 16 | self.setGeometry(100, 300, self.widget.width(), self.widget.height()) 17 | self.initialiseWidget() 18 | 19 | def closeEvent(self, event): 20 | if self.aboutToClose: 21 | self.aboutToClose(self) 22 | event.accept() 23 | 24 | def eventTick(self, delta_seconds): 25 | self.myTick(delta_seconds) 26 | 27 | 28 | ########################################## 29 | 30 | 31 | def initialiseWidget(self): 32 | self.time_while_this_window_is_open = 0.0 33 | self.random_actor = None 34 | self.widget.button_RotateRandom.clicked.connect(self.rotateRandomActorInScene) 35 | 36 | def rotateRandomActorInScene(self): 37 | import random 38 | import WorldFunctions 39 | all_actors = WorldFunctions.getAllActors(use_selection = False, actor_class = unreal.StaticMeshActor, actor_tag = None) 40 | rand = random.randrange(0, len(all_actors)) 41 | self.random_actor = all_actors[rand] 42 | 43 | def myTick(self, delta_seconds): 44 | # Set Time 45 | self.time_while_this_window_is_open += delta_seconds 46 | self.widget.lbl_Seconds.setText("%.1f Seconds" % self.time_while_this_window_is_open) 47 | # Affect Actor 48 | if self.random_actor: 49 | speed = 90.0 * delta_seconds 50 | self.random_actor.add_actor_world_rotation(unreal.Rotator(0.0, 0.0, speed), False, False) -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Content/Python/QtWindows/QtWindowTwo.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Form 4 | 5 | 6 | 7 | 0 8 | 0 9 | 474 10 | 154 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | QWidget#Form { 18 | background-color:#4d4d4d; 19 | color:white; 20 | } 21 | 22 | 23 | 24 | 25 | 26 | 27 | 20 28 | 29 | 30 | 31 | color:white; 32 | 33 | 34 | Window Two 35 | 36 | 37 | Qt::AlignCenter 38 | 39 | 40 | 41 | 42 | 43 | 44 | Qt::Vertical 45 | 46 | 47 | 48 | 20 49 | 40 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Qt::Horizontal 60 | 61 | 62 | 63 | 40 64 | 20 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 10 74 | 75 | 76 | 77 | color: white; 78 | 79 | 80 | Time While This Window Is Open: 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 10 89 | 90 | 91 | 92 | color: white; 93 | 94 | 95 | 0 Seconds 96 | 97 | 98 | 99 | 100 | 101 | 102 | Qt::Horizontal 103 | 104 | 105 | 106 | 40 107 | 20 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Qt::Vertical 118 | 119 | 120 | 121 | 20 122 | 40 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | Rotate Random Actor In Scene 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexQuevillon/UnrealPythonLibrary/d9c2348553aaacbc173e81b1b3ddc977b0bb3c37/UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Resources/Icon128.png -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Source/UnrealPythonLibraryPlugin/Private/CppLib.cpp: -------------------------------------------------------------------------------- 1 | #include "CppLib.h" 2 | #include "Runtime/Core/Public/Misc/ConfigCacheIni.h" 3 | //PublicDependencyModuleNames-> "UnrealEd" 4 | #include "Editor/UnrealEd/Public/Editor.h" 5 | #include "Editor/UnrealEd/Public/Toolkits/AssetEditorManager.h" 6 | #include "Editor/UnrealEd/Public/LevelEditorViewport.h" 7 | // PublicDependencyModuleNames -> "ContentBrowser" 8 | #include "Editor/ContentBrowser/Public/ContentBrowserModule.h" 9 | #include "Editor/ContentBrowser/Private/SContentBrowser.h" 10 | // PublicDependencyModuleNames -> "AssetRegistry" 11 | #include "Runtime/AssetRegistry/Public/AssetRegistryModule.h" 12 | // PublicDependencyModuleNames -> "PythonScriptPlugin" && "Python" 13 | #include "../Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PythonScriptPlugin.h" 14 | 15 | TArray UCppLib::GetAllProperties(UClass* Class) { 16 | TArray Ret; 17 | if (Class != nullptr) { 18 | for (TFieldIterator It(Class); It; ++It) { 19 | UProperty* Property = *It; 20 | if (Property->HasAnyPropertyFlags(EPropertyFlags::CPF_Edit)) { 21 | Ret.Add(Property->GetName()); 22 | } 23 | } 24 | } 25 | return Ret; 26 | } 27 | 28 | void UCppLib::ExecuteConsoleCommand(FString ConsoleCommand) { 29 | if (GEditor) { 30 | UWorld* World = GEditor->GetEditorWorldContext().World(); 31 | if (World) { 32 | GEditor->Exec(World, *ConsoleCommand, *GLog); 33 | } 34 | } 35 | } 36 | 37 | TArray UCppLib::GetSelectedAssets() { 38 | FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); 39 | TArray SelectedAssets; 40 | ContentBrowserModule.Get().GetSelectedAssets(SelectedAssets); 41 | TArray Result; 42 | for (FAssetData& AssetData : SelectedAssets) { 43 | Result.Add(AssetData.PackageName.ToString()); 44 | } 45 | return Result; 46 | } 47 | 48 | void UCppLib::SetSelectedAssets(TArray Paths) { 49 | FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); 50 | FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked("AssetRegistry"); 51 | TArray PathsName; 52 | for (FString Path : Paths) { 53 | PathsName.Add(*Path); 54 | } 55 | FARFilter AssetFilter; 56 | AssetFilter.PackageNames = PathsName; 57 | TArray AssetDatas; 58 | AssetRegistryModule.Get().GetAssets(AssetFilter, AssetDatas); 59 | ContentBrowserModule.Get().SyncBrowserToAssets(AssetDatas); 60 | } 61 | 62 | TArray UCppLib::GetSelectedFolders() { 63 | FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); 64 | TArray SelectedFolders; 65 | ContentBrowserModule.Get().GetSelectedFolders(SelectedFolders); 66 | return SelectedFolders; 67 | } 68 | 69 | void UCppLib::SetSelectedFolders(TArray Paths) { 70 | FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); 71 | ContentBrowserModule.Get().SyncBrowserToFolders(Paths); 72 | } 73 | 74 | void UCppLib::CloseEditorForAssets(TArray Assets) { 75 | FAssetEditorManager& AssetEditorManager = FAssetEditorManager::Get(); 76 | for (UObject* Asset : Assets) { 77 | AssetEditorManager.CloseAllEditorsForAsset(Asset); 78 | } 79 | } 80 | 81 | TArray UCppLib::GetAssetsOpenedInEditor() { 82 | FAssetEditorManager& AssetEditorManager = FAssetEditorManager::Get(); 83 | return AssetEditorManager.GetAllEditedAssets(); 84 | } 85 | 86 | void UCppLib::SetFolderColor(FString FolderPath, FLinearColor Color) { 87 | GConfig->SetString(TEXT("PathColor"), *FolderPath, *Color.ToString(), GEditorPerProjectIni); 88 | } 89 | 90 | int UCppLib::GetActiveViewportIndex() { 91 | int Index = 1; 92 | if (GEditor != nullptr && GCurrentLevelEditingViewportClient != nullptr) { 93 | GEditor->GetLevelViewportClients().Find(GCurrentLevelEditingViewportClient, Index); 94 | } 95 | return Index; 96 | } 97 | 98 | // ViewportIndex is affected by the spawning order and not the viewport number. 99 | // e.g. Viewport 4 can be the first one if the user spawned it first. 100 | // And can become the last one if the user open the other ones and then close and re-open Viewport 4. 101 | // Also, the indexes are confusing. 102 | // 1st Spawned Viewport : Index = 1 103 | // 2nd Spawned Viewport : Index = 5 104 | // 3rd Spawned Viewport : Index = 9 105 | // 4th Spawned Viewport : Index = 13 106 | void UCppLib::SetViewportLocationAndRotation(int ViewportIndex, FVector Location, FRotator Rotation) { 107 | if (GEditor != nullptr && ViewportIndex < GEditor->GetLevelViewportClients().Num()) { 108 | FLevelEditorViewportClient* LevelViewportClient = GEditor->GetLevelViewportClients()[ViewportIndex]; 109 | if (LevelViewportClient != nullptr) { 110 | LevelViewportClient->SetViewLocation(Location); 111 | LevelViewportClient->SetViewRotation(Rotation); 112 | } 113 | } 114 | } 115 | 116 | void UCppLib::ExecutePythonScript(FString PythonScript) { 117 | FPythonScriptPlugin::Get()->ExecPythonCommand(*PythonScript); 118 | } 119 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Source/UnrealPythonLibraryPlugin/Private/UnrealPythonLibraryPlugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "UnrealPythonLibraryPlugin.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FUnrealPythonLibraryPluginModule" 6 | 7 | void FUnrealPythonLibraryPluginModule::StartupModule() 8 | { 9 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 10 | 11 | } 12 | 13 | void FUnrealPythonLibraryPluginModule::ShutdownModule() 14 | { 15 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 16 | // we call this function before unloading the module. 17 | 18 | } 19 | 20 | #undef LOCTEXT_NAMESPACE 21 | 22 | IMPLEMENT_MODULE(FUnrealPythonLibraryPluginModule, UnrealPythonLibraryPlugin) -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Source/UnrealPythonLibraryPlugin/Private/UnrealPythonLibraryPluginBPLibrary.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "UnrealPythonLibraryPluginBPLibrary.h" 4 | #include "UnrealPythonLibraryPlugin.h" 5 | 6 | UUnrealPythonLibraryPluginBPLibrary::UUnrealPythonLibraryPluginBPLibrary(const FObjectInitializer& ObjectInitializer) 7 | : Super(ObjectInitializer) 8 | { 9 | 10 | } 11 | 12 | float UUnrealPythonLibraryPluginBPLibrary::UnrealPythonLibraryPluginSampleFunction(float Param) 13 | { 14 | return -1; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Source/UnrealPythonLibraryPlugin/Public/CppLib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Kismet/BlueprintFunctionLibrary.h" 4 | #include "CppLib.generated.h" 5 | 6 | UCLASS() 7 | class UCppLib : public UBlueprintFunctionLibrary { 8 | GENERATED_BODY() 9 | 10 | public: 11 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 12 | static TArray GetAllProperties(UClass* Class); 13 | 14 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 15 | static void ExecuteConsoleCommand(FString ConsoleCommand); 16 | 17 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 18 | static TArray GetSelectedAssets(); 19 | 20 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 21 | static TArray GetSelectedFolders(); 22 | 23 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 24 | static void SetSelectedAssets(TArray Paths); 25 | 26 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 27 | static void SetSelectedFolders(TArray Paths); 28 | 29 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 30 | static void CloseEditorForAssets(TArray Assets); 31 | 32 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 33 | static TArray GetAssetsOpenedInEditor(); 34 | 35 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 36 | static void SetFolderColor(FString FolderPath, FLinearColor Color); 37 | 38 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 39 | static void SetViewportLocationAndRotation(int ViewportIndex, FVector Location, FRotator Rotation); 40 | 41 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 42 | static int GetActiveViewportIndex(); 43 | 44 | UFUNCTION(BlueprintCallable, Category = "Unreal Python") 45 | static void ExecutePythonScript(FString PythonScript); 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Source/UnrealPythonLibraryPlugin/Public/UnrealPythonLibraryPlugin.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "Modules/ModuleManager.h" 6 | 7 | class FUnrealPythonLibraryPluginModule : public IModuleInterface 8 | { 9 | public: 10 | 11 | /** IModuleInterface implementation */ 12 | virtual void StartupModule() override; 13 | virtual void ShutdownModule() override; 14 | }; 15 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Source/UnrealPythonLibraryPlugin/Public/UnrealPythonLibraryPluginBPLibrary.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "Kismet/BlueprintFunctionLibrary.h" 6 | #include "UnrealPythonLibraryPluginBPLibrary.generated.h" 7 | 8 | /* 9 | * Function library class. 10 | * Each function in it is expected to be static and represents blueprint node that can be called in any blueprint. 11 | * 12 | * When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable. 13 | * BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins. 14 | * BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins. 15 | * DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu. 16 | * Its lets you name the node using characters not allowed in C++ function names. 17 | * CompactNodeTitle - the word(s) that appear on the node. 18 | * Keywords - the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu. 19 | * Good example is "Print String" node which you can find also by using keyword "log". 20 | * Category - the category your node will be under in the Blueprint drop-down menu. 21 | * 22 | * For more info on custom blueprint nodes visit documentation: 23 | * https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation 24 | */ 25 | UCLASS() 26 | class UUnrealPythonLibraryPluginBPLibrary : public UBlueprintFunctionLibrary 27 | { 28 | GENERATED_UCLASS_BODY() 29 | 30 | UFUNCTION(BlueprintCallable, meta = (DisplayName = "Execute Sample function", Keywords = "UnrealPythonLibraryPlugin sample test testing"), Category = "UnrealPythonLibraryPluginTesting") 31 | static float UnrealPythonLibraryPluginSampleFunction(float Param); 32 | }; 33 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/Source/UnrealPythonLibraryPlugin/UnrealPythonLibraryPlugin.Build.cs: -------------------------------------------------------------------------------- 1 | // Some copyright should be here... 2 | 3 | using UnrealBuildTool; 4 | 5 | public class UnrealPythonLibraryPlugin : ModuleRules 6 | { 7 | public UnrealPythonLibraryPlugin(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | // ... add public include paths required here ... 14 | } 15 | ); 16 | 17 | 18 | PrivateIncludePaths.AddRange( 19 | new string[] { 20 | // ... add other private include paths required here ... 21 | } 22 | ); 23 | 24 | 25 | PublicDependencyModuleNames.AddRange( 26 | new string[] 27 | { 28 | "Core", 29 | // ... add other public dependencies that you statically link with here ... 30 | } 31 | ); 32 | 33 | 34 | PrivateDependencyModuleNames.AddRange( 35 | new string[] 36 | { 37 | "CoreUObject", 38 | "Engine", 39 | "Slate", 40 | "SlateCore", 41 | // Additional Modules 42 | "UnrealEd", 43 | "Blutility", 44 | "ContentBrowser", 45 | "AssetRegistry", 46 | "Python", 47 | "PythonScriptPlugin" 48 | } 49 | ); 50 | 51 | 52 | DynamicallyLoadedModuleNames.AddRange( 53 | new string[] 54 | { 55 | // ... add any modules that your module loads dynamically here ... 56 | } 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/Plugins/UnrealPythonLibraryPlugin/UnrealPythonLibraryPlugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "Unreal Python Library Plugin", 6 | "Description": "A Pipeline Oriented Function Library", 7 | "Category": "Scripting", 8 | "CreatedBy": "Alex Quevillon", 9 | "CreatedByURL": "https://www.youtube.com/AlexQuevillonEn", 10 | "DocsURL": "https://www.youtube.com/AlexQuevillonEn", 11 | "MarketplaceURL": "https://github.com/AlexQuevillon/UnrealPythonLibrary", 12 | "SupportURL": "https://www.youtube.com/AlexQuevillonEn", 13 | "CanContainContent": true, 14 | "IsBetaVersion": true, 15 | "Installed": false, 16 | "Modules": [ 17 | { 18 | "Name": "UnrealPythonLibraryPlugin", 19 | "Type": "Runtime", 20 | "LoadingPhase": "PreLoadingScreen" 21 | } 22 | ], 23 | "Plugins": [ 24 | { 25 | "Name": "PythonScriptPlugin", 26 | "Enabled": true 27 | } 28 | ] 29 | } -------------------------------------------------------------------------------- /UnrealProject/UnrealPythonLibrary/UnrealPythonLibrary.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "{5B95D221-408A-62EF-5456-17A670F44F86}", 4 | "Category": "", 5 | "Description": "", 6 | "Plugins": [ 7 | { 8 | "Name": "PythonScriptPlugin", 9 | "Enabled": true 10 | }, 11 | { 12 | "Name": "EditorScriptingUtilities", 13 | "Enabled": true 14 | }, 15 | { 16 | "Name": "SequencerScripting", 17 | "Enabled": true 18 | } 19 | ] 20 | } --------------------------------------------------------------------------------