New object instances and assigning them properties

Hey I’ve got this bit of code where I add a group of units into the scene at the same time. i need them to enter the scene with the same property[‘team’] as the player. So I’ve written this.

if lmb.positive:
for i in cont.actuators:
i.object = unit[‘unit’]
i.instantAddObject()
new_unit = i.objectLastCreated
new_unit[‘team’] = player[‘team’]

the dude’s get made but the last line where it is supposed to assign teams never happens. Now looking at it, it doesn’t seem like the right way so a nudge in the right direction would be sweet.

Thanks

That ladt line should work. However I have noticed that sometimes setting properties the frame an object is created sometimes doesn’t work unless the property already exists in he object (ie from blenders ui)

Otherwise, try using the python methods for adding objects (scene.addObject)

You should use

 tags when you post code to preserve indentation - indentation matters a lot, especially in cases like this. For example, if this was your code:


if lmb.positive:

for i in cont.actuators:

    i.object = unit['unit']

    i.instantAddObject()

new_unit = i.objectLastCreated

new_unit['team'] = player['team']


Then new_unit would only point to the last add object actuator (and so, only the last one would have its team property assigned to). I'd go with the scene.addObject() approach, though - it automatically returns a reference to the added object.


cont = logic.getCurrentController()
obj = cont.owner
sce = obj.scene

if lmb.positive:

new_unit = sce.addObject(unit['unit'], obj)  # In this line, obj is the object creating the unit
new_unit['team'] = player['team']

You can also do this if you only need to reference the object once:


cont = logic.getCurrentController()
obj = cont.owner
sce = obj.scene

if lmb.positive:

    sce.addObject(unit['unit'], obj)['team'] = player['team']


Thanks for the heads up guys

so my current format was

I
if lmb.positive:
    for i in cont.actuators:
        i.object = unit['unit']
        i.instantAddObject()
        new_unit = i.objectLastCreated
        new_unit['team'] = player['team']

Now the cont.actuators part is because I have five different empties that the units need to spawn in

could I just use a for look for the addobject code you guys used the same way?


if 'Spawn' not in own:
     own['Spawn']=[]
     for item in scene.objects:
         if 'SpawnPoint' in item:
             own['Spawn']+=[item]

will generate the list for you just add the property SpawnPoint to your spawns.

Best not to add lists to lists unless it’s actually necessary (i.e you want to make a new list consisting of the members of N (N > 1) other lists.

Here, it’s more efficient and obvious that you want to append these elements to a list. Furthermore, it can be done in a single statement
try:
spawn_points = own[‘spawn_points’]
except KeyError:
spawn_points = [o for o in scene.objects if ‘SpawnPoint’ in o]
own[‘spawn_points’] = spawn_points

do something with spawn_points



Otherwise, exactly this. Might be useful to demonstrate a blend file though - the logic bricks should function as required.

Yeah, you can use a for loop to loop through the five empties and spawn the unit at that position. You just have to get those references to those empties and use them.

My apologies for being a dunderhead but I’ve been trying to re-work your guy’s approach into the system and all I’ve gotten is errors. The most pervasive is when I use addObject it accuses me of trying to add an object that isn’t in an inactive layer which from what I can see is libel and treacherous lies.

above should be the blend file if any of yall are bored and wouldn’t mind giving it a peek that’d be fantastic :confused:

at this point you should be able to just move your mouse and left click where you want to place the squad of guys. then do the same thing for the mech. The goal is for them to enter the battlefield and then receive the same team property value as the player object

Also the object with the code on it is the cone called placer

Also why can’t you just call scenes in the scene list by name?! Sorry non sequitur

Sorry, forgot to pack it :confused:

My favourite BA quote, thus far.
A number of things need to be addressed here.
Firstly, you’re setting the team on the group instance, not on the members it contains. You need to set the groupMembers’ team value instead, i.e


player_team = player['team']
for obj in unit.groupMembers:
    obj['team'] = player_team

You also don’t seem to set this for squads at the moment… Is this intentional?

Your logic profile results indicate a lot of performance heavy operations are going on. This is far too great for what is actually going on. Game AI should barely register on the logic scale per unit, if it’s relatively conventional FSM stuff.
I would advise the following:

  1. Convert your script based code to use python module mode.
  2. Use these changes to catch exceptions and return from the function, catching specific errors if they’re expected, but not handling others, so they’re seen in the console.

One example of this is the placer script which doesn’t check if the minimap wasn’t found. Better to fail directly at the source of the issue, rather than consequentially, later on.


def place_unit(cont):
    # ....
    minimap = logic.getSceneList['Mini_map'] # This will fail if it doesn't exist

It might also be advisable to consider if you really need to use the mutation feature of KX_GameObjects. I don’t use it these days, because I find it error prone (makes more sense to separate the logic from the physical object, as you can then handle cleanup without the engine doing it silently).
If you wish to use it, the need should be clear, such as giving units methods. There’s little point using it if you’re still going to use module based methods.

I would probably have a logic manager if i was going to use mutated classes (i.e the added units wouldn’t have logic bricks).

Haha. Thanks for the heads up. I didn’t realize that I was trying to give the group a property instead of the actual object. I fixed it like this


def add_unit():
    if logic.unit['squad'] == True:
        for i in cont.actuators:
             i.object = logic.unit['unit']
             i.instantAddObject()
            
             new = i.objectLastCreated.groupMembers
             for ob in new:
                ob['team'] = player['team']

I also didn’t know .groupMembers was a thing.

Pardon my extreme inexperience, I am a product of learning python via Youtube videos.

As far as setting for squads, I wouldn’t know how.

As for the rest of your suggestions. I am highly thankful for them and as soon as I figure out what all that stuff you said meant I will get right on it!

Btw How do you mark these as solved? When I go to tools it’s not in the options :confused:

open first post, go advanced, then go to top - prefix -> solved.

Thanks mate. That is not very obvious.

Also I know this isn’t the place for suggestions but it would be sweet if we could upvote peoples responses so instead of having to write “ditto to what guy above said” I could just throw an upvote and the thread would be sorted by highest voted response kind of like Stack Overflow or reddit etc. :confused:

It’d be nice to highlight the post which solved the issue – done in many forums. Having threaded posts would be nice for readability, finding content and easily sorting data, but old forum hags would hate it, because human beings don’t like change. :wink: