He descubierto cómo hacer esto. Como esperaba, dado que IronPython compila a CLR, los objetos C # y IronPython pueden interactuar entre sí sin ningún tratamiento especial necesario. Creé un script que en realidad crea un nuevo tipo de Componente al que se puede hacer referencia muy bien desde C #.
Una breve palabra sobre la estructura de mi juego: su solución tiene dos proyectos: Game y GameEngine. El juego es lo que finalmente se compila en un EXE, y el GameEngine se compila en una DLL que se encuentra en el mismo directorio.
La secuencia de comandos
Actualmente se encuentra en el proyecto de contenido predeterminado, no tiene acción de compilación y se copia en el directorio de salida.
Tenga en cuenta que la clase Componente es parte de GameEngine y, por lo tanto, se compila en GameEngine.dll . Tampoco tiene nada que ver con la clase GameComponent de XNA y sus métodos no necesitan pasar un 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()
Cómo se compila y ejecuta el script
Solo una vez dentro del juego, ejecuto esto:
// 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);
Cuando se ejecuta el script, crea su propia instancia de un PyComponent.
Por supuesto, deberá hacer referencia a la biblioteca IronPython y al tiempo de ejecución dinámico de Microsoft. Descubrí que solo necesito estas cuatro DLL de la carpeta raíz de la descarga de IronPython:
- IronPython.dll
- IronPython.Modules.dll
- Microsoft.Dynamic.dll
- Microsoft.Scripting.dll
Agregue estas referencias a su proyecto, luego estas using
declaraciones a su código (de acuerdo con Embedded IronPython en una aplicación C # ):
using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
Obteniendo una referencia al objeto Python
No estoy seguro de cómo obtener una referencia directamente del script, pero tengo una forma indirecta de hacerlo. En el diseño de mi motor, todos los componentes se registran automáticamente con la colección de componentes del motor, por lo que puedo obtener una referencia al objeto a través de allí. En un caso más específico, puede hacer que los nuevos objetos de Python se registren con una cola en alguna parte, de modo que los cree y luego los recupere de inmediato.