Как я могу общаться с компонентом IronPython в игре C # / XNA?

8

Моя игра XNA является компонентно-ориентированной и имеет различные компоненты для позиционирования, представления физики, рендеринга и т. Д., Которые расширяют базовый Componentкласс. У игрока и врагов также есть контроллеры, которые в настоящее время определены в C #. Я хотел бы превратить их в скрипты Python через IronPython (реализация Python для .NET). Моя проблема в том, что я не уверен, как взаимодействовать с этими скриптами.

Примеры встраивания IronPython в приложение C # предполагают, что мне придется создать что-то вроде компонента Script, который компилирует скрипт Python и вызывает метод Update контроллера через Python - по сути, это был бы класс-оболочка для C # для взаимодействия с Python ,

Я чувствую, что мне чего-то не хватает в моих исследованиях. Там должна быть способом , чтобы загрузить сценарий, экземпляр объекта Python (либо в сценарии Python или в C #) , а затем то есть прямая ссылка на этот объект Python в моих C # код.

Есть ли способ работать с объектом IronPython напрямую , или требуется оболочка?

doppelgreener
источник

Ответы:

7

Я понял, как это сделать. Как я и ожидал, поскольку IronPython компилируется в CLR, объекты C # и IronPython могут нормально взаимодействовать друг с другом без специальной обработки. Я создал скрипт, который на самом деле создает новый тип компонента, на который можно просто ссылаться из C #.

Краткое описание структуры моей игры: в ее решении два проекта: Game и GameEngine. Game - это то, что в конечном итоге компилируется в EXE, а GameEngine компилируется в DLL, которая находится в той же директории.

Сценарий

В настоящее время он находится в проекте контента по умолчанию, не выполняет никаких действий по сборке и копируется в выходной каталог.

Обратите внимание, что класс Component является частью GameEngine и поэтому скомпилирован в GameEngine.dll . Он также не имеет ничего общего с классом XNA GameComponent, и его методам не нужно передавать объект 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()

Как скрипт компилируется и запускается

Только один раз в игре я запускаю это:

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

Когда скрипт выполняется, он создает свой собственный экземпляр PyComponent.

Конечно, вам нужно сослаться на библиотеку IronPython и среду выполнения Microsoft Dynamic. Я обнаружил, что мне нужны только эти четыре библиотеки DLL из корневой папки загрузки IronPython:

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

Добавьте эти ссылки в ваш проект, а затем эти usingутверждения в ваш код (в соответствии с Embedded IronPython в приложении C # ):

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

Получение ссылки на объект Python

Я не уверен, как получить ссылку непосредственно из сценария, но у меня есть обходной способ сделать это. В моем проекте движка все компоненты автоматически регистрируются в коллекции компонентов движка, поэтому я могу получить ссылку на объект через него. В более конкретном случае вы могли бы просто сделать так, чтобы новые объекты Python регистрировались где-то в очереди, поэтому вы создаете их, а затем немедленно получаете их.

doppelgreener
источник
Мое последнее обновление к этому посту будет, когда я пойму, как напрямую получить ссылку на объект python.
doppelgreener