python code suddenly stopped working

This code worked before and now it has stopped working.Why is that?Did something change in the bge?

import bge


cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = scene.objects ["player"]


obja = cont.owner
list = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]
length = len(list)


if obja.getDistanceTo(player) > 29:
    for i in range(0, length):
        obja = scene.addObject("lung", player, 0)
        obja.worldPosition = list[i]
                        

don’t use list as a variable. it is a native python keyword and using it as a variable might mess with stuff.

Okay i will try that.

Here is the error i get.Here is the blend file.

File "adders to", line 13, in <module>
ValueError: scene.addObject(object, reference, time): KX_Scene (first argument), requested name "lung" did not match any KX_GameObject in this scene
Python script error - object 'pla', controller 'Python':
Traceback (most recent call last):
  File "adders to", line 13, in <module>
ValueError: scene.addObject(object, reference, time): KX_Scene (first argument), requested name "lung" did not match any KX_GameObject in this scene
Blender Game Engine Finished

Attachments

adds vectoring.blend (489 KB)

well the only thing is:

requested name “lung” did not match any KX_GameObject in this scene

so the name is wrong, head to layer 2 select lung type lung again hit enter hit p to play it works. (maybe you wrote it with a white space behind it or something)

That worked but i have another problem.I have to put positive on the logic brick.But it keeps spawning it then.But I would like it to spawn the lungs once.

Please be patient with me but I do not get what this code is supposed to do.

What do you mean with “put positive in the logic brick”?

What do you mean with “put positive in the logic brick”?

the brick connected to the python brick (true pulse)

As the script is you don’t need true pulse, but i suggest you got more then that.
easiest way is to work with a property, so don’t spawn right away but check a property first(this example: Boolean), if that is true or false.

So if false you did not spawn anything so you add the lung and set the property to true. now it wont spawn anymore of them, until you put the property to false again.


prop = own['boolean_property']
if not prop:
    # add lung
    own['boolean_property'] = True

cotax=
The script did not work without positive pulse.
Monster=
The script supposed to add odd shaped boxes called lung at different vector positions.

Have you resolved your problems? Make a positive pulse run your code, and follow what cotax said about creating a property. That should work I think.

I did try that but the framerate constantly goes down with this script with positive pulse.I am just assumming it is constantly adding the lung boxes.

import bge




cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = scene.objects ["player"]




obja = cont.owner
list = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]
length = len(list)




if obja.getDistanceTo(player) > 29:
    for i in range(0, length):
        
     prop = own['boolean_property'] 
       if not prop:
       obja = scene.addObject("lung", player, 0)
        obja.worldPosition = list[i]
           own['boolean_property'] = True

flying2.blend (409 KB)

Sorry i posted wrong blend.Here is the blend.adds vectoring.blend (423 KB)

A couple pointers:

  • You’re using the wrong file - use Text.001.
  • Do not assign obja (which is your owner == obja) to be the object you add ( obja = scene.addObject(“lung”, player, 0) ). Otherwise, you will invite weird behavior.
  • Try to fix your formatting. Every ‘for’ loop and ‘if’ check deserves a tab for each statement that comes after it, and is part of that condition (if they haven’t been misbehaving haha)
  • When you implement cotax’s solution, you actually need to do:
if "prop" not in obja:
obja["prop"] = "anyVariableIWantToUse"

The idea here is initially, obja doesn’t have the property called prop. But by doing

obja["prop"] = "anyVariableIWantToUse"

You are making that property exist. And a property is just like when you create a game property for an object. Warning: you cannot do obja[“prop”] = “anyVariableIWantToUse” without checking that prop exists first. Otherwise, you’ll get a “doesn’t exist” type error.

  • Keep the positive trigger going with these fixes.

Other pointers for your programming:

  • What I like to do is use the print statement to log out how many and what my code is executing. If you see
    the console’s sidebar constantly descend, for example, then you know code is being executed rather frequently
    for where you have the print statement.
  • Include comments in your code (always a good habit) so you can keep track of where you are.

Looks like good progress.


import bge




cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = scene.objects ["player"]




obja = cont.owner
list = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]
length = len(list)


prop = obja['boolean_property'] 


if not prop and obja.getDistanceTo(player) > 29:


    for i in range(0, length):      
       obja = scene.addObject("lung", player, 0)
       obja.worldPosition = list[i]
    
    obja['boolean_property'] = True  

This works, notice that logic and raster goes crazy, so put your long as a no collision, or set the right physics type.
it ads a bunch then it stops, so it does what you want it to do.

#edit
also the property on the empty need to set to false, the script will turn it to true

I would recommend to create a custom sensor (checking the distances) and a custom actuator (adding the objects).

Unfortunetly the BGE does not allow to create any of them (a mysterium since I know the BGE). This is a perfect example where we need it as we get a processing conflict (constant checking sensor vs. one frame running actuator).

Cotax showed you an example how to behave like a sensor by storing the last evaluation status. (I recomend to give the proeprty a more meaningful name e.g. “last evaluation status” or “was in range” or “was positive”).

Additionally accessing by “get()” allows you to use an internal property (no need to create it via GUI).

General Custom Sensor
A basic “mimicry” of a sensor could look like that (it includes the controller part assuming there is no additional sensor to check):


import bge

INTERNAL_PROPERTY_LAST_EVALUATION_STATUS = "last status"

currentStatus = evaluate() # call your custom evaluation

lastStatus = owner.get(INTERNAL_PROPERTY_LAST_EVALUATION_STATUS)
owner[INTERNAL_PROPERTY_LAST_EVALUATION_STATUS] = currentStatus 

if currentStatus:
    if isTrueLevelTriggering() or currentStatus != lastStatus:
        activateAllActuators() 
else: 
    if isFalseLevelTriggering() or currentStatus != lastStatus:
        deactivateAllActuators() 


This sample does not include the details of isTrueLevelTriggering(), isFalseLevelTriggering, activateAllActuators(), deactivateAllActuators() I guess you see what it is meant to do.

evaluate() should perform your evaluation check resulting in True or False as this are the only results that are possible.

Applied to your situation
Translated to your situation your code might look like this (including the actuator part):


import bge


INTERNAL_PROPERTY_LAST_EVALUATION_STATUS = "last status"

owner = bge.logic.getCurrentController().owner
player = owner.scene.objects["player"]

#evaluate 
currentStatus = owner.getDistanceTo(player) > 29

lastStatus = owner.get(INTERNAL_PROPERTY_LAST_EVALUATION_STATUS)

#store current status to be used within hte next frame
owner[INTERNAL_PROPERTY_LAST_EVALUATION_STATUS] = currentStatus 

if currentStatus and currentStatus != lastStatus:
    # behave like sensor without pulse mode
    # do your thing when the sensor just went positive
    positions = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]

    reference = player # it might maybe better to use owner as reference rather than player
    for i in range(0, len(positions)):      
        addedLung = reference.scene.addObject("lung", reference, 0)
        addedLung.worldPosition = positions[i]
 

What does it do?

  1. it grabs the objects that are needed for evaluation
  2. it evaluates if the distance between the owner and the player are above 29
  3. it checks if the evaluation is True and the evaluation of the previous frame differs (must be False)
    3A) if so … add the objects
    3B) otherwise no further processing

I hope you notice this code snippet does not look for True or False level triggering. I assume you do not want it configurable. Therefore this configuration is hard-coded by skipping according checks. This belongs to False evaluation too (3B).

With build-in sensors
Alternatively you can use a near sensor. This way you need the “controller” and “actuator part” only:


import bge

#controller part
controller = bge.logic.getCurrentController()
sensor = controller.sensors[0]

if sensor.positive:

    #actuator part
    owner = controller.owner
    player = owner.scene.objects["player"]

    positions = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]

    reference = player # it might maybe better use owner as reference
    for i in range(0, len(positions)):      
        addedLung = reference.scene.addObject("lung", reference, 0)
        addedLung.worldPosition = positions[i]

I hope you see the “actuator part” is the same as above. Here you do not need to worry about the sensor processing as the build-in sensor already does everything for your.

Indeed both methods can be mixed e.g. when you want to perform custom evaluation and build.in sensor together. I guess these are more details as you want to know right now ;).

[edit]

Small mistake in the above code:


addedLung = scene.addObject("lung", reference, 0) 

must be


addedLung = reference.scene.addObject("lung", reference, 0) 

(otherwise Python will complain that ‘scene’ is not present)

But i wanted it to add one for each vector position cotex.

But i wanted it to add one for each vector position cotex.

it does exactly what you want the script to do, remember you are loping trough the list, so for every list entry it places one.

Cotax your script did not work.So you are saying it worked for you.I do not know what is going on if that is the case.
Here is the blend.

Attachments

vector plan.blend (953 KB)

you dont have true pulse on, and you using it on other objects so the error in the console says owner is not defined, i see i used own, you use owner, it needs to be obja.
so change it to obja and it works, but you still doing something wrong, due to logic gets crazy after it.

Now that i read your code better no wonder, you use obja as owner and as a variable, thats not the way to do things, keep the owner seperate like own = cont.owner then you can call the added object obja.

so use this code(tested and working), and put true pulse on.


import bge


cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = scene.objects ["player"]


own = cont.owner


list = [[3,4,5],[2,2,2],[1,1,1],[3,3,3],[8,8,8],[10,10,10]]


prop = own['boolean_property'] 


if not prop and own.getDistanceTo(player) > 29:


    for i in range(len(list)):   
           
       obja = scene.addObject("lung", player, 0)
       obja.worldPosition = list[i]
    
    own['boolean_property'] = True

You can use the code I posted in “Applied to your situation” as it is now.

  1. Copy and paste the text into your “adding those lungs” script.
  2. Do not forget to enable True Level Triggering on the sensor.

then test it.