Eu descobri como fazer isso. Como eu esperava, como o IronPython é compilado até o CLR, os objetos C # e IronPython podem interagir um com o outro, sem nenhum tratamento especial necessário. Eu criei um script que realmente cria um novo tipo de componente que pode ser referenciado muito bem em C #.
Uma breve palavra sobre a estrutura do meu jogo: Sua solução tem dois projetos: Game e GameEngine. O jogo é o que é compilado em um EXE e o GameEngine é compilado em uma DLL que fica no mesmo diretório.
O script
Atualmente, ele fica no projeto de conteúdo padrão, não tem ação de construção e é copiado para o diretório de saída.
Observe que a classe Component faz parte do GameEngine e, portanto, é compilada no GameEngine.dll . Ele também não tem nada a ver com a classe GameComponent do XNA e seus métodos não precisam receber um objeto GameTime.
import clr
clr.AddReferenceToFileAndPath("GameEngine.dll")
from GameEngine import *
# or: from GameEngine import Component
class PyComponent(Component):
def __new__(self):
Component.__new__(self)
def Initialize(self):
pass
def Update(self):
pass
def Draw(self):
pass
pc = PyComponent()
Como o script é compilado e executado
Apenas uma vez dentro do jogo, eu corro o seguinte:
// Engine setup stuff. The scope can work with variables in the script by
// adding references, accessing/removing current references, etc.
// Each script COULD have its own scope but I have no reason to do that yet.
ScriptEngine PythonEngine = Python.CreateEngine();
ScriptScope DefaultScope = PythonEngine.CreateScope();
string filename = @"Content\ScriptTest.py";
ScriptSource script = PythonEngine.CreateScriptSourceFromFile(filename, Encoding.ASCII);
script.Execute(scope);
Quando o script é executado, ele cria sua própria instância de um PyComponent.
Obviamente, você precisará fazer referência à biblioteca IronPython e ao Microsoft Dynamic runtime. Descobri que só preciso dessas quatro DLLs da pasta raiz do download do IronPython:
- IronPython.dll
- IronPython.Modules.dll
- Microsoft.Dynamic.dll
- Microsoft.Scripting.dll
Adicione essas referências ao seu projeto e, em seguida, essas using
instruções ao seu código (de acordo com a Incorporação do IronPython em um aplicativo C # ):
using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
Obtendo uma referência ao objeto Python
Não sei como obter uma referência diretamente do script, mas tenho uma maneira indireta de fazer isso. No design do meu mecanismo, todos os componentes se registram automaticamente na coleção de componentes do mecanismo, para que eu possa obter uma referência ao objeto por lá. Em um caso mais específico, você pode simplesmente fazer com que novos objetos Python se registrem em uma fila em algum lugar, para criá-los e recuperá-los imediatamente.