Bagaimana cara saya berkomunikasi dengan komponen IronPython di game C # / XNA?

8

Game XNA saya berorientasi pada komponen , dan memiliki berbagai komponen untuk posisi, representasi fisika, rendering, dll, yang semuanya memperluas Componentkelas dasar . Pemain dan musuh juga memiliki pengontrol yang saat ini didefinisikan dalam C #. Saya ingin mengubahnya menjadi skrip Python melalui IronPython (implementasi .NET dari Python). Masalah saya adalah saya tidak yakin bagaimana berinteraksi dengan skrip-skrip itu.

Contoh di Embedding IronPython di C # Aplikasi menyarankan saya harus membuat sesuatu seperti komponen Script yang mengkompilasi skrip Python dan memanggil metode Pembaruan controller melalui Python - pada dasarnya, itu akan menjadi kelas pembungkus untuk C # untuk berinteraksi dengan Python .

Saya merasa bahwa saya kehilangan sesuatu dalam penelitian saya. Ada harus menjadi cara untuk memuat naskah, instantiate objek Python (baik dalam script Python atau C #) dan kemudian kemudian memiliki langsung mengacu bahwa objek Python di C # kode.

Apakah ada cara untuk bekerja dengan objek IronPython secara langsung , atau diperlukan pembungkus?

doppelgreener
sumber

Jawaban:

7

Saya sudah menemukan cara untuk melakukan ini. Seperti yang saya harapkan, karena IronPython mengkompilasi ke CLR, objek C # dan IronPython dapat berinteraksi satu sama lain dengan baik tanpa memerlukan perawatan khusus. Saya telah membuat skrip yang benar-benar membuat tipe baru Komponen yang dapat direferensikan dengan baik dari C #.

Sebuah kata singkat tentang struktur permainan saya: Solusinya memiliki dua proyek: Game, dan GameEngine. Game adalah apa yang akhirnya dikompilasi menjadi EXE, dan GameEngine dikompilasi ke dalam DLL yang berada di direktori yang sama.

Naskah

Saat ini duduk di proyek konten default, tidak memiliki tindakan membangun dan disalin ke direktori output.

Perhatikan bahwa kelas Komponen adalah bagian dari GameEngine, dan dikompilasi ke dalam GameEngine.dll . Ini juga tidak ada hubungannya dengan kelas GameComponent XNA dan metodenya tidak perlu melewati objek 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()

Bagaimana skrip dikompilasi dan dijalankan

Sekali saja dalam permainan, saya menjalankan ini:

// 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);

Ketika skrip dieksekusi, ia membuat turunannya sendiri dari sebuah PyComponent.

Tentu saja Anda harus merujuk pustaka IronPython dan runtime Microsoft Dynamic. Saya telah menemukan bahwa saya hanya memerlukan keempat DLL ini dari folder root unduhan IronPython:

  • IronPython.dll
  • IronPython.Modules.dll
  • Microsoft.Dynamic.dll
  • Microsoft.Scripting.dll

Tambahkan referensi ini ke proyek Anda, lalu usingpernyataan ini ke kode Anda (sesuai dengan Embedding IronPython dalam Aplikasi C # ):

using IronPython.Hosting;
using IronPython.Runtime;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;

Memperoleh referensi ke objek Python

Saya tidak yakin bagaimana saya akan mendapatkan referensi langsung dari skrip, tetapi saya memiliki cara bundaran untuk melakukan itu. Dalam desain mesin saya, semua komponen secara otomatis mendaftarkan diri mereka ke koleksi komponen mesin, jadi saya bisa mendapatkan referensi ke objek melalui sana. Dalam kasus yang lebih spesifik, Anda bisa meminta objek Python baru mendaftarkan diri dengan antrian di suatu tempat, sehingga Anda membuatnya dan kemudian segera mengambilnya.

doppelgreener
sumber
Pembaruan terakhir saya untuk posting ini adalah ketika saya mencari cara untuk mendapatkan referensi langsung ke objek python.
doppelgreener