Ho capito come farlo. Come mi aspettavo, dal momento che IronPython si compila fino a CLR, gli oggetti C # e IronPython possono interagire tra loro bene senza alcun trattamento speciale necessario. Ho creato uno script che in realtà crea un nuovo tipo di componente che può essere referenziato bene da C #.
Una breve parola sulla struttura del mio gioco: la sua soluzione ha due progetti: Game e GameEngine. Il gioco è ciò che alla fine viene compilato in un EXE e GameEngine viene compilato in una DLL che si trova nella stessa directory.
Il copione
Attualmente si trova nel progetto di contenuto predefinito, non ha azioni di compilazione e viene copiato nella directory di output.
Nota che la classe Component fa parte di GameEngine e quindi viene compilata in GameEngine.dll . Inoltre non ha nulla a che fare con la classe GameComponent di XNA e i suoi metodi non hanno bisogno di passare un oggetto 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()
Come viene compilato ed eseguito lo script
Solo una volta all'interno del gioco, eseguo questo:
// 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 lo script viene eseguito, crea la propria istanza di un PyComponent.
Ovviamente dovrai fare riferimento alla libreria IronPython e al runtime Microsoft Dynamic. Ho scoperto che ho solo bisogno di queste quattro DLL dalla cartella principale del download IronPython:
- IronPython.dll
- IronPython.Modules.dll
- Microsoft.Dynamic.dll
- Microsoft.Scripting.dll
Aggiungi questi riferimenti al tuo progetto, quindi queste using
istruzioni al tuo codice (secondo Embedding IronPython in un'applicazione C # ):
using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
Ottenere un riferimento all'oggetto Python
Non sono sicuro di come ottenere un riferimento direttamente dalla sceneggiatura, ma ho un modo rotatorio per farlo. Nella mia progettazione del motore, tutti i componenti si registrano automaticamente con la raccolta dei componenti del motore, in modo da poter ottenere un riferimento all'oggetto da lì. In un caso più specifico, potresti semplicemente far registrare nuovi oggetti Python con una coda da qualche parte, quindi li crei e poi li recuperi immediatamente.