yet another addObject question ;)

    I have the object I am spawning on a separate layer from what I read  that is correct, but I am having errors that the key is not in the  list...double checked names and everything. Can anyone maybe see  something I do not?

I am using UPBGE…don’t know if there is a depreciation or code change etc…

here is the error.
KeyError: “CList[key]: ‘‘breadcrumb’’ key not in list” I assume it thinks there is no object with that name

and the code I used below.


import bge  
def main():

  cont = bge.logic.getCurrentController()
own = cont.owner
scene = bge.logic.getCurrentScene()

node = scene.objects['breadcrumb']
life_time = 480#8 seconds??? ;)
#scene.addObject(object,loc,duration) *duration is in frames
if own['nodeSpawnTimer'] >= 5 and own['nodeCount'] <= 20:
    scene.addObject(node,own.worldPosition, life_time)
    own['nodeCount'] += 1
    own['nodeSpawnTimer'] = 0  main()


FORMATING IS NOT THIS MESSED UP.

EDIT: this worked
node = scene.objectsInactive[“name”]
but
node = scene.addObjects[‘name’]
did not?..anyway resolved

A good way to debug is to do something like:
print(scene.objects)

Then you’ll notice that the node object isn’t actually within your scene, only the visible objects are. To add objects from other layers you will have to use scene.addObject() and this WILL allow you access the objects that aren’t in the current scene (on separate layers).

To keep a reference:
myobj = scene.addObject(params)
myobj.worldposition = something

I see, I got that confused and the object is indeed on another layer…I’ve seen some of your vids :)…good stuff thanks for the response. I will test a few things with this knowledge.

wait…I am using scene.addObjects() and the object exists in the second layer…I am still having the error…I will do some more testing in a simpler scene and come back.

node = scene.objectsInactive[“name”]

if you are having issues with:

node = “Name”

also, own.worldPosition is not necessary. just use own.

i have no idea what the main() is all about, but its wrong.



import bge
def main():cont = bge.logic.getCurrentController()
own = cont.owner
scene = bge.logic.getCurrentScene()

node_name = "breadcrumb"
life_time = 8*60
if own["nodeSpawnTimer"] >= 5 and own["nodeCount"] <= 20:

[INDENT=2]node = scene.addObject(node_name,own,life_time)
owner["nodeCount"] += 1
owner["nodeSpawnTimer"] = 0
[/INDENT]

main()


I did change it to use “own”…I threw this together quickly and just assumed it would be a no brainer…quite easy…but those are the things that seem to trip me up…simple mistakes…

the issue with main() is the formatting on the forum…my code formatting looks nothing like that above…indentations alon would never let it run…but we all know that :wink:

I will test the objectsinactive();
thanks.

Yep, that was it apparently…now I just need to play with the rest, thanks everyone.

This should give you a different error.

addObject is a function and needs () rather than

The point of “main” is … it has no point. It is a copy of a copy of a copy of someone who thought it is professional to write code that looks like basic or c or so.

It has no meaning in the context of the BGE (or Python) and makes the code less readable as nobody knows what a “main” is, or what the code should do (pretty much the same as calling a variable “variable”, a class “class”, a function “function” or a human “human”).

Within a BGE script it forces a reader to jump down and up in the code as you need to ignore the function in the first stage, scroll down and than scroll up again. This makes the code harder to read.

Btw. within the context of Python the code is:


<b>if</b> __name__ == "__main__":
    # execute only if run as a script

see Python Documentation. It does not apply to the BGE (unless you write scripts that run in script and in module mode).

@Monster: I agree calling it “main” is arbitrary…I would call main a function in which I would call other functions and it would generally be the loop…speaking of I have another question but maybe I should explain it better what I am trying to do…

I am “trying”(tinkering) to create a semi dynamic follow the player script…path following where the npc, if cannot see the player can see the nodes and test which one can see both the npc and the player *but the closest to the player and move toward it until it either sees the player or a closer node…I am trying to check in a simple “for i in scene.objects” if i is the breadcrumb test etc…
The problem I have now is I am not seeing the object in the list,( I have a simple print(“node”) to test) …and I do not want to confuse it with the object it is instanced from(on another layer). Does anyone know a simple straightforward way to do this, or am I just doing something stupid? :slight_smile:

SIGH, I got it working I do not know why it did not before, but I am getting some strange error that my ‘import bge’ does not exist? it is intermittent and happens even with a new script(from the bge simple template). curious.

EDIT: here is the error.

ImportError: No module named ‘bge’

and I am using UPBGE 1.8…don’t know if anyone else has gotten this error?
I need to check main branch to see if it is something I have done.

Sounds like you click the [run script] button.

It should be executed from a python controller (script or module mode).

thanks monster, I just figured it out…it had something to do with live edit mode in the scripts options…odd.

I’m still having problems…a never ending fight…

the nodes are working, created and deleted and the enemy casts to the player(from head and foot positions)…
I then proceed to see if they are returning the player. If not, I cycle through the nodes and do a raycast to see if they see the player…

I’m having the problem though that they are only casting from the oldest node…how do I force it to cycle through them?
I am already doing it in a loop…I assumed it would just cycle through all of them, but that is not the case.

I would need to see some code for more details.

Just now I suggest you print the list you loop over to console and check if it is the way you expect it to be.

I will report back tomorrow, just stopped by to see if someone had some direct insight…need to get the kids to bed etc…so tomorrow I will post some code.

ok, I started from scratch because it was turning into a spagetti monster, but here is the basis of the code…I took out the check to look for ‘breadcrumb’ in the list and it cycles through just fine…too well…clearly it cycles through every visible object :wink:

before this I simply check if nodes are created
if ‘breadcrumb’ in objList:
then I do a raycast to see if the enemy sees the player…if not I execute the next piece of script below…for me that was fairly tough without a lot of python experience, but fairly straightforward

 currNode = objList[own['node_index']]
           own['node_index'] = (own['node_index'] + 1) % len(objList)
           nextNode = objList[own['node_index']]

           noderay = own.rayCast(player_vec, nextNode.worldPosition, 100, '', 0, 0, 0)#by lowering the raydistance it will help to keep the checks lower range
           bge.render.drawLine(nextNode.worldPosition,player_vec,(1,0,0.0))

so the only issue I have is that I cannot check before to see if the object is ‘breadcrumb’ since it just stops cycling at the first object with that name. Any clever ideas.

I rushed to find the answer without really thinking…
this code works…for obvious reasons…

 
currNode = objList[own['node_index']]
own['node_index'] = (own['node_index'] + 1) % len(objList)
nextNode = objList[own['node_index']]

if nextNode == objList['breadcrumb']:
    noderay = own.rayCast(player_vec, nextNode.worldPosition, 100, '', 0, 0, 0)
    bge.render.drawLine(nextNode.worldPosition,player_vec,(1,0,0.0))

I was wrong, it still only traces from the first object with that name…damn…oh well…if no one has an answer I may just live with it…

I gave up on that, it does not cost any more resources really since it will only cast a short distance and only be doing one cast at a time.
So I marked this as solved.