├── Content ├── ActorDistributionTool │ ├── ActorDistributionTool.uasset │ ├── BP_DistributionBase.uasset │ ├── Distributions │ │ ├── BP_3DGridDistribution.uasset │ │ ├── BP_CircleDistribution.uasset │ │ ├── BP_ComplexCircleDistribution.uasset │ │ └── BP_FibonacciSphereDistribution.uasset │ └── E_CircleDistributionOrientation.uasset ├── Assets │ ├── M_GasTank.uasset │ ├── M_Steel.uasset │ ├── M_TriplanarGrid.uasset │ └── SM_GasTankAbomination.uasset ├── BP_ActorUtilities.uasset ├── BP_SnapToSurface.uasset ├── BP_TheSimplestTool.uasset ├── BP_ToolbarButton.uasset ├── GeometryScripting │ ├── BP_MeshGenerator.uasset │ ├── SM_BakedStaticMeshActor.uasset │ ├── S_AssetSettings.uasset │ └── S_MeshSettings.uasset ├── MaterialTools │ ├── BP_BaseMaterialSelectDialogHelper.uasset │ └── BP_TextureActions.uasset ├── Python │ ├── .pylintrc │ ├── .vscode │ │ └── settings.json │ ├── __pycache__ │ │ ├── material_instance_tools.cpython-39.pyc │ │ ├── material_tools.cpython-39.pyc │ │ └── scoped_slow_task.cpython-39.pyc │ ├── material_instance_tools.py │ ├── material_tools.py │ └── scoped_slow_task.py └── Viewport │ ├── BP_ViewportSceneCapture.uasset │ ├── M_CameraMaterial.uasset │ ├── M_Viewport.uasset │ ├── RT_Viewport.uasset │ └── WBP_Viewport.uasset ├── Resources └── Icon128.png └── UtilityToolkit.uplugin /Content/ActorDistributionTool/ActorDistributionTool.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/ActorDistributionTool/ActorDistributionTool.uasset -------------------------------------------------------------------------------- /Content/ActorDistributionTool/BP_DistributionBase.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/ActorDistributionTool/BP_DistributionBase.uasset -------------------------------------------------------------------------------- /Content/ActorDistributionTool/Distributions/BP_3DGridDistribution.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/ActorDistributionTool/Distributions/BP_3DGridDistribution.uasset -------------------------------------------------------------------------------- /Content/ActorDistributionTool/Distributions/BP_CircleDistribution.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/ActorDistributionTool/Distributions/BP_CircleDistribution.uasset -------------------------------------------------------------------------------- /Content/ActorDistributionTool/Distributions/BP_ComplexCircleDistribution.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/ActorDistributionTool/Distributions/BP_ComplexCircleDistribution.uasset -------------------------------------------------------------------------------- /Content/ActorDistributionTool/Distributions/BP_FibonacciSphereDistribution.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/ActorDistributionTool/Distributions/BP_FibonacciSphereDistribution.uasset -------------------------------------------------------------------------------- /Content/ActorDistributionTool/E_CircleDistributionOrientation.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/ActorDistributionTool/E_CircleDistributionOrientation.uasset -------------------------------------------------------------------------------- /Content/Assets/M_GasTank.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Assets/M_GasTank.uasset -------------------------------------------------------------------------------- /Content/Assets/M_Steel.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Assets/M_Steel.uasset -------------------------------------------------------------------------------- /Content/Assets/M_TriplanarGrid.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Assets/M_TriplanarGrid.uasset -------------------------------------------------------------------------------- /Content/Assets/SM_GasTankAbomination.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Assets/SM_GasTankAbomination.uasset -------------------------------------------------------------------------------- /Content/BP_ActorUtilities.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/BP_ActorUtilities.uasset -------------------------------------------------------------------------------- /Content/BP_SnapToSurface.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/BP_SnapToSurface.uasset -------------------------------------------------------------------------------- /Content/BP_TheSimplestTool.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/BP_TheSimplestTool.uasset -------------------------------------------------------------------------------- /Content/BP_ToolbarButton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/BP_ToolbarButton.uasset -------------------------------------------------------------------------------- /Content/GeometryScripting/BP_MeshGenerator.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/GeometryScripting/BP_MeshGenerator.uasset -------------------------------------------------------------------------------- /Content/GeometryScripting/SM_BakedStaticMeshActor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/GeometryScripting/SM_BakedStaticMeshActor.uasset -------------------------------------------------------------------------------- /Content/GeometryScripting/S_AssetSettings.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/GeometryScripting/S_AssetSettings.uasset -------------------------------------------------------------------------------- /Content/GeometryScripting/S_MeshSettings.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/GeometryScripting/S_MeshSettings.uasset -------------------------------------------------------------------------------- /Content/MaterialTools/BP_BaseMaterialSelectDialogHelper.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/MaterialTools/BP_BaseMaterialSelectDialogHelper.uasset -------------------------------------------------------------------------------- /Content/MaterialTools/BP_TextureActions.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/MaterialTools/BP_TextureActions.uasset -------------------------------------------------------------------------------- /Content/Python/.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | 3 | # A comma-separated list of package or module names from where C extensions may 4 | # be loaded. Extensions are loading into the active Python interpreter and may 5 | # run arbitrary code. 6 | extension-pkg-allow-list= 7 | 8 | # A comma-separated list of package or module names from where C extensions may 9 | # be loaded. Extensions are loading into the active Python interpreter and may 10 | # run arbitrary code. (This is an alternative name to extension-pkg-allow-list 11 | # for backward compatibility.) 12 | extension-pkg-whitelist= 13 | 14 | # Return non-zero exit code if any of these messages/categories are detected, 15 | # even if score is above --fail-under value. Syntax same as enable. Messages 16 | # specified are enabled, while categories only check already-enabled messages. 17 | fail-on= 18 | 19 | # Specify a score threshold to be exceeded before program exits with error. 20 | fail-under=10.0 21 | 22 | # Files or directories to be skipped. They should be base names, not paths. 23 | ignore=CVS 24 | 25 | # Add files or directories matching the regex patterns to the ignore-list. The 26 | # regex matches against paths and can be in Posix or Windows format. 27 | ignore-paths= 28 | 29 | # Files or directories matching the regex patterns are skipped. The regex 30 | # matches against base names, not paths. The default value ignores emacs file 31 | # locks 32 | ignore-patterns=^\.# 33 | 34 | # Python code to execute, usually for sys.path manipulation such as 35 | # pygtk.require(). 36 | init-hook="../../Intermediate/PythonStub/" 37 | 38 | # Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the 39 | # number of processors available to use. 40 | jobs=1 41 | 42 | # Control the amount of potential inferred values when inferring a single 43 | # object. This can help the performance when dealing with large functions or 44 | # complex, nested conditions. 45 | limit-inference-results=100 46 | 47 | # List of plugins (as comma separated values of python module names) to load, 48 | # usually to register additional checkers. 49 | load-plugins= 50 | 51 | # Pickle collected data for later comparisons. 52 | persistent=yes 53 | 54 | # Minimum Python version to use for version dependent checks. Will default to 55 | # the version used to run pylint. 56 | py-version=3.10 57 | 58 | # Discover python modules and packages in the file system subtree. 59 | recursive=no 60 | 61 | # When enabled, pylint would attempt to guess common misconfiguration and emit 62 | # user-friendly hints instead of false-positive error messages. 63 | suggestion-mode=yes 64 | 65 | # Allow loading of arbitrary C extensions. Extensions are imported into the 66 | # active Python interpreter and may run arbitrary code. 67 | unsafe-load-any-extension=no 68 | 69 | 70 | [MESSAGES CONTROL] 71 | 72 | # Only show warnings with the listed confidence levels. Leave empty to show 73 | # all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, 74 | # UNDEFINED. 75 | confidence= 76 | 77 | # Disable the message, report, category or checker with the given id(s). You 78 | # can either give multiple identifiers separated by comma (,) or put this 79 | # option multiple times (only on the command line, not in the configuration 80 | # file where it should appear only once). You can also use "--disable=all" to 81 | # disable everything first and then re-enable specific checks. For example, if 82 | # you want to run only the similarities checker, you can use "--disable=all 83 | # --enable=similarities". If you want to run only the classes checker, but have 84 | # no Warning level messages displayed, use "--disable=all --enable=classes 85 | # --disable=W". 86 | disable=raw-checker-failed, 87 | bad-inline-option, 88 | locally-disabled, 89 | file-ignored, 90 | suppressed-message, 91 | useless-suppression, 92 | deprecated-pragma, 93 | use-symbolic-message-instead 94 | 95 | # Enable the message, report, category or checker with the given id(s). You can 96 | # either give multiple identifier separated by comma (,) or put this option 97 | # multiple time (only on the command line, not in the configuration file where 98 | # it should appear only once). See also the "--disable" option for examples. 99 | enable=c-extension-no-member 100 | 101 | 102 | [REPORTS] 103 | 104 | # Python expression which should return a score less than or equal to 10. You 105 | # have access to the variables 'fatal', 'error', 'warning', 'refactor', 106 | # 'convention', and 'info' which contain the number of messages in each 107 | # category, as well as 'statement' which is the total number of statements 108 | # analyzed. This score is used by the global evaluation report (RP0004). 109 | evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)) 110 | 111 | # Template used to display messages. This is a python new-style format string 112 | # used to format the message information. See doc for all details. 113 | #msg-template= 114 | 115 | # Set the output format. Available formats are text, parseable, colorized, json 116 | # and msvs (visual studio). You can also give a reporter class, e.g. 117 | # mypackage.mymodule.MyReporterClass. 118 | output-format=text 119 | 120 | # Tells whether to display a full report or only the messages. 121 | reports=no 122 | 123 | # Activate the evaluation score. 124 | score=yes 125 | 126 | 127 | [REFACTORING] 128 | 129 | # Maximum number of nested blocks for function / method body 130 | max-nested-blocks=5 131 | 132 | # Complete name of functions that never returns. When checking for 133 | # inconsistent-return-statements if a never returning function is called then 134 | # it will be considered as an explicit return statement and no message will be 135 | # printed. 136 | never-returning-functions=sys.exit,argparse.parse_error 137 | 138 | 139 | [BASIC] 140 | 141 | # Naming style matching correct argument names. 142 | argument-naming-style=snake_case 143 | 144 | # Regular expression matching correct argument names. Overrides argument- 145 | # naming-style. If left empty, argument names will be checked with the set 146 | # naming style. 147 | #argument-rgx= 148 | 149 | # Naming style matching correct attribute names. 150 | attr-naming-style=snake_case 151 | 152 | # Regular expression matching correct attribute names. Overrides attr-naming- 153 | # style. If left empty, attribute names will be checked with the set naming 154 | # style. 155 | #attr-rgx= 156 | 157 | # Bad variable names which should always be refused, separated by a comma. 158 | bad-names=foo, 159 | bar, 160 | baz, 161 | toto, 162 | tutu, 163 | tata 164 | 165 | # Bad variable names regexes, separated by a comma. If names match any regex, 166 | # they will always be refused 167 | bad-names-rgxs= 168 | 169 | # Naming style matching correct class attribute names. 170 | class-attribute-naming-style=any 171 | 172 | # Regular expression matching correct class attribute names. Overrides class- 173 | # attribute-naming-style. If left empty, class attribute names will be checked 174 | # with the set naming style. 175 | #class-attribute-rgx= 176 | 177 | # Naming style matching correct class constant names. 178 | class-const-naming-style=UPPER_CASE 179 | 180 | # Regular expression matching correct class constant names. Overrides class- 181 | # const-naming-style. If left empty, class constant names will be checked with 182 | # the set naming style. 183 | #class-const-rgx= 184 | 185 | # Naming style matching correct class names. 186 | class-naming-style=PascalCase 187 | 188 | # Regular expression matching correct class names. Overrides class-naming- 189 | # style. If left empty, class names will be checked with the set naming style. 190 | #class-rgx= 191 | 192 | # Naming style matching correct constant names. 193 | const-naming-style=UPPER_CASE 194 | 195 | # Regular expression matching correct constant names. Overrides const-naming- 196 | # style. If left empty, constant names will be checked with the set naming 197 | # style. 198 | #const-rgx= 199 | 200 | # Minimum line length for functions/classes that require docstrings, shorter 201 | # ones are exempt. 202 | docstring-min-length=-1 203 | 204 | # Naming style matching correct function names. 205 | function-naming-style=snake_case 206 | 207 | # Regular expression matching correct function names. Overrides function- 208 | # naming-style. If left empty, function names will be checked with the set 209 | # naming style. 210 | #function-rgx= 211 | 212 | # Good variable names which should always be accepted, separated by a comma. 213 | good-names=i, 214 | j, 215 | k, 216 | ex, 217 | Run, 218 | _ 219 | 220 | # Good variable names regexes, separated by a comma. If names match any regex, 221 | # they will always be accepted 222 | good-names-rgxs= 223 | 224 | # Include a hint for the correct naming format with invalid-name. 225 | include-naming-hint=no 226 | 227 | # Naming style matching correct inline iteration names. 228 | inlinevar-naming-style=any 229 | 230 | # Regular expression matching correct inline iteration names. Overrides 231 | # inlinevar-naming-style. If left empty, inline iteration names will be checked 232 | # with the set naming style. 233 | #inlinevar-rgx= 234 | 235 | # Naming style matching correct method names. 236 | method-naming-style=snake_case 237 | 238 | # Regular expression matching correct method names. Overrides method-naming- 239 | # style. If left empty, method names will be checked with the set naming style. 240 | #method-rgx= 241 | 242 | # Naming style matching correct module names. 243 | module-naming-style=snake_case 244 | 245 | # Regular expression matching correct module names. Overrides module-naming- 246 | # style. If left empty, module names will be checked with the set naming style. 247 | #module-rgx= 248 | 249 | # Colon-delimited sets of names that determine each other's naming style when 250 | # the name regexes allow several styles. 251 | name-group= 252 | 253 | # Regular expression which should only match function or class names that do 254 | # not require a docstring. 255 | no-docstring-rgx=^_ 256 | 257 | # List of decorators that produce properties, such as abc.abstractproperty. Add 258 | # to this list to register other decorators that produce valid properties. 259 | # These decorators are taken in consideration only for invalid-name. 260 | property-classes=abc.abstractproperty 261 | 262 | # Regular expression matching correct type variable names. If left empty, type 263 | # variable names will be checked with the set naming style. 264 | #typevar-rgx= 265 | 266 | # Naming style matching correct variable names. 267 | variable-naming-style=snake_case 268 | 269 | # Regular expression matching correct variable names. Overrides variable- 270 | # naming-style. If left empty, variable names will be checked with the set 271 | # naming style. 272 | #variable-rgx= 273 | 274 | 275 | [FORMAT] 276 | 277 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. 278 | expected-line-ending-format= 279 | 280 | # Regexp for a line that is allowed to be longer than the limit. 281 | ignore-long-lines=^\s*(# )??$ 282 | 283 | # Number of spaces of indent required inside a hanging or continued line. 284 | indent-after-paren=4 285 | 286 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 287 | # tab). 288 | indent-string=' ' 289 | 290 | # Maximum number of characters on a single line. 291 | max-line-length=100 292 | 293 | # Maximum number of lines in a module. 294 | max-module-lines=1000 295 | 296 | # Allow the body of a class to be on the same line as the declaration if body 297 | # contains single statement. 298 | single-line-class-stmt=no 299 | 300 | # Allow the body of an if to be on the same line as the test if there is no 301 | # else. 302 | single-line-if-stmt=no 303 | 304 | 305 | [LOGGING] 306 | 307 | # The type of string formatting that logging methods do. `old` means using % 308 | # formatting, `new` is for `{}` formatting. 309 | logging-format-style=old 310 | 311 | # Logging modules to check that the string format arguments are in logging 312 | # function parameter format. 313 | logging-modules=logging 314 | 315 | 316 | [MISCELLANEOUS] 317 | 318 | # List of note tags to take in consideration, separated by a comma. 319 | notes=FIXME, 320 | XXX, 321 | TODO 322 | 323 | # Regular expression of note tags to take in consideration. 324 | #notes-rgx= 325 | 326 | 327 | [SIMILARITIES] 328 | 329 | # Comments are removed from the similarity computation 330 | ignore-comments=yes 331 | 332 | # Docstrings are removed from the similarity computation 333 | ignore-docstrings=yes 334 | 335 | # Imports are removed from the similarity computation 336 | ignore-imports=no 337 | 338 | # Signatures are removed from the similarity computation 339 | ignore-signatures=no 340 | 341 | # Minimum lines number of a similarity. 342 | min-similarity-lines=4 343 | 344 | 345 | [SPELLING] 346 | 347 | # Limits count of emitted suggestions for spelling mistakes. 348 | max-spelling-suggestions=4 349 | 350 | # Spelling dictionary name. Available dictionaries: none. To make it work, 351 | # install the 'python-enchant' package. 352 | spelling-dict= 353 | 354 | # List of comma separated words that should be considered directives if they 355 | # appear and the beginning of a comment and should not be checked. 356 | spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: 357 | 358 | # List of comma separated words that should not be checked. 359 | spelling-ignore-words= 360 | 361 | # A path to a file that contains the private dictionary; one word per line. 362 | spelling-private-dict-file= 363 | 364 | # Tells whether to store unknown words to the private dictionary (see the 365 | # --spelling-private-dict-file option) instead of raising a message. 366 | spelling-store-unknown-words=no 367 | 368 | 369 | [STRING] 370 | 371 | # This flag controls whether inconsistent-quotes generates a warning when the 372 | # character used as a quote delimiter is used inconsistently within a module. 373 | check-quote-consistency=no 374 | 375 | # This flag controls whether the implicit-str-concat should generate a warning 376 | # on implicit string concatenation in sequences defined over several lines. 377 | check-str-concat-over-line-jumps=no 378 | 379 | 380 | [TYPECHECK] 381 | 382 | # List of decorators that produce context managers, such as 383 | # contextlib.contextmanager. Add to this list to register other decorators that 384 | # produce valid context managers. 385 | contextmanager-decorators=contextlib.contextmanager 386 | 387 | # List of members which are set dynamically and missed by pylint inference 388 | # system, and so shouldn't trigger E1101 when accessed. Python regular 389 | # expressions are accepted. 390 | generated-members= 391 | 392 | # Tells whether missing members accessed in mixin class should be ignored. A 393 | # class is considered mixin if its name matches the mixin-class-rgx option. 394 | ignore-mixin-members=yes 395 | 396 | # Tells whether to warn about missing members when the owner of the attribute 397 | # is inferred to be None. 398 | ignore-none=yes 399 | 400 | # This flag controls whether pylint should warn about no-member and similar 401 | # checks whenever an opaque object is returned when inferring. The inference 402 | # can return multiple potential results while evaluating a Python object, but 403 | # some branches might not be evaluated, which results in partial inference. In 404 | # that case, it might be useful to still emit no-member and other checks for 405 | # the rest of the inferred objects. 406 | ignore-on-opaque-inference=yes 407 | 408 | # List of class names for which member attributes should not be checked (useful 409 | # for classes with dynamically set attributes). This supports the use of 410 | # qualified names. 411 | ignored-classes=optparse.Values,thread._local,_thread._local 412 | 413 | # List of module names for which member attributes should not be checked 414 | # (useful for modules/projects where namespaces are manipulated during runtime 415 | # and thus existing member attributes cannot be deduced by static analysis). It 416 | # supports qualified module names, as well as Unix pattern matching. 417 | ignored-modules= 418 | 419 | # Show a hint with possible names when a member name was not found. The aspect 420 | # of finding the hint is based on edit distance. 421 | missing-member-hint=yes 422 | 423 | # The minimum edit distance a name should have in order to be considered a 424 | # similar match for a missing member name. 425 | missing-member-hint-distance=1 426 | 427 | # The total number of similar names that should be taken in consideration when 428 | # showing a hint for a missing member. 429 | missing-member-max-choices=1 430 | 431 | # Regex pattern to define which classes are considered mixins ignore-mixin- 432 | # members is set to 'yes' 433 | mixin-class-rgx=.*[Mm]ixin 434 | 435 | # List of decorators that change the signature of a decorated function. 436 | signature-mutators= 437 | 438 | 439 | [VARIABLES] 440 | 441 | # List of additional names supposed to be defined in builtins. Remember that 442 | # you should avoid defining new builtins when possible. 443 | additional-builtins= 444 | 445 | # Tells whether unused global variables should be treated as a violation. 446 | allow-global-unused-variables=yes 447 | 448 | # List of names allowed to shadow builtins 449 | allowed-redefined-builtins= 450 | 451 | # List of strings which can identify a callback function by name. A callback 452 | # name must start or end with one of those strings. 453 | callbacks=cb_, 454 | _cb 455 | 456 | # A regular expression matching the name of dummy variables (i.e. expected to 457 | # not be used). 458 | dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ 459 | 460 | # Argument names that match this expression will be ignored. Default to name 461 | # with leading underscore. 462 | ignored-argument-names=_.*|^ignored_|^unused_ 463 | 464 | # Tells whether we should check for unused import in __init__ files. 465 | init-import=no 466 | 467 | # List of qualified module names which can have objects that can redefine 468 | # builtins. 469 | redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io 470 | 471 | 472 | [CLASSES] 473 | 474 | # Warn about protected attribute access inside special methods 475 | check-protected-access-in-special-methods=no 476 | 477 | # List of method names used to declare (i.e. assign) instance attributes. 478 | defining-attr-methods=__init__, 479 | __new__, 480 | setUp, 481 | __post_init__ 482 | 483 | # List of member names, which should be excluded from the protected access 484 | # warning. 485 | exclude-protected=_asdict, 486 | _fields, 487 | _replace, 488 | _source, 489 | _make 490 | 491 | # List of valid names for the first argument in a class method. 492 | valid-classmethod-first-arg=cls 493 | 494 | # List of valid names for the first argument in a metaclass class method. 495 | valid-metaclass-classmethod-first-arg=cls 496 | 497 | 498 | [DESIGN] 499 | 500 | # List of regular expressions of class ancestor names to ignore when counting 501 | # public methods (see R0903) 502 | exclude-too-few-public-methods= 503 | 504 | # List of qualified class names to ignore when counting class parents (see 505 | # R0901) 506 | ignored-parents= 507 | 508 | # Maximum number of arguments for function / method. 509 | max-args=5 510 | 511 | # Maximum number of attributes for a class (see R0902). 512 | max-attributes=7 513 | 514 | # Maximum number of boolean expressions in an if statement (see R0916). 515 | max-bool-expr=5 516 | 517 | # Maximum number of branch for function / method body. 518 | max-branches=12 519 | 520 | # Maximum number of locals for function / method body. 521 | max-locals=15 522 | 523 | # Maximum number of parents for a class (see R0901). 524 | max-parents=7 525 | 526 | # Maximum number of public methods for a class (see R0904). 527 | max-public-methods=20 528 | 529 | # Maximum number of return / yield for function / method body. 530 | max-returns=6 531 | 532 | # Maximum number of statements in function / method body. 533 | max-statements=50 534 | 535 | # Minimum number of public methods for a class (see R0903). 536 | min-public-methods=2 537 | 538 | 539 | [IMPORTS] 540 | 541 | # List of modules that can be imported at any level, not just the top level 542 | # one. 543 | allow-any-import-level= 544 | 545 | # Allow wildcard imports from modules that define __all__. 546 | allow-wildcard-with-all=no 547 | 548 | # Analyse import fallback blocks. This can be used to support both Python 2 and 549 | # 3 compatible code, which means that the block might have code that exists 550 | # only in one or another interpreter, leading to false positives when analysed. 551 | analyse-fallback-blocks=no 552 | 553 | # Deprecated modules which should not be used, separated by a comma. 554 | deprecated-modules= 555 | 556 | # Output a graph (.gv or any supported image format) of external dependencies 557 | # to the given file (report RP0402 must not be disabled). 558 | ext-import-graph= 559 | 560 | # Output a graph (.gv or any supported image format) of all (i.e. internal and 561 | # external) dependencies to the given file (report RP0402 must not be 562 | # disabled). 563 | import-graph= 564 | 565 | # Output a graph (.gv or any supported image format) of internal dependencies 566 | # to the given file (report RP0402 must not be disabled). 567 | int-import-graph= 568 | 569 | # Force import order to recognize a module as part of the standard 570 | # compatibility libraries. 571 | known-standard-library= 572 | 573 | # Force import order to recognize a module as part of a third party library. 574 | known-third-party=enchant 575 | 576 | # Couples of modules and preferred modules, separated by a comma. 577 | preferred-modules= 578 | 579 | 580 | [EXCEPTIONS] 581 | 582 | # Exceptions that will emit a warning when being caught. Defaults to 583 | # "BaseException, Exception". 584 | overgeneral-exceptions=BaseException, 585 | Exception 586 | -------------------------------------------------------------------------------- /Content/Python/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.linting.pylintEnabled": true, 3 | "python.linting.enabled": true, 4 | "python.linting.flake8Enabled": false, 5 | "python.analysis.extraPaths": [ 6 | "../../../../Intermediate/PythonStub/" 7 | ], 8 | "python.autoComplete.extraPaths": [ 9 | "../../../../Intermediate/PythonStub/" 10 | ], 11 | } -------------------------------------------------------------------------------- /Content/Python/__pycache__/material_instance_tools.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Python/__pycache__/material_instance_tools.cpython-39.pyc -------------------------------------------------------------------------------- /Content/Python/__pycache__/material_tools.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Python/__pycache__/material_tools.cpython-39.pyc -------------------------------------------------------------------------------- /Content/Python/__pycache__/scoped_slow_task.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Python/__pycache__/scoped_slow_task.cpython-39.pyc -------------------------------------------------------------------------------- /Content/Python/material_instance_tools.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | 3 | 4 | def create_new_material_instance_asset(name, base_material_path): 5 | asset_tools = unreal.AssetToolsHelpers.get_asset_tools() 6 | material_instance = unreal.MaterialInstanceConstant() 7 | 8 | package_name, asset_name = asset_tools.create_unique_asset_name(name, '') 9 | if not unreal.EditorAssetLibrary.does_asset_exist(package_name): 10 | path = package_name.rsplit('/', 1)[0] 11 | name = package_name.rsplit('/', 1)[1] 12 | material_instance = asset_tools.create_asset(name, path, unreal.MaterialInstanceConstant, unreal.MaterialInstanceConstantFactoryNew()) 13 | else: 14 | material_instance = unreal.load_asset(package_name) 15 | 16 | base_material = unreal.EditorAssetLibrary.find_asset_data(base_material_path) 17 | unreal.MaterialEditingLibrary.set_material_instance_parent(material_instance, base_material.get_asset()) 18 | return material_instance 19 | 20 | suffix_to_parameter_map = { 21 | 'D': 'Albedo', 22 | 'M': 'Metalness', 23 | 'N': 'Normal', 24 | 'R': 'DR', 25 | } 26 | 27 | def create_material_instance_from_textures(name, base_material_path): 28 | if not base_material_path: 29 | # No path provided. Ask for the new base material. 30 | result, base_material_path = ask_for_base_material_path() 31 | if not result: 32 | # Operation canceled by user. 33 | return 34 | 35 | material_instance = create_new_material_instance_asset(name, base_material_path) 36 | 37 | selected_assets = unreal.EditorUtilityLibrary.get_selected_assets() 38 | for asset in selected_assets: 39 | if isinstance(asset, unreal.Texture): 40 | texture_name = asset.get_path_name() 41 | texture_suffix = texture_name.rsplit('_', 1)[1] 42 | if texture_suffix in suffix_to_parameter_map: 43 | parameter_name = suffix_to_parameter_map[texture_suffix] 44 | unreal.MaterialEditingLibrary.set_material_instance_texture_parameter_value(material_instance, parameter_name, asset) 45 | 46 | unreal.EditorAssetLibrary.save_asset(material_instance.get_path_name(), only_if_is_dirty = True) 47 | 48 | asset_tools = unreal.AssetToolsHelpers.get_asset_tools() 49 | asset_tools.open_editor_for_assets([material_instance]) 50 | 51 | 52 | def ask_for_base_material_path(): 53 | helper_type = unreal.load_class(None, '/UtilityToolkit/MaterialTools/BP_BaseMaterialSelectDialogHelper.BP_BaseMaterialSelectDialogHelper_C') 54 | 55 | base_material_select_dialog_helper = unreal.new_object(helper_type) 56 | options = unreal.EditorDialogLibraryObjectDetailsViewOptions(show_object_name = True, allow_search = True) 57 | result = unreal.EditorDialog.show_object_details_view("Select the base material", base_material_select_dialog_helper, options) 58 | 59 | base_material = base_material_select_dialog_helper.get_editor_property('Material') 60 | base_material_path = base_material.get_path_name() 61 | 62 | return result, base_material_path -------------------------------------------------------------------------------- /Content/Python/material_tools.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | 3 | 4 | ## 5 | # Actions to be performed on a per-texture basis 6 | ## 7 | 8 | # A base class for actions 9 | class Action: 10 | def execute(self, material, expression): 11 | pass 12 | 13 | # Adds a sampler and connects the desired output to the desired material property pin 14 | class CreateConnection(Action): 15 | def __init__(self, output_name, material_property): 16 | self.output_name = output_name 17 | self.material_property = material_property 18 | 19 | def execute(self, material, expression, y_pos): 20 | unreal.MaterialEditingLibrary.connect_material_property(expression, self.output_name, self.material_property) 21 | 22 | # Same as CreateConnection, but a Multiply node is also generated so the color value is scaled by the given factor 23 | class CreateConnectionScaled(CreateConnection): 24 | def __init__(self, output_name, material_property, scale): 25 | self.output_name = output_name 26 | self.material_property = material_property 27 | self.scale = scale 28 | 29 | def execute(self, material, expression, y_pos): 30 | multiply_node = unreal.MaterialEditingLibrary.create_material_expression(material, unreal.MaterialExpressionMultiply, -250, y_pos) 31 | multiply_node.set_editor_property('ConstB', self.scale) 32 | unreal.MaterialEditingLibrary.connect_material_expressions(expression, self.output_name, multiply_node, 'A') 33 | unreal.MaterialEditingLibrary.connect_material_property(multiply_node, '', self.material_property) 34 | 35 | # Sets any available property on the material asset 36 | class SetProperty(Action): 37 | def __init__(self, property, value): 38 | self.property = property 39 | self.value = value 40 | 41 | def execute(self, material, expression, y_pos): 42 | material.set_editor_property(self.property, self.value) 43 | 44 | # Sets the sampler type for the texture sample 45 | class SetSamplerType(Action): 46 | def __init__(self, sampler_type): 47 | self.sampler_type = sampler_type 48 | 49 | def execute(self, material, expression, y_pos): 50 | expression.set_editor_property('sampler_type', self.sampler_type) 51 | 52 | ## 53 | # This dictionary assigns the given texture type names (found in suffixes, for ex. T_TextureName_D - D means it's a Diffuse texture) 54 | # to the different actions that should be performed to properly set it up in the material. 55 | ## 56 | 57 | actions = { 58 | 'DA': [ 59 | CreateConnection('RGB', unreal.MaterialProperty.MP_BASE_COLOR), 60 | CreateConnection('A', unreal.MaterialProperty.MP_OPACITY), 61 | SetProperty('blend_mode', unreal.BlendMode.BLEND_TRANSLUCENT) 62 | ], 63 | 'D': [ 64 | CreateConnection('RGB', unreal.MaterialProperty.MP_BASE_COLOR) 65 | ], 66 | 'AO': [ 67 | CreateConnection('R', unreal.MaterialProperty.MP_AMBIENT_OCCLUSION), 68 | SetSamplerType(unreal.MaterialSamplerType.SAMPLERTYPE_MASKS) 69 | ], 70 | 'A': [ 71 | CreateConnection('R', unreal.MaterialProperty.MP_OPACITY), 72 | SetSamplerType(unreal.MaterialSamplerType.SAMPLERTYPE_GRAYSCALE), 73 | SetProperty('blend_mode', unreal.BlendMode.BLEND_TRANSLUCENT) 74 | ], 75 | 'N': [ 76 | CreateConnection('RGB', unreal.MaterialProperty.MP_NORMAL), 77 | SetSamplerType(unreal.MaterialSamplerType.SAMPLERTYPE_NORMAL) 78 | ], 79 | 'M': [ 80 | CreateConnection('R', unreal.MaterialProperty.MP_METALLIC), 81 | SetSamplerType(unreal.MaterialSamplerType.SAMPLERTYPE_MASKS) 82 | ], 83 | 'R': [ 84 | CreateConnection('G', unreal.MaterialProperty.MP_ROUGHNESS), 85 | SetSamplerType(unreal.MaterialSamplerType.SAMPLERTYPE_MASKS) 86 | ], 87 | 'S': [ 88 | CreateConnection('B', unreal.MaterialProperty.MP_SPECULAR), 89 | SetSamplerType(unreal.MaterialSamplerType.SAMPLERTYPE_MASKS) 90 | ], 91 | 'E': [ 92 | CreateConnectionScaled('RGB', unreal.MaterialProperty.MP_EMISSIVE_COLOR, 15) 93 | ], 94 | } 95 | 96 | ## 97 | # Helper functions 98 | ## 99 | 100 | # Create a material at a given path 101 | def create_empty_material(name) -> unreal.Material: 102 | asset_tools = unreal.AssetToolsHelpers.get_asset_tools() 103 | 104 | package_name, asset_name = asset_tools.create_unique_asset_name(name, '') 105 | if not unreal.EditorAssetLibrary.does_asset_exist(package_name): 106 | path = package_name.rsplit('/', 1)[0] 107 | name = package_name.rsplit('/', 1)[1] 108 | return asset_tools.create_asset(name, path, unreal.Material, unreal.MaterialFactoryNew()) 109 | return unreal.load_asset(package_name) 110 | 111 | # Perform actions defined in the 'actions' dictionary. This should result in textures being added properly with respect for required 112 | # or desired settings for certain texture types 113 | def apply_texture(material, texture_name, y_pos): 114 | sampler = unreal.MaterialEditingLibrary.create_material_expression(material, unreal.MaterialExpressionTextureSample, -500, y_pos) 115 | 116 | sampler.texture = unreal.load_asset(texture_name) 117 | texture_suffix = texture_name.rsplit('_', 1)[1] 118 | for key in actions: 119 | if key in texture_suffix: 120 | texture_suffix = texture_suffix.replace(key, '') 121 | for action in actions[key]: 122 | action.execute(material, sampler, y_pos) 123 | 124 | ## 125 | # Create material from selected textures 126 | ## 127 | 128 | def create_material_from_textures(name): 129 | material = create_empty_material(name) 130 | 131 | selected_assets = unreal.EditorUtilityLibrary.get_selected_assets() 132 | y_pos = 0 133 | for asset in selected_assets: 134 | if isinstance(asset, unreal.Texture): 135 | apply_texture(material, asset.get_path_name(), y_pos) 136 | y_pos += 250 137 | 138 | unreal.MaterialEditingLibrary.recompile_material(material) 139 | unreal.EditorAssetLibrary.save_asset(material.get_path_name(), only_if_is_dirty = True) 140 | 141 | asset_tools = unreal.AssetToolsHelpers.get_asset_tools() 142 | asset_tools.open_editor_for_assets([material]) 143 | -------------------------------------------------------------------------------- /Content/Python/scoped_slow_task.py: -------------------------------------------------------------------------------- 1 | import unreal 2 | import time 3 | import random 4 | 5 | 6 | ### make_dialog_delayed(delay, can_cancell=False, allow_in_pie=False) 7 | 8 | def scoped_slow_task_example(): 9 | items = unreal.EditorUtilityLibrary.get_selection_set() 10 | 11 | with unreal.ScopedSlowTask(len(items), 'Processing items') as task: 12 | task.make_dialog(True) 13 | 14 | processed_items = 0 15 | for item in items: 16 | if task.should_cancel(): 17 | show_cancel_confirmation_dialog() 18 | break 19 | 20 | task.enter_progress_frame(1, 'Processing {} ({}/{})'.format(item.get_actor_label(), processed_items, len(items))) 21 | 22 | # simulate long processing of the item 23 | time.sleep(random.uniform(0.1, 0.3)) 24 | processed_items += 1 25 | 26 | def nested_scoped_slow_task_example(): 27 | items = unreal.EditorUtilityLibrary.get_selection_set() 28 | 29 | with unreal.ScopedSlowTask(len(items), 'Processing items') as task: 30 | task.make_dialog(True) 31 | 32 | processed_items = 0 33 | for item in items: 34 | if task.should_cancel(): 35 | show_cancel_confirmation_dialog() 36 | break 37 | 38 | task.enter_progress_frame(1, 'Processing {} ({}/{})'.format(item.get_actor_label(), processed_items, len(items))) 39 | 40 | # simulate long processing of the item 41 | time.sleep(random.uniform(0.1, 0.3)) 42 | 43 | numbers_to_count = int(random.uniform(20, 50)) 44 | with unreal.ScopedSlowTask(numbers_to_count, 'Counting') as sub_task: 45 | sub_task.make_dialog(True) 46 | for current_number in range(0, numbers_to_count): 47 | if sub_task.should_cancel(): 48 | show_cancel_confirmation_dialog() 49 | return 50 | 51 | sub_task.enter_progress_frame(1, 'Counting {} of {}'.format(current_number, numbers_to_count)) 52 | 53 | # counting takes time 54 | time.sleep(random.uniform(0.05, 0.15)) 55 | 56 | processed_items += 1 57 | 58 | def show_cancel_confirmation_dialog(): 59 | unreal.EditorDialog.show_message('Operation canceled', 'Operation canceled by user', unreal.AppMsgType.OK, unreal.AppReturnType.OK) 60 | 61 | def ask_for_cancel_confirmation(): 62 | user_confirmation = unreal.EditorDialog.show_message( 63 | 'Are you sure?', 64 | 'Are you 100% positive you want to cancel?', 65 | unreal.AppMsgType.YES_NO_YES_ALL, 66 | unreal.AppReturnType.NO 67 | ) 68 | if user_confirmation == unreal.AppReturnType.YES: 69 | # cancel single item 70 | pass 71 | if user_confirmation == unreal.AppReturnType.YES_ALL: 72 | # cancell all items 73 | return 74 | -------------------------------------------------------------------------------- /Content/Viewport/BP_ViewportSceneCapture.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Viewport/BP_ViewportSceneCapture.uasset -------------------------------------------------------------------------------- /Content/Viewport/M_CameraMaterial.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Viewport/M_CameraMaterial.uasset -------------------------------------------------------------------------------- /Content/Viewport/M_Viewport.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Viewport/M_Viewport.uasset -------------------------------------------------------------------------------- /Content/Viewport/RT_Viewport.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Viewport/RT_Viewport.uasset -------------------------------------------------------------------------------- /Content/Viewport/WBP_Viewport.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Content/Viewport/WBP_Viewport.uasset -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daltongd/UtilityToolkit/6bb0705bb6da13b44cc3cc642c007aa44ef7a198/Resources/Icon128.png -------------------------------------------------------------------------------- /UtilityToolkit.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "UtilityToolkit", 6 | "Description": "", 7 | "Category": "Tools", 8 | "CreatedBy": "dalton", 9 | "CreatedByURL": "", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": true, 14 | "IsBetaVersion": false, 15 | "IsExperimentalVersion": false, 16 | "Installed": false 17 | } --------------------------------------------------------------------------------