Sign in to follow this  

how to make the npc follow a moving target(moved by physics) smoothly?

This topic is 2575 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have several NPC want to follow the player, if the player stand still, I can use liner interpolation to move the npc towards the player's position, and it works well, however, it's jiggle if the player is moving as well(player is moved by force with physics, but npc is just controlled by updating the position directly). Any ideas to make the npc to follow the player smoothly? Thanks

Share this post


Link to post
Share on other sites
The simplest controller you could try would be a proportional one.

Call the player's position vector 'r.' Call the NPC's position vector 'x.' Suppose that the NPC has dynamics,

x[k+1] = x[k] + u[k] dt

where 'k' is the index of the current simulation step, u[k] is the velocity (you can choose it), and dt is the size of the timestep. Then a proportional controller would select u[k] at each time as,

u[k] = g(r[k] - x[k])

where 'g' is some constant. This will result in closed-loop dynamics (just plugging the second equation into the first),

x[k+1] = x[k] + k(r[k] - x[k]) dt
= (1 - g dt) x[k] + (g dt) r[k]

This will be stable so long as

-1 < 1 - g dt < 1

or equivalently,

0 < g < 2/dt ;

I would suggest a g in the range

0 < g < 1/dt

to avoid oscillation.

This is the simplest controller you can use. If it works, problem solved. If the performance isn't good enough (i.e., if you can't catch the target because it moves too much), you can add integral terms; if you find that's necessary, post back and I can explain that.

Share this post


Link to post
Share on other sites
Quote:
Original post by Emergent
The simplest controller you could try would be a proportional one.

Call the player's position vector 'r.' Call the NPC's position vector 'x.' Suppose that the NPC has dynamics,

x[k+1] = x[k] + u[k] dt

where 'k' is the index of the current simulation step, u[k] is the velocity (you can choose it), and dt is the size of the timestep. Then a proportional controller would select u[k] at each time as,

u[k] = g(r[k] - x[k])

where 'g' is some constant. This will result in closed-loop dynamics (just plugging the second equation into the first),

x[k+1] = x[k] + k(r[k] - x[k]) dt
= (1 - g dt) x[k] + (g dt) r[k]

This will be stable so long as

-1 < 1 - g dt < 1

or equivalently,

0 < g < 2/dt ;

I would suggest a g in the range

0 < g < 1/dt

to avoid oscillation.

This is the simplest controller you can use. If it works, problem solved. If the performance isn't good enough (i.e., if you can't catch the target because it moves too much), you can add integral terms; if you find that's necessary, post back and I can explain that.




Thanks, my way is similar to yours:

Vector3 dir = player.position - npc.position;
dir.Normalize();
Vector3 targetpos = player.position - dir * mDistance; //mDistance is to avoid the npc getting too close to the player
float factor = Mathf.Min(1.0f, Updater.deltaTime*5.0f);
npc.position = Interpolation.Linear(npc.position, targetpos, factor);

dir = player.position - npc.position;
npc.rotation = Interpolation.Linear(npc.rotation, Quaternion.LookRotation(dir), factor);



Vector3 Linear(Vector3 v0, Vector3 v1, float factor)
{
return v0 * (1.0f - factor) + v1 * factor;
}


However, it's not smooth enough. If the player stands still, it works well, but if the player is moving with a changing velocity calculated from the forces applied by physics engine, the movement of the npc is jiggle. So I suspect the reason is the target is moving with a changing velocity. I tried to use the average position of the player from the last 30 frames as the target position, it seems not working either.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyou23
my way is similar to yours:


Ok, I see; rather than using a proportional ("P") controller to get the NPC to the player's position, you use one to get the NPC to the closest point on a sphere of radius mDistance surrounding the player. And, translating to my notation, your control gain is chosen to be

g = min{5, 1/dt}

which is indeed stable.

Quote:

However, it's not smooth enough. If the player stands still, it works well, but if the player is moving with a changing velocity calculated from the forces applied by physics engine, the movement of the npc is jiggle. So I suspect the reason is the target is moving with a changing velocity. I tried to use the average position of the player from the last 30 frames as the target position, it seems not working either.


I'm surprised that you get unacceptable "jiggle" with a P controller. Is your control gain (factor) just too high?

If not, then the first thing I'd try is what you did, which is to filter the reference. What didn't work about your average-position-over-last-30-frames method?

Share this post


Link to post
Share on other sites

This topic is 2575 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this