[SOLVED] Linked object with addobject script?

Greetings. I am just having a minor issue where I made a torch -prop that has a script to spawn flame from layer2. When I Link it in to the game level the flame itself stays in the middle of the main level world (coordinates zero). Exactly where it is in the prop file on layer 2.

Even though the script mentions it should spawn on the empty that is in the tip or the torch.

Should I be more specific in the script on where to spawn the actual flame object?


import bge
import random
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
own = cont.owner
light = scene.objects["light"]

def particles():
    particle = scene.addObject("flame", "Empty", 0)
    particle.applyMovement((random.uniform(-0.02, 0.02), random.uniform(-0.02, 0.02), 0), True)
    light.energy = random.uniform(0.5, 1.0)

if own["on"] == True:
    particles()


EDIT: I just realised it could also be an issue wich the grouping? I have all the torch, light, flame, empty in the same group and it’s Linked to the game level. Does this make also the layer 2 spawning object to be constantly visible?

Attachments

prop_torch.blend (1.16 MB)

this may or may not work, but you should try adding Empty = scene.objects[‘Empty’] and the remove the quotation marks around the Empty in the addObject line, how does it work now?

Edit:

i downloaded your.blend and had some trouble with it freezing, but i was able to see something, it appears to me that everything is working as it should, I’m taking it was bothering you how your flame spawns is sorta inside your torch? That’s just because when you add the object, its origin goes to the empty’s location, so you could either go to your flame and change its origin so its at the bottom or move the empty until it looks right to you

The AddObjectActuator needs the game object to copy from (template object) inactive (which means it resides at an hidden layer).
If this requirement is not met, you see the just template object at it’s own location. At a flame it usually means you see exactly one particle.

If you instanciate a group all instance objects are placed at the layer of the instantiating object. That means the template object is at an active layer as well. To make it work you need two groups: one with the templates one with the emitters (the game objects that add the new game objects).

KX_scene.addObject() can use active objects as template object as well.
This means the above requirement is not your problem.

From your question I guess to situations:
A) the flame plays an location action
B) the flame is added at (0,0,0) which means the emitter is there.

Now I will have a look at your blend to see if any of my guesses are true ;).

I can’t see you group instantiated at all. Being part of a group is usually ignored by the BGE. So this is not the problem.

When starting your file I can see a few particles at the top of the torch. But the BGE crashed pretty fast.
Luckily I can slow down the execution with my FBF-Debugger.

It can see one particle at (0,0,0). I guess this is your template particle. It seems it performs the same logic as the other particles. When it ends Blender crashes. I guess because you try to add an object that does not exist.

This is one of the reasons because I recommend to keep the templates inactive (at an inactive layer). The other reason is that they are easier to identify.

Solution: make sure your template particle is not visible and does not end.

Monster

Edit: nevermind, the reason it was crashing was because you had the hidden layer set visible lol, but anyway, if you change the flames origin or the empty’s location, you can get the flame to appear in the spot you want it to, good luck :smiley:

very cool! (can grab it ? :slight_smile: )

as say Monster, it crash when you try to add the flame.

the problem happen when the “original” is destroyed , and you try to add flame, all copy of flame have need to the original . (i have examinated this crash some time ago…)
keep EVER the obj to spawn in a layer not visible (no visible = no destroyable)

in your case just select only the layer [1] (or deselect the [2])

very cool :slight_smile:

PS:this bug is very easy to solve !!! there some reason to keep this crap?

Oh yes, sorry I saved the file while both layers were selected so it should work alright if the main level is only selected. Thank you for the tips and solutions will look in to them!

Oh and sure grab it if you wish. I will use that prop in my game but sure you can take it :slight_smile:

  1. Make sure layer one is only selected.
  2. I still have an issue if I want to Link this prop in to another blend file (game level). I am not sure how should I bring it in (as a group or…?) to keep it working so that the flame particle would spawn right from layer 2.

thanks for the “grab” :wink:

to have a good references , you can use the list of children (of the torch) instead to using the list of the scene.
in fact in a game you can have many obj with the same name .(overall “Empty”)

while if you call the “Empty” as children (from the torch obj) return “that Empty” , not another .

just change a some word in the script torch:

from :


import bge
import random
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
own = cont.owner
light = scene.objects["light"]

def particles():
    particle = scene.addObject("flame", "Empty", 0)
    particle.applyMovement((random.uniform(-0.02, 0.02), random.uniform(-0.02, 0.02), 0), True)
    light.energy = random.uniform(0.5, 1.0)

if own["on"] == True:
    particles()


to:


import bge
import random
cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
own = cont.owner
light = own.children["light"]
empty = own.children["Empty"]

def particles():
    particle = scene.addObject("flame", empty, 0)
    particle.applyMovement((random.uniform(-0.02, 0.02), random.uniform(-0.02, 0.02), 0), True)
    light.energy = random.uniform(0.5, 1.0)

if own["on"] == True:
    particles()


particle = scene.addObject(“flame”, “Empty”, 0)
particle = scene.addObject(“flame”, own.children[“Empty”], 0)

note the difference in this two line …if not there obj duplicated return the same obj , if instead there obj duplicated cn return two references different
for thath is better not using the “string” in the second argument , but a ID of one obj…

tell me if not work

Monster, little question:

when you use multiple blend , there issue with the name of the obj and the script?

“main.py” (current script internal in the game1.blend)

give conflict with
“main.py” imported from game2.blend ?

or there some system of autorenaming?
(now i read also your pdf)

That is the reason why you should never never never use such generic names.

Always use names that describe the purpose. As a side effect you easily discover if you write the same module twice ;).

In general linking python files can lead to such problems. This can be solved by saving the Python files externally and use the module mode. If a python file is internal and external the internal one is ignored.

ehh, i know :wink:
(my question was a bit off topic, i mean for libLoad , not group instances , my mistake)

It does not matter, where the Python code comes from. A good organization (with a consistent naming convention) is essential for a good design :wink:

Damn. Thank you everyone for your aid. I got it to work now. This is why like this forum or you guys :slight_smile: