#lish
Having chatted with @mrobbins, this thread is about the porting of Pyblish to C# - hence the name - for use with Unity and the C# APIs of Maya and 3ds Max.
Introduction
The entirety of Pyblish - base library, integrations, graphical user interfaces and more - is written in Python. For use with C# we’ll need a version of pyblish-base
written in C#.
At the end of this journey, I expect a fully functional port of pyblish-base, running alongside the pyblish-qml GUI.
Why?
Both Unity, Maya and 3ds Max grant access to their APIs via Python, so why bother with C#?
In the case of Unity, the Python API is both unofficial and exposed via IronPython - a C# implementation of Python. It lacks aspects of Python currently used in pyblish-base
, although at this time it is uncertain what and how much - for example the dependency six
won’t import successfully.
Porting Pyblish to C# then would expose the entirety of Unity’s API to Pyblish plug-in developers.
The benefits of C# in Maya and 3ds Max are yet to be investigated, although at first glance they seem more performant. I’d imagine that if a shop it Unity based, they may have more developers writing C# and have most of their code base written in it as well, favouring a single language across all content creation software they use.
Where else is C# favourable?
What do we need?
We have a few challenges ahead of us, but if we start small and work our way up I’m certain we’ll succeed. For starters, if we can find a way to port this snippet, we’d be well on our way.
Knowing little about C#, I’ll provide a step-by-step guide on core functionality as we go, assuming it can do nothing of what Python does and work our way towards full feature paridy.
We will need:
- Functions
- Functions that take arguments
- Passing functions as arguments
- Functions that can take functions are arguments
- A key:value, dictionary/map type object, e.g.
{"hello": "world"}
- A list/array type object, e.g.
[1, 2, 3]
def process(Plugin, instance):
"""Process plugin, and produce result"""
Plugin(instance)
return {
"plugin": Plugin,
"instance": instance,
}
def publish(plugins, context):
"""Primary publishing mechanism"""
for Plugin in plugins:
for instance in context:
process(Plugin, instance)
def Plugin1(instance):
"""An InstancePlugin"""
print("Plugin1 ran")
plugins = [Plugin1]
context = list()
instance = list()
context.append(instance)
publish(plugins, context)
Development
For starters, you are invited to share snippets of code right here in this thread. We can test out our code directly via a C# development environment, or via Docker like this.
$ cd path/to/script.cs
$ docker run -ti --rm -v $(pwd):/csharp ubuntu
$ apt-get install -y mono-complete
$ mono script.cs
mono
is the C# equivalent to python
, and script.cs
is our script. This will be a live connection, so as you save your C# script locally, re-run mono script.cs
to run it.