Lilttle trouble with for loop.

import bge 

cont = bge.logic.getCurrentController()
own = cont.owner
vm=bge.logic.globalDict


scene=bge.logic.getCurrentScene()
obs=scene.objects


hair_m = obs["Hair1"]  
top_m = obs["Top1"] 
bot_m = obs["Bot1"]  






h_list = [1,2,3,4,5,6,7,8,9,10]






hair_i_want = vm['hair-id']
top_i_want = vm['top-id']
bot_i_want = vm['bot-id']
#shoe_i_want = vm['shoe-id']


for h in list:
    if hair_i_want == h:
        hair_string = "Hair" + str(h)
        hair_obj = own.scene.objectsInactive[hair_string]
        hair_m.replaceMesh(str(hair_obj))
        
        
for t in list:
    if top_i_want == t:
        top_string = "Top" + str(t)
        top_obj = own.scene.objectsInactive[top_string]
        top_m.replaceMesh(str(top_obj)) 
        
for b in list:
    if bot_i_want == b:
        bot_string = "Bot" + str(b)
        bot_obj = own.scene.objectsInactive[bot_string]
        bot_m.replaceMesh(str(bot_obj))        


        

Hi everyone. i would like to ask if there is a way to fix this script. It should replace those hair,top,bot meshes. The script works, everything can be replaced but only when i start with the hair mesh first. How could i make those for loops independent from each other?

Thanks

Usually you replace a mesh with another mesh. Therefore it would be a good idea to use mesh names rather than object names.

You might assume that the object name and the mesh name match. I suggest to check if that is true.

Beside of that your code has quite a lot of cryptic names. That reduces readability quite a lot.

Ah, now that I see it like this, I’m pretty sure you’ve got the loop in the wrong place.

You can use a loop if you have several characters who needed different clothes, or several types of outfit that needed changing at once. If you give your dummy clothes a property such as “shoes” and name the different kinds of shoes’ meshes as “shoes1”, “shoes2” etc…

If you are careful about what you save in the globalDict you can choose individual clothes:

bge.logic.globalDict = {"hair":1,
         "shoes":4,
         "hat":12,
         "skirt":1,
         "ribbon":3,
         "sunglasses":4}

We loop through the keys of the dictionary, getting the dictionary contents for each and using that along with the key to replace the mesh.

import bge 

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

for item_key in bge.logic.globalDict:
         item_number = str(clothing_dictionary[item_key])
         item_object = [ob for ob in own.scene.objects if ob.get(item_key)][0] 
     # be careful, script will fail if there's no objects with a property matching item_key
         item_object.replaceMesh(item_key + item_number)

Then you only need one function for every piece of clothing, and you can add more items to the globalDict, as long as you make sure they are available as objects and meshes in your game.

thanks Monster

Yes those are all same. Each object in my game has its mesh name like its object name.


for # in list:

You haven’t defined list! Maybe that is the problem? You have h_list, but not list!

thanks smoking mirror

i think i would use these lines… but i am still confused with how to replace these values. Alright i have vm[‘hair-id’] which is always a changeable value from other scene. The scene with the clothes will get that value and execute the changing. Could you please help me to apply it to the code? thanks

import bge

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

for item_key in bge.logic.globalDict:
item_number = str(clothing_dictionary[item_key])
item_object = [ob for ob in own.scene.objects if ob.get(item_key)][0]
# be careful, script will fail if there’s no objects with a property matching item_key
item_object.replaceMesh(item_key + item_number)

Have you tried my reccomendation to use:


for h in h_list:

isntead of:


for h in list:

?
Because it looks like there doesn’t exist anything that is called list in your code!

thanks adriansnetlis

i have this line h_list = [1,2,3,4,5,6,7,8,9,10]
the script i added in the first part of the topic works ,without giving any weird error in toggle console. but it kinda has a hierarchy with it. I can only change the bottom after changing the top, and the top also, after changing the hair.

Maybe use def modules for each of the loops so you can execute them seperately?

o.o how can i apply it to the script?

Firstly, as adrian points out, you’re trying to iterate over the list type (list), rather than a list instance. The list type is not iterable, so that will fail. I recommend looking at the Python console for more information on this. When scripts fail to work correctly, that’s your debug output window.

Secondly, your script module is bound to one object, so I would recommend moving to module mode.
Thirdly, you don’t need a for loop here. You’re just allowing the user to replace the hair with an input variable.[

import bge 


def _replace_item(item, new_id, item_prefix):    
    mesh_name = "{}{}".format(item_prefix, new_id)
    item.replaceMesh(mesh_name)


def _any_positive(cont):
    for sens in cont.sensors:
        if sens.positive:
            return True
    
    return False


def update_hair(cont):
    if not _any_positive(cont):
        return
    
    own = cont.owner
    scene = own.scene
    
    hair_m = scene.objects["Hair1"]  
    top_m = scene.objects["Top1"] 
    bot_m = scene.objects["Bot1"]  

    hair_i_want = logic.globalDict['hair-id']
    top_i_want = logic.globalDict['top-id']
    bot_i_want = logic.globalDict['bot-id']
    #shoe_i_want = logic.globalDict['shoe-id']
    
    _replace_item(hair_m, hair_i_want, "Hair")
    _replace_item(top_m, top_i_want, "Top")
    _replace_item(bot_m, bot_i_want, "Bot")

thanks agoose77, should i just connect the module to an always sensor and name it as replace.replace_item right?

The script doesnt give any weird arrow when i wrote in module field.

test.replace_item

Only this phrase is found:"test.replace_item’ takes 3 args, should be zero or 1 controller arg. Nothing is changed while vm values change.

I think yo uwas supposed to use the update_hair module:D

When i replace the name to test.update_hair , it gives something like this

AtributeError: ‘module’ object has no attritbute ‘update_hair’

I made some mistakes, but the module is still there. Try the updated code.

thanks agoose, hm it still gives some mistakes like this


(KANYA module is just a broken script, i just deleted it)

Doesn’t it have to use update_hair? Use it, because _replace_mesh is used for update_hair! It takes 3 args that you later set in update_hair! Maybe just reaqd the code deep and figure out it’s structure;) So in controller use: test.update_hair

thanks adriansnetlis, but i answered to this in the reply above

The reason I used an underscore is to explicitly point out it’s a private (not-to-be-used) module!

The problem you have is that test.py already exists inside Python stdlib. Rename your module to something else, and then use the update_hair method.

thanks agoose, i did change it

now it gives a problem in line 18

if not any_positive(cont):

‘any_positive’ is not defined, is there something missing ?