Way to 'if not' null vectors like 'None' object?

I have a random number generator generating -1,0, or 1 to decide the direction that my mobs wander.
Sometimes it generates a null vector (0,0,0) and so the ‘apply movement’ can’t be applied. Is it possible to do something along the lines of

‘If forwardVect != Null:’?

There is nothing wrong in applying a movment of (0,0,0). That said, if you still want to check it, first I would prupose to check the number you’ve generated e.j:

<i>n = random.randint(-1,1)
if n != 0: own.applyMovment([0,0,n])</i>

If that can’t be done becouse you create a Vector object, then just use it’s attributes (xyz) or (wxyz if 4D). So:

n = random.randint(-1,1)
vect = mathutils.Vector([0,0,n])
n = None #Ups!
if vect.z != 0: own.applyMovment(vect)

If not happy with that and you still want to check all two vectors are equal (in this case, equal to (0,0,0)), you can just do:

if (vect.x, vect.y, vect.z) == (0,0,0):

#The pharentesys is just my style, this is also valid:
if vect.x, vect.y, vect.z == 0, 0, 0:

#You can also try this
if vect == mathutils.Vector([0,0,0]): #

Now the last line may not work, since python will probably check the object references and not if the objects are equal. (The documentation however says it should work fine, but I’m not convinced). The documentation also sais that you can use:

<i>if vect.to_tuple() == (0,0,0):</i>

And it also says that you can use Swizzling, wich if I understood correctly (not really sure), shuld make this possible:

<i>if vect.xyz == (0,0,0):</i>

And last but not least, since you can acces the elements of a vector like if it were a sequence, this shuld also be possible:

<i>if vect[:] == [0,0,0]:</i>

Not even I knew there was so much ways to do it before you asked.

Also an important note if you’re going to use vectors in BGE. A mathutils.Vector has no owner, but an obj.localPosition vector has “obj” as it’s owner. It means that modifying the vector will also apply the changes on the position of the object, this can generate some unexpected behavior, so if that’s the case you can make a copy of such vector with obj.localPosition.copy().

Edit: If you’re really going into python, try BGECore, if you aren’t, you should still try it’s launcher.

When the only choices are 1.0 and -1.0 = 2 choices it makes much sense the create random values within that value range (two values).

regardless what random values you create you map them to the choice values (vectors).

e.g.:


import random

...
choices = [ Vector([-1.0, 0,0] ), Vector( [1.0, 0.0, 0.0])
...

   randomVector = random.choice(choices)

see random.choice

In case you want to create a long range of choices I suggest to ensure excluding invalid choices from mapping of random values to choice values.


import random

def mapZeroTo(number, zeroMappedValue):
   if number == 0: 
      return zeroMappedValue

   return number

...
    scaling = 100.0
    randomX = random.random() # this excludes 1.0
    
    # transform value range from [0.0, 1.0) to [-50.0, +50.0] excluding 0.0
    xAxis = mapZeroTo( randomX*scaling/2, scaling/2 )
    randomVector = Vector( [xAxis, 0.0, 0.0] )


Thanks, that random choice thing is what I want I think. It just keeps printing (null vector!) in the console. When it DOES print null vector!, is that cpu being used up if the console is closed?

It prints that because it is a warning.

You do not need to care if that warning takes cpu time. You can avoid it by correcting the situation as you asked for.

With the above solutions you should not get a null vector anymore.

To check for null vectors you can check their length attribute. i.e.
if vector.length != 0.0:
You don’t need to check all the xyz values.

A better way might be to make a list of directions and then choose randomly from the list. That way you only get valid directions.