Class inheritance error

Hello Blenderartists.
I have a class which i want to inherit the attributes of a GameObject. This worked.
However, when i attempt to pass another attribute to the init function, it doesn’t work, and mentions “pyObjectplus” in the error console.
Any ideas?
http://www.pasteall.org/27112

Well, I don’t know if we’re actually supposed to inherit from KX_GameObject; the documentation for that type doesn’t specify initialization arguments, even though it seems to work … sort of.

I’m guessing there’s some special work going on behind the scenes, where it doesn’t really function like a typical python inheritance case, so here, you don’t call init yourself, instead it’s the responsibility of the engine (this is my best guess).

So, in a few tests I managed to run, I didn’t even have to call the parent constructor (which, by the way, would usually be called “bge.types.KX_GameObject.init(self, object)” - note the self in front, or, the more modern approach: “super().init(object)”).

I think you could just create an additional method, called “initialize” or something like that, and instance your objects like this:


my_object = MyObject(cont.owner)
my_object.initialize(arg1, arg2, arg3, etc)

You’re going to have some trouble inheriting it directly. What I did to get around this was to create a class that ‘pushed’ all the method calls and attribute access for a KX_GameObject onto a referenced object.

http://code.google.com/p/novus-terra-code/source/browse/trunk/src/entities/entity_base.py

What you want to have a look at is the _wrap method, which binds all the game object functions to the class (the _unwrap function isn’t necessary, we use it because we pickle the class) and the getattr and setattr methods which push all the attribute access onto the game object.

I use the inspect module to grab all the attributes and methods of KX_GameObject so I know what to push and what not to. Since getattr and setattr are overriden you can’t really store any attributes on the class, to get around this I created a Container class to store all the attributes.

You can create the init method to look something like this:

def __init__(self, name):
    self._data = bge.logic.getCurrentScene().addObject(name, bge.logic.getCurrentController().owner)

That way creating objects becomes:

player = EntityBase('player')

Its quite hacky, but once you’ve coded it you can inherit the class, all the messy stuff is tucked away and everything works nicely.

(Note that I hard coded the object property access, the inspect module didn’t pick those up)

Inheritance as a concept builds on that the base class object is created when the child object is created. If You want to reference a already existent object from Your class You should use aggregation - simply give Your server class a attributed ‘own’ referencing the game object and access the game object through that attribute.

You can, as andrew-101 point out, make Your class a proxy for the game object. That might look elegant but it is also confusing. Might have it’s uses but generally I recommend against it.