python position vector problem

Why does not this add the cube to both position vectors?Only the first if statement works.
Here is the python code i used.

import bge


def main():






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




    sens = cont.sensors['mySensor']
    actu = cont.actuators['myActuator']
    if obj.getDistanceTo(player) > 29:
      obj = scene.addObject("lung", player, 0)
      obj.worldPosition = [2,8,9]
      if obj.getDistanceTo(player) > 29:
        obj = scene.addObject("lung", player, 0)
        obj.worldPosition = [2,8,3]
                
          


               




main()


First, you don’t need two if statements, you are defining the obj variable twice,there is an indentation problem with the second unneeded if statement.

Add two empties to your scene named pos1, pos2 at the locations where you want the object to be added and then use this script:


import bge

def main():
    cont = bge.logic.getCurrentController()
    scene = bge.logic.getCurrentScene()
    player = scene.objects['player']
    
    pos1 = scene.objects['pos1']
    pos2 = scene.objects['pos2']
    
    obj = cont.owner
    
    if obj.getDistanceTo(player) > 29:
        scene.addObject('lung', pos1, 0)
        scene.addObject('lung', pos2, 0)
main()

Whole idea for the python script is not to use emptys or other mesh objects.

Whoever told you that? Python scripting is there so you can do more advanced things WITH the objects in your scene that cannot be or are either really hard to do by logic bricks.

Defining position vectors virtually inside the python script accurately is really hard, instead using proxies like empties and using their positions inside the script is very easy and accurate, also if you want to change the positions you can simply change the positions of the empties instead of going into the script and changing the positions. Why can you not use empties? They are not meshes.

If you still want to use just scripting then remove your second if statement it should work.

Because if i use them to procedural generate an environment the framerate would drop too much.I am trying to figure that out slowly.

Scene add object returns the thing you’ve just added. it’s great because you can then place it where you want it or rotate it or scale it or anything you want before it gets rendered. So it appears just as you want it.

However, lostscience needs more variables.

You define own as obj, then you define the added object as obj, then you get the distance from the added object to the player and then add another object which you name obj.

You can use obj_1 obj_2 etc… Or lung_1, body, etc… try to use variables which describe the thing that you’re working with so you remember what it is.

Try this then:


import bge
def main():






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




    sens = cont.sensors['mySensor']
    actu = cont.actuators['myActuator']
    if obj.getDistanceTo(player) > 29:
      obj1 = scene.addObject("lung", player, 0)
      obj1.worldPosition = [2,8,9]
      obj2 = scene.addObject("lung", player, 0)
      obj2.worldPosition = [2,8,3]
                
          


               




main()

It did not work and it does not have no errors in the console.

There were indentation errors I told you before, I figured you could solve them by yourself but oh well,

import bge
def main():
    
    cont = bge.logic.getCurrentController()
    scene = bge.logic.getCurrentScene()
    player = scene.objects ["player"]
        
    obj = cont.owner
    
    if obj.getDistanceTo(player) > 29:
        obj1 = scene.addObject("lung", player, 0)
        obj1.worldPosition = [2,8,9]
        obj2 = scene.addObject("lung", player, 0)
        obj2.worldPosition = [2,8,3]
main()

It did not show up in the cosole.Why did it not show up?You forgot to put main on the other script at the bottom.I did not look.I thought it was correct.oh you did.

Also there needs to be precisely four spaces (if I remember correctly) after every semi colon, it gives an “Unexpected Indentation” error otherwise.

Or you can use tabs.

@Lostscience, if you want to level up your programming skills, I suggest you take a course on Codeacademy. It’s a free site which can teach you how to program more easily.
It has interactive tutorials which guide you though some of the trickier coding concepts and gives you feedback so you can see if you’re doing it right. I wish I had know about before now.

It covers several programming languages. Python is in there.

Wisaam’s code showed a function:

def add_more_skunks(number):    
    number += 10
    return number

In order for a function to be used it has to be called.

smelly_skunks = 1
smelly_skunks = add_more_skunks(smelly_skunks)
smelly_skunks = add_more_skunks(smelly_skunks)
print (smelly_skunks)

main() is a function, you have to call it before it can do anything.

Also you only get errors in the console if the code does something it’s not allowed to. If you tell it to do something strange it will try and if it works there won’t be any error, even though the result is not what you want.

Consider:

def add_more_skunks(number):    
    number -= 10
    return number
smelly_skunks = 1
smelly_skunks = add_more_skunks(smelly_skunks)
smelly_skunks = add_more_skunks(smelly_skunks)
print (smelly_skunks)

How many smelly skunks will print this time? It’s not a code error, it’s a user error.
These are the hardest kind of errors to find.
Several times I’ve used (y,x) instead of (x,y) and couldn’t work out why everything was in the wrong place.
Now it’s something I look out for, but the first couple of times it happened I couldn’t work out what was happening.
Or I named something the same as another object.

I did use codeacademy but i was not getting a answer fast enough to my question so i gave up using it.
It was taking weeks.

main() is nonsense.

When you use script mode put everything at top level indentation.

When you need functions it is time to use module mode.

not true, a script is property of the gameobject caller(controller caller) .you can organize a script using functions exactly as in modules . the differences are, 1: scripts are more slow2: script can be used only from the object “owner”

no you can’t

A script is always executed from top to bottom. That is why you need to define a function first and call it after that. This disturbs the reading of the code as you need to jump to the end of the file to discover you need to jump back to somewhere before. Unless it is a lexicon I would never expect a reader to jump around in a book.

A module does the same, it gets executed from top to button, parsing all the definitions. The difference is the module mode. It parses the module once and you do not need any other code than pure module initialization at indentation level zero (module level). The module mode allows you to define any function as entry to your Python module. This allows you to place the entry points right at the top of the module supporting the reader to read them in a useful order. No need to jump up and down. Additional you can have as many entry points as you like rather than a single one.

The next thing is [attention: repetition] the statement main() has absolutely no meaning within the BGE and Python. It has a meaning in GLSL, in C, even in Java. There it defines the entry point of an application (in GLSL the entry point of the shader). The BGE cares what you write into your Python controller. According to the dictionaries “main” describes a characteristic, not a thing, nor an operation.

It is not necessary and serves no additional information, therefore I recommend to skip it completely.

As said, when you use script mode, your code should be small and simple, which means you do not need functions. When you need it because your code grows … switch to module mode or place your functions into another module and call them from your script. This let you focus on the important aspects of your code rather than cluttering it with little details and confusing structures.

… finally it is your choice, just think about it.

I agree with Monster. As soon as you’re writing more than a simple script it’s time to move to module mode.
The big benefit of module mode is being able to write multiple modules and import them. This allows you to split up your code in to bite sized chunks so you don’t have to scroll through thousands of lines of code to find a bug.

Compare:
error in line 3690 of main

error in line 12 of footsteps

The way I see it there are several problems being discussed here:

  1. Fix my script (How do I add lots of objects?)
  2. Python or empties?
  3. How do you debug a python program?
  4. How do you structure a python program?

The first on I’ll cover really quickly:


import bge

cont = bge.logic.getCurrentController()
scene = bge.logic.getCurrentScene()
player = scene.objects ["player"]
 
obj = cont.owner  #Not sure what this object is? Can we give it a better variable name?


if obj.getDistanceTo(player) > 29:
    lung_1 = scene.addObject("lung", player, 0) #Because we're adding a lung, let's call it lung
    lung_1.worldPosition = [2,8,9]
    lung_2 = scene.addObject("lung", player, 0) #And because there's two of them, lets call this one lung_2!
    lung_2.worldPosition = [2,8,3]

In module mode:


DISTANCE = 29
POS_1 = [2,8,9]
POS_2 = [2,8,3]

def check_close_enough_for_lungs(cont):
    player = cont.owner.scene.objects['player']
    if cont.owner.getDistanceTo(player) < DISTANCE:
        add_lung(player, POS_1)
        add_lung(player, POS_2)

def add_lung(ref_obj, pos):
    scene = ref_obj.scene
    lung = scene.addObject("lung", ref_obj, 0)
    lung.worldPosition = pos


Python Or Empties
Whichever you like and are comfortable with. Empties are easy to manipulate, you drag them around in blender and they move. On the other hand, if you have lots of positions you want to store (hundreds), managing hundreds of empties is hard.
You can make vectors with:


import mathutils

vec = mathutils.Vector([0,0,0]) #Replace [0,0,0] with any 2-4 long list of whatever you like.

if you need to do vector operations (like adding or subtracting positions.
If you want rotations, you can store eulers or quaternions.
Or more generally, you could simply store a transformation matrix, which is all an empty actually is.

Where should I use empties
Where you have a few of something that may need to be tweaked.
Where it has to interact with other objects (eg parenting), it is often easier to do it in empties.

Where should I use some other storage medium
When maintaining the empties becomes hard (eg lots of them)
When you want to load different sets of them (eg from a text file)


How do you debug python
This is just the basics:

  1. Check for errors in the console. This is always the first step, but only picks up minor errors such as typos
  2. Print “I’m here” markers, so you can see if your code is getting to various places. This can be as simple as adding “print(1)” to one line and “print(2)” to another. Make sure you remove them afterwards though. You may place some around inside the if statements to see if they are getting exectuted.
  3. Print various variables. This one would pick up the error in the first script in this thread. It would show that for the first conditional, obj is the name of the object running the script, but for the second conditional, obj is the added object “lung”
  4. Check conditionals. Print out things like the obj.getDistanceTo(player) and see what it actually is.
  5. Read through the API
  6. Draw diagrams, and thing through your problem on paper
  7. Read through a physics textbook
  8. Ask your teacher/lecturer/dad/someone else who knows what you’re working on, and is likely to know the problems you’re having.
  9. Ask random people on the internet for help

How do you write python

  1. Get out pen and paper. Yar, I know every IT teacher says this, and they hammer you with it, and as a teenager you go “but I can think it all through in my head, it’s faster without paper,” but knowing what you are making before you start is a good plan. Draw flow charts, UML diagrams, wite down what you expect the program to do, figure out how to break it up into logical sections
  2. Test early, test often. When I make an object call a function, the first thing I do is make that function be:

def new_function(input):
    print("Hello, I'm here")
    return some_trivial_but_valid_output #eg 0 or false

That catches an amazing number of errors before they send me on wild goose chases through my code.
3) Test your code after every 3 lines of code. You don’t have to test it very thuroughly, but if you make small changes, things are less likely to end in a train-smash.
4) Keep consistent style. Use pylint and pep008. Force yourself to obey their rules. Yes, a 30 line function may seem managable, but split into smaller ones anyway. It means when your code throws an exception, you have fewer lines of code to hunt through.
5) Study physics (looking at you adrian)
6) Debug the mess you’ve made
7) use more paper
8) Cry a little about the horrible mess your neat code turned into
9) Realize no-one actually knows how to write good code
10) Get out more paper and try re-organize things
11) Realize you need more modules and functions

Yeah, I often start out writing pseudocode, just empty functions. I then use print(“a”) print(“b”) print(“c”) to tell me when events have fired. “a” is in the main body just before the function, “b” is in the function before it returns and “c” is when it returns the right thing.

If all the letters print in the right order I know the code is set out right and I can start populating the functions so they actually do something. Or I print the thing it’s supposed to do like print(“add lung”) rather than letters.

Welcome to the wonderful world of re-factoring :D. Time to switch to an IDE that does all the boring work for us.