How to move in two directions at once?

For example…

W and D at the same time for angled movement.
W and A
S and D
S and A

making sense?

What’s the most efficient way of doing this?

The simplest way is to just use motion actuators connected to keyboard sensors (the force and Dloc types for instance are inherently additive in terms of speed and direction).

Alternatively, you can switch the mode to use servo control, which provides motion more suitable for characters.

I know how to do wasd
I want to know how to make it so pushing w and d at the same time angle my motion instead of just going the way of the last keystroke.

Set your actuators to ADD mode.

what are you using for motion? if you are just using keyboard and motion logic bricks and simple or character(DLOC) motion, it pretty much works this way out of the box. if you are using a python script then the problem could be the other keypresses are getting ignored in the movement loop. maybe a little more info needed here. a demo blend or even a screenshot of your setup.

You are amazing!

So turning on add made it work right, but now I need it to respond properly when opposite directions are hit.

For example, I can push s while w is down and I stop but not the other way around

I also need it where when a and d are active they cancel each other out, that does not seem to be happening at the moment.

This is happening because

w is a positive value of 0.25
s is a negative value of -0.25

w-s=0 great that’s what I want

See the problem?

Likewise is true for a and d.

Something like that.

Regardless, it’s actually acting unpredictable. Moving me in unwanted directions.

Here is the blender file.

This relates to a bug -
For now, it may be wise to perform ADD mode manually, by checking for W and S, just W or just S.

So… by sending messages from those keypresses and manually putting in the logic that will preform how I want?

When this bug is fixed this wont be necessary, right, it should act right in the future?

How do I tell it to stop moving?

Oh, I’ll use properties to dictate motion states, that will work.

Problem solved, I just used simple motion and it works exactly as expected. Character motion was acting really buggy to me. It seems to function rather differently.

The only problem is that

wa, wd, sa, sd move faster than w a s d alone.

They’re moving 1.4142x faster (or, the square root of 2).
Divide your movements by that while you’re moving diagonally, and that will nullify that extra speed.

(PS simple motion will cause you problems with collision. Try using Force, or Servo motion, if you plan on having collisions with walls and such)

(PPS character movement is bricked and nobody should ever use it LOL :wink: )

What makes servo motion different?
Also I notice that with simple motion using linear velocity does not move in both w and a, it just picks the key I took my finger off last to apply the velocity to.

Can servo do velocity and do it better?

Right now I have it when w and a are presses at the same time to subtract a certain amount of motion from both axis. Is this ok? Is there a better way?

Something I threw together real quick-like.
You can do all this without motion actuators, if you’re willing to use some python.

Not the most efficient code, but it illustrates the idea.

(edit: Above when I say to divide the square root of 2 from movement, it’s supposed to be subtract. My bad.)
(edit2: Apparently you can’t subtract from a Vector. Didn’t notice that error in the console before I uploaded. Oops)

easy_move.blend (476 KB)

in that script, how to i change how much velocity there is?

Like I need normal moment with velocity but not just velocity.

How can i get servo to me at a constant speed?

Why wont this script work?

import bge

def main():

cont = bge.logic.getCurrentController()
player = cont.owner
keyboard = bge.logic.keyboard
if bge.logic.KX_SENSOR_ACTIVE == []:
    player.applyMovment((0, .5, 0), True)
if bge.logic.KX_SENSOR_ACTIVE == []:
    player.applyMovment((-.5, 0, 0), True)
if bge.logic.KX_SENSOR_ACTIVE == []:
    player.applyMovment((0, -.5, 0), True)
if bge.logic.KX_SENSOR_ACTIVE == []:
    player.applyMovment((.5, 0, 0), True)


It’s applied with the always brick and the pulse mode is on.

The SPEED global at the top of the script defines how much force is applied.
If you want the cube to change velocity faster/slower, alter its mass (in it’s physics tab).

If you’re not worried about physics/collisions, and you want to just translation, you should be able to just change the applyForce() calls to applyMovement() (which by the looks of it is exactly what you’re doing). Note: You will probably want to change SPEED to something like 0.2 if you do do that, or your cube is going to move very fast. You may also want to change it from Rigid Body type back to Static (since you don’t need the rigid body physics).

As for why your script isn’t working, you need to change your key checks to:

if bge.logic.KX_INPUT_ACTIVE ==[]

or better yet:

W = bge.logic.KX_INPUT_ACTIVE ==[]
if W:

You can also change INPUT_ACTIVE to ‘INPUT_JUST_ACTIVATED’ or ‘INPUT_JUST_RELEASED’, if you want those sorts of controls.