1
\$\begingroup\$

I have two objects rotating around a sphere. One is controlled by the user (object A), another is simulating a user but controlled by the computer (object B). At random intervals of time I'd like object B to start moving towards object A.

I can get this to work using this formula to determine the movement direction between two points:

public Vector3 DirectionTowards(Vector3 from, Vector3 to)
{
    return (to - from).normalized;
}

This gives me a normalized direction vector to update the x/y movement with. Since this is momentum based, if the objects need to move in an opposite direction I update their movement direction vector like so: (notice the "+=" instead of just "=" to give the effect of momentum/acceleration, more on this below)

// This code runs when  I need to move object B toward object A
var newDirection = DirectionTowards(transform.position, target.transform.position);
xMove = newDirection.x;
yMove = newDirection.y;

...

// This code runs in my update method
_moveVector.x += xMove * _acceleration;
_moveVector.y += yMove * _acceleration;

The problem I'm having is that when the objects are at opposite sides of the sphere, sometimes object B will start moving in the direction that is not the shortest distance to object A. Is there a way I can determine the direction in a similar way, but force it to choose the shortest distance around the sphere?

Also, to go along with this. By using "+=" vs "=" when I update the _moveVector sometimes that causes the direction to get changed slightly because it does an arc as it slows down its momentum before moving in the new direction. Does anyone know why that might be, or if I'm doing that incorrectly? Basically object B will start moving "almost" in the right direction due to this, but eventually after a while the whole things gets screwed up. If I use "=" only, this works perfectly every time except for the issue of shortest distance as I mentioned above.

Thanks! Let me know if any other information is needed.

\$\endgroup\$
2
\$\begingroup\$

A few issues come to mind as I read this:

  1. Your movement is on the surface of a sphere, so travel direction should be a tangent to this surface, not just a (to-from) normalized, as that would point into the sphere.

  2. You mention acceleration and movement, but nowhere "velocity" or "speed." Use standardized terms, to make your intentions and code clearer. I think you call it moveVector instead? Just use acceleration, velocity, position, as a physicist would. Force changes Acceleration. Acceleration changes Velocity, Velocity changes Position.

To address (1): the computation of your Acceleration needs to be a tangent to the sphere. You can use something like this:

targetdir = targetpos - position;
surfacenormal = position.normalized();
crossed = z.crossProd( x );
crossed.normalize();
traveldir = crossed.crossProd( surfacenormal );

Now you have a travel direction to where you can steer towards. We use this to accelerate (or push) your object towards. A fancy way would be to now use PID controller for steering by setting forces/acceleration, but we can make it easy by just interpolating the current velocity and the traveldir, which is a desired velocity.

s = 3 * dt; // higher values for less momentum.
t = 1 - s;
velocity = t * velocity + s * traveldir;
position = position + dt * traveldir;
\$\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.