Problem with Spawning Objects and their Script

Hey Guys,

I tried to do a little Tower defense Game, but faced a Problem while Spawning enemys. The first one does as it should, the second one (Same object, same logic bricks, same script) doesn’t and produces following error:

BlockquotePython script error - object ‘enemy.001’, controller ‘Python’:
Traceback (most recent call last):
File “C:\Users\x\Desktop\tower defense.blend\enemy.py”, line 53, in main
File “C:\Users\x\Desktop\tower defense.blend\enemy.py”, line 25, in state_normal
ValueError: Steering not in this python controllers actuator list

Does somebody know what is wrong and how i can fix it?

Since i cannot upload a file right now heres my code for the enemy.

from bge import logic, events, types

#Sensoren und Aktuatoren verfügbar machen
cont = logic.getCurrentController()
scene = logic.getCurrentScene()
#obj = cont.owner
own = cont.owner
path = cont.actuators["Steering"]
assign = cont.actuators["assign"]
end = cont.actuators["end"]

class Enemy(types.KX_GameObject):

    def __init__(self,own):
        
        self.holder = None
        self.cont = logic.getCurrentController()
        #print(self.cont.actuators)
        self.main = self.state_normal
        
        
    #states
    def state_normal(self):
        #cont = logic.getCurrentController() 
        self.cont.activate(path)
        pass
    
    def state_gehalten(self):
        cont.deactivate(path)
        cont.activate(assign)
        
    def state_kill(self):
        cont.activate(end)
    
    def kill(self):
        self.main = self.state_kill
        
    def halten(self, holder):
        self.holder = holder
        self.main = self.state_gehalten
        
    def get_holder(self):
        return self.holder

        
def main(cont):
    cont = logic.getCurrentController()
    own = cont.owner
    if not "init" in own: #hier alles rein was nur einmal ausgeführt werden soll
        own["init"] = True
        own = Enemy(own)

    own.main()

Thanks for your help (and mind my english, its not my mother tongue)

Gerrit

you are missing the actuators.

also if multiple objects you should use module mode, the actuators in this case only getting executed once in total not per object

Thanks for your answer.
The actuators schouldn’t be missing, cause they are in the object.
The script is in module mode (the main function is called) und triggered by an always with true level triggering.

There hast to be some problem with the script itself.Can i force the actuators to beexecuted per object? or is there any other possibility, without writing a new script for every new object?

This is not in module mode or within the class, so this code only getting executed once

here:

from bge import logic, events, types

class Enemy(types.KX_GameObject):
    
    cont = logic.getCurrentController()
    
    path = cont.actuators["Steering"]
    assign = cont.actuators["assign"]
    end = cont.actuators["end"]

    def __init__(self,own):
        
        self.holder = None
        self.cont = logic.getCurrentController()
        #print(self.cont.actuators)
        self.main = self.state_normal
        
        
    #states
    def state_normal(self):
        #cont = logic.getCurrentController() 
        self.cont.activate(path)
        pass
    
    def state_gehalten(self):
        cont.deactivate(path)
        cont.activate(assign)
        
    def state_kill(self):
        cont.activate(end)
    
    def kill(self):
        self.main = self.state_kill
        
    def halten(self, holder):
        self.holder = holder
        self.main = self.state_gehalten
        
    def get_holder(self):
        return self.holder

        
def main(cont):
    #using cont in a function already gives you the controller, no need to add it again
    own = cont.owner
    
    if not "init" in own: #hier alles rein was nur einmal ausgeführt werden soll
        own["init"] = True
        own = Enemy(own)

#always-> python -module-> scriptname.main
#is the proper way to run in module mode, what you had is just running in scripting mode

#edit
made a small mistake haha, placed it in the actual location where you use it else it had no function at all.

First of all, thanks for your help!

Second: it doesn’t work :smiley:

If i put the variables declaration in the class, the script always tells me “variable cont not defined” (or similar).

Maybe this is just a thing not possible in the blender game engine.

I’m no hero with classes haha but one thing i can say is you do

self.cont = blabla
so you actually have the controller so:

self.cont.actuators["Steering"]
or
self.actuators["Steering"]
should do the trick

i’m not sure if you can save the sesnors within the object it self, else you could add it into the init state. (same thing you have at state_normal)

subclassing the game object is iffy at best. i would say avoid doing this.

The error message tells you that your current controller does not have an actuator named “Steering”.

Usually this message is pretty right. So the cotnroller the BGE is currently looking at and the controller you think you look at are mostlikely not the same.

To verify that I suggest to add a print statment at the place right before the error raises. The stack tells you it is line 25 in function state_normal.

So add:

print(self.cont.owner.name + '.' + self.cont.name + ' has follwing connected actuators: '+ self.cont.actuators)

and check if your assumptions match what the BGE sees.