Closed antirotor closed 4 years ago
So far I've made progress in project support code. This is included in lib.py
but should be handled by config and is there mainly for reference. How do we do it in pype now: just before unreal editor is launched on specific task, hook is called and checks if there is Unreal project in AVALON_WORKDIR
. If not, it creates one using create_unreal_project()
and prepare_project()
in lib. Those two functions:
Plugins/Avalon
directory and copy there Avalon integration plugin sourcesSource
directory and create there bunch of C# and C++ files to allow Unreal Build Tool to kick in and compile Avalon Integration plugin and project modules.This is because of Avalon Integration plugin distribution as source code. Overhead of compiling and distributing plugin binaries is shifted to the user :)
Project name in Unreal must be less then 20 characters and must not start with non-alpha character as its name is used inside Unreal code as variable name in multiple places.
I don't like the idea of writing this hardcoded source code from python, but I wasn't able to find other way. There can possibly be way to run some Unreal generator creating those files in more safe way.
There are few caveats so far:
Unreal needs Visual Studio to work
This is because of Avalon Integration plugin distribution as source code. Overhead of compiling and distributing plugin binaries is shifted to the user :)
I don't know what's industry standard practice, but I know in our indie game division, artist don't have visual studio installed on their computers. The only person I know for certain that has visual studio installed is the leader programmer as he compiles the builds.
True, but from Avalon point of view it shouldn't matter. That code in lib is there mainly for reference and how you create and setup project is on avalon config implementation. In Pype I did it so you have options to either point with preset to compiled plugins so project won't need compilation or point to the sources. I agree that with visual studio it is mainly for development but can be useful until unreal implementation in avalon is stabilized.
So I've tweaked code in lib.py
a little bit so C++ project gets created only if Binaries
and Intermediate
folders are not present in installed plugins. So if we provide compiled binaries for running Unreal Engine version then normal project get created and that doesn't need Visual Studio installed.
I've made more changes:
Unreal doesn't have concept of groups or sets in its Content Browser, assets there are organized in folder structure. Unfortunately we cannot add metadata to these directories.
So I've made two new Blueprint classes - AvalonContainer and AvalonPublishInstance. They are almost same. They are created by avalon in containerise()
or other places at the folder grouping assets. For example - we have family Prop consisting of static mesh Foo and its material Bar. Selecting those and clicking Create ... -> Prop
will move them from wherever they are to /Game/modelingPropFoo
(or whatever it's subset name is) and under it it will create instance of AvalonPublishInstance
:
/Game/modelingPropFoo
/modelingPropFoo (AvalonPublishIntance)
/Foo (StaticMesh)
/Bar (Material)
It will imprint metadata on AvalonPublishInstance
- and that is whats returned by ls()
. There is also functionality implemented in both Blueprint classes to track all assets under directory where instance of this class is, so modelingPropFoo
will have live list of assets under /Game/modelingPropFoo
. This is right now just shotcut because unreal api has ability to list assets at some path, but its foundation for later more advanced usage.
We can color code directories in Content Browser to help visualize types of Avalon containers or publish instances. With few caveats I am afraid - setting color will have visible result only after Unreal Editor is restared as this information is written into project config ini file. I couldn't find a way to "refresh" it.
Most of the code reflect changes in antirotor/avalon-unreal-integration. Note that we'll move this repository to pypeclub/avalon-unreal-integration.
Still need more work and testing.
This is now in basic working state. Here is a little bit of documentation take from my Pype PR note. As Pype is now fully opensourced, you can see details about Pypes parts there but note that no code here has any dependency in Pype. Avalon bits are identical, project generation code is there also, the only difference is that in Pype there is example implementation of creators and loaders and demo pipeline for exporting static meshes from Maya. I apologize for all those Pype references but as it is quite a long text I didn't have enough energy to edit it 😩
You need to compile Unreal Editor Avalon Integration plugin for your Unreal Engine version. For that you need Microsoft Visual Studio 2017 (Community Edition is 👌 ). You can either compile it manually, or just clone it somewhere and then set AVALON_UNREAL_PLUGIN
to point there. This can also be set in pypeclub/pype-config in environments/unreal_4.24.json
on line 2. Then during Unreal project creation when starting Unreal from ftrack task, Pype will detect presence of Binaries
and Intemediate
folders in plugin directory at AVALON_UNREAL_PLUGIN
. If found, they will be copied to new project then and Visual Studio is not needed. Otherwise project will be set as C++ project and it will compile everything during first launch.
It will automatically enable required plugins PythonScriptPlugin and EditorScriptingUtilities.
Implementation is multi-part. Avalon Core part implements support for loading, creating, managing and publishing instances. Pype part takes care of project setup, Unreal launching and basic pipeline for publishing StaticMesh from Maya and loading, managing and creating publish instance in Unreal.Avalon Integration Plugin is enabling Avalon in Unreal - it provides menu to control avalon functionality and provides other support functions for bridging Unreal and Avalon. And finally pype-config is providing basic support for creating correct environment.
:warning: Python Scripting in Unreal Editor is still VERY experimental indeed. Things can (and probably should) change |
---|
This is C++ and Python code connecting Unreal Python API and Avalon Core API. Unreal doesn't support creation of new main menu items from Python so this plugin is defining new Blueprint class doing just that. Callback functions for this menu are implemented in Python part (in Content/Python/init_unreal.py
) and they themselves are referencing corresponding functions in avalon-core host integration.
This plugin is also providing two "container" BP classes - AssetContainer
and AvalonPublishInstance
container. Reason behind those two is that you cannot add metadata to folders in Unreal Editor Content Browser - and that is the only way to group assets together there.
So loading stuff from avalon will create folder with subset name, put content in it and also create AssetContainer
class asset there to hold metadata.
There are two reasons for this: first, it holds metadata on it needed for Avalon to keep track of assets and second - it helps to easily find this container. Unreal project can have thousands of assets and iterating through them can be time consuming. But finding assets of only specific class type is much faster.
Those two classes tracks all changes in directory they reside in and provide live list of assets they are "containing" for script or Blueprint use.
This plugin is also exposing some C++ API not available yet in Python API, implemented as UAvalonLib
in C++ and AvalonHelpers
in Python. There is currently only one function - set_folder_color()
that can be used to set folder colors 😄 that can be normally done from UI. Caveat is that for color change take place, editor must be restarted.
As work in Unreal Editor is quite different then in other DCCs there must be different approach to its support. In Unreal, there are no work scenes as files. Instead we work directly in self-contained project folder. So running Unreal Editor in specific context must include environment setup, project management and Unreal Engine version support.
Pype can autodetect installed Unreal Engine versions (at least on Windows). You can then choose per project/task what version you wish to use. This is done by enabling corresponding Avalon application in ftrack.
When launching Unreal Editor for given context, project must be prepared before Engine itself is run:
AVALON_UNREAL_PLUGIN
location. If Binaries and Intermediate are present (plugin was compiled) than simple project is created. Otherwise project is set as C++ project and will try to compile itself on Editor launch. For that you'll need Visual Studio 2017install_unreal_python_engine
, it will also install and enable Unreal Engine Python. It will be pulled from PYPE_UNREAL_ENGINE_PYTHON_PLUGIN
and if that is missing than it will be cloned with git from github. For that, you'll need git installed and in PATH and also Visual Studio 2017 to compile it.⚠️ Unreal Python Engine: This plugin may not support latest Unreal Engine versions |
---|
📔 You can also trigger C++ project by setting dev_mode in presets |
---|
This is pre-launch hook file of Pype preparing Unreal project before launch. It is using same functions as they are in project.py
in this PR:
This includes basic support of Static Meshes pipeline. You can create and publish Static Meshes from Maya and load them into Unreal. There is simple validation for correct naming and checking for world orientation etc. This is not by far complete pipeline and serves as demonstration for implementing other, more advanced stuff.
This implements necessary host specific API in Avalon Core to support it and its tools. Mainly creating containers, imprinting them with data and discovering them.
pip
Just wanted to say great work on this!
This has been contaminated by Pype. I'll close this one and I'll make another PR with vanilla Avalon Core.
This is implementation of #498.
Introduction
Unreal Engine can be used for many different things from its obvious use in game development to render/previz tool in movie production. Its architecture is somehow different then in most common DCCs where we work within project directory holding relevant stuff and using scene files that produce publishable output like models, renders, etc. As Unreal is first of all game engine, project is more interlinked then just bunch of directories and scene files doesn't exists at all. Instead we have levels and those can be considered as possible versioned scene files. I suppose that most common use of Unreal will be in context of sequence/episode or game itself containing all assets under it - in movie, every unreal level can be scene in sequence or even shot.
Implementation
This is DRAFT pull request to allow discussion about particular implementation details.
Setup
Unreal has no way to create main menu entries with Python. For that I've created plugin that creates basic Avalon menu entries and I am referencing it in this code. This plugin calls c++ methods on class and those are overridden during Unreal startup in python
Content/Python/init_unreal.py
https://github.com/antirotor/avalon-unreal-integration/blob/f21b2f4830559cf33cb68e766f2c1d93a2c4291e/Content/Python/init_unreal.py#L8
Those methods should call relevant code from this integration to show Avalon dialogs, etc.
So far I've implemented functions in
lib
to find installed Unreal Engines and to create projects. Those projects in Unreal are set of directories and.uproject
file that is actually a JSON file. In this file, we can specify what built-in and external plugins our project will use so I took opportunity and placed there code to enable Python plugin and also install (copy it to new project directory) Avalon Integration plugin if found on setAVALON_UNREAL_PLUGIN
env variable. This could be extended in future to make use of TOOLS and other stuff specified in configs.Work to be done
Containers
Find out how to containerize assets loaded in Unreal. This can be done in three ways:
Unreal supports creating arbitrary metadata on each asset with Python. This looks to me like the most promising way. Other possible ways would be our own
UActor
descendant class wrapping imported assets, or perhaps adding Blueprint component to assets holding information?Functions to show dialogs
As mentioned above, we need functions to be called from integration plugin to show dialogs, but those should be easy enought to implement.
Workio
I am quite not sure what to do with workio part as there is no scene file nor ability to open one. Perhaps work with levels can be tweakend into existing workio api.
Note, this is still non-functional and heavy in development.