Diagonal movement speed

Hello,

I’m working on a simple control scheme, which I’ve attached. As you can see, you use the arrow keys to move, and straight movement works just fine. The problem is, when movind diagonally, you move at twice the speed. I tried to create a solution, but it was very complex and I’m probably overthinking things. Can anyone think of a way?

Also, as a side question, is there any way to assign a controller to multiple states in version 2.47?

Thanks for your time.

Attachments

Basic Game Control Setup2.blend (238 KB)

It is not moving with twice speed. It’s 1.4. It would be twice if both motions are in the same direction.

This is simple math. Your object moves along X with speed 1. Now you add a motion with speed 1 to Y. The resulting speed is Sqr(11+11) = 1.4… the direction is 45 degrees on XY (or half between X and Y movement).
If you want exactly the same speed (1), you have to make reduce the speed along each axis, when combining the motion.
You can calculate this with sin() and cos() both are .707 at 45 degrees.

Your solution could be:

  • If the up and the right key are pressed at the same time (two motions activated), the motion forward will be 0.707normal speed and the motion to right will be 0.707normal speed.
  • etc.

I hope it helps

In python, you can set a maximum speed, with obj.linVelocityMax- just use that, and then you can even use force for movement to get the character moving more smoothly.

Monster-
Thanks!
I tried to make a system where whenever two keys were pressed, it would limit the speed in the direction of the keys to 70.7% using servo control, but it isn’t working. Strange, considering I’ve used servo control in the past to limit speed, and I double checked to make sure the settings were correct.

Captian Oblivion
Thanks for the suggestion, but I don’t even have python. Could you direct me to a tutorial on getting python working in blender?

If you have blender, you have python (you don’t need to separately install python for the GE)

To get the speed limiting script going, just copy the following script into the text window, name it something (like “limit”). On the object, add a controller, change it to python, and type the script’s name into the field. Connect that to an always sensor, with pulse (the little box in the corner that reads “…”) off (no need to run the script more than once).
Lastly, add a property named “speed” (without the quotes, of course), and set the number to whatever max speed you want. If you don’t use this property, the max speed will default to 1 and the object won’t go very fast at all.

The script:


o=GameLogic.getCurrentController().owner
if o.has_key('speed'): speed=o['speed']
else: speed=1
o.linVelocityMax=speed

I did it exactly as you said, but I keep getting this error:

PYTHON SCRIPT ERROR
Traceback(most recent call last):
File"limit", Line 1, in <module>
AttributeError: owner

By the way, Is it possible to to only limit the x and y speed?

Are you using blender 2.49? it shouldn’t not an error in the script, I tested it before posting…

Limiting just X and Y speed is definitely possible, it just requires the math to be done manually:

This script only limits speed while it’s running, so plug it into an always sensor with true pulse on.


g=GameLogic
o=g.getCurrentController().owner

if not o.has_key('speed'): speed=1
else: speed=o['speed']

vel=o.getLinearVelocity()
XYSpeed=(vel[0]**2+vel[1]**2)**(1/2)
if XYSpeed&gt;speed: vel=[vel[0]/XYSpeed*speed,vel[1]/XYSpeed*speed,vel[2]]

o.setLinearVelocity(vel)

Alternately, this version should be compatible with old versions of the BGE (it will return deprecation warnings in 2.49, and won’t work in 2.5 once it comes along, so the script above is preferable):


g=GameLogic
o=g.getCurrentController().getOwner()

if not hasattr(o,'speed'): speed=1
else: speed=o.speed

vel=o.getLinearVelocity()
XYSpeed=(vel[0]**2+vel[1]**2)**(1/2)
if XYSpeed&gt;speed: vel=[vel[0]/XYSpeed*speed,vel[1]/XYSpeed*speed,vel[2]]

o.setLinearVelocity(vel)

[edit] fixed the import

Yeah, I don’t have 2.49 yet, but I’ll get it soon. The second script worked perfectly, of course.

Thanks a bunch!:slight_smile:

If you don’t want to import math (so python is not required) you could replace sqrt(function) with (function)**(1/2)

I should have thought of that myself, but I just found out about ** and it hadn’t really clicked that it’ll do any power, even fractions, yet.