1
$\begingroup$

I need an object to move along the local axis of a different object. This is more or less what my code looks like.

obj = scene.objects['obj'] #this being the object I want to move
look = scene.objects['look'] #the object with the axis I need 
local = True #y'all know what this is for
or = look.worldOrientation 
input = cont.sensors['input']

if input.positive:
obj.applyMovement([0.0,0.15,0.0], local)

Of course, this doesn't do what I want it to do, and replacing 'local' with 'or' just gives me an error in the console, so I'm stumped. Please help.

For a bit more context, the setup for the character basically has two parts: The controller(obj), which moves around and rotates the camera around, but whose y axis always looks away from the camera, and a directional object(look), which is parented to the controller and rotates the character around to look in the direction the controller is moving.

What I need is for the controller to move in the direction the directional object is looking at when the conditions (input) are met.

$\endgroup$
2
$\begingroup$

This is a question of the coordinate system you are referring to (the space).

What spaces do we have?

Scene Space

There is the scene space (world in the BGE). The origin is the scene origin. It defines the (1,1,1) scale and the orientation of the whole scene.

Object Space

There is the object space (local in the BGE). It expresses the relativ transformation (= position, rotation, scaling) from the parent. If there is no explicit parent, the scene is the parent.

Without any transformation the object would be at the parents location, facing the same direction, and having the same scaling.

You have several different object spaces within a scene (one for each object). They can be equal, they do not need to be equal.

Other Spaces

There are more spaces (vertex space, texture space, view space, screen space ...). I want to focus on the scene and object spaces as this is what you need to deal with your situation.

Purpose

Why do we need different spaces? We do not need them. We just need one, which is valid for all participants. The different spaces are used to make things easier e.g. it is much easier move "forward" when you can add step to a single axis.

Operations in different spaces

To operate with different spaces you need to know how to convert from one space to another (e.g. from scene space to object space).

Scene space and object space are the most used spaces. You have a different use case right now. You want a -lets say- "look space". To work with it you need to find a way to convert the coordinates of one space to your "look space" and vice versa.

Luckily you can combine conversions.

Convert from scene space to look space:

referenceObject.worldTransform.inverted() * positionInSceneSpace

Convert from look space to scene space:

referenceObject.worldTransform * positionInLookSpace

Move in look space:

To move along an axis of the look space you convert the current position in scene space to coordinates in look space.

Now you can apply the motion e.g. along the x axis. All operations are in scene space.

After the change you convert the result back to scene space and apply it to the object.

Sample code:

import bge

scene = bge.logic.getCurrentScene()
referenceObject = scene.objects["ReferenceObject"]

controller = bge.logic.getCurrentController()

if all(sensor.positive for sensor in controller.sensors):
    owner = controller.owner

    # get position in scene space    
    positionInSceneSpace = owner.worldPosition

    # convert to look space
    positionInLookSpace = referenceObject.worldTransform.inverted() * positionInSceneSpace

    # modify in look space
    positionInLookSpace.x += .01

    # convert to scene space
    positionInSceneSpace = referenceObject.worldTransform * positionInLookSpace

    # apply position in scene space (as the object expects it that way)    
    owner.worldPosition = positionInSceneSpace

This solution considers motion, orientation and scaling of the reference object.

Operations in look space

  • positionInLookSpace.x += 1 moves the object 1 BU along the reference object's x axis

  • positionInLookSpace = mathutils.Vector((0,0,0)) sets the object at the origin of the reference object

  • positionInLookSpace = mathutils.Vector((1,0,0)) creates an vector that goes one BU along the referenced object's x axis. After converting it to scene space you can apply it to applyMovement().

Convert from object space

Just for information: When you want to use localPosition rather than worldPosition:

  • convert from object space to scene space
  • convert from scene space to look space
  • change position in look space
  • convert from look space to scene space
  • convert from scene space to object space

So you need two additional conversions. Luckily the BGE already does that for you when you use worldPosition.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.