AI : fire on moving object - c#

i try to to make an AI in C# (with unity) that can predict the estimated position of a moving object to hit it with a bullet
the moving object have a movement speed of 5f and the bullet have a speed of 7f
my problem is that the time my bullet travel to my estimated position my "enemy" already moved further and the bullet don't hit
do you know a formula or code that i can adapt to improve my targeting AI ? (already looking for that in google but don't find anything usefull)
thank

An answer to your question from unreal engine forums
Here is the top answer from there in case the link dies. I did not write this code I simply found it with a quick google of your problem which you stated you already tried.
Link answer:
Get the "velocity" of the target player. Multiply by the time the bullet will take to travel to the target. Then get the position of the target, add the velocity*time vector, and that's the position you should aim at. You can either hard-code the travel time (half a second, or whatever,) or you can in turn measure the distance between AI and player, and divide by bullet travel time, to come up with an approximate travel time. You can also apply a differential equation to calculate the exact time of impact and exact direction, but that requires a little more math and is slightly harder to write out, so I think the above will work best for you.
Simply:
Distance = Length(Target_Position - Firing_Position)
Time = Distance / Bullet_Speed
Predicted_Position = Target_Position + (Target_Velocity * Time)

Related

C# Monogame, trying to create a 2D racing AI

So I have been tasked in making a 2D top-down racing game over the summer for college, and I have been dreading doing the AI but it is finally time. I have googled many different ways of the same thing just to try and find a person asking the same question but it seems everyone uses Unity over Monogame.
So I have an "enemy" car which can accelerate (as in slowly speeds up to top speed), decelerate and steer left and right. I have got the actual car the player drives working fine but the game is boring when the player isn't racing against anyone. All I need is a very basic AI which will follow a path around the course and will readjust if it gets knocked or something happens to it. I don't even know where to start, Please help!!! Please let me know if you need any more details.
I may be misunderstanding your question, but it does not seem like you are looking for AI capabilities in your enemy car.... "All I need is a very basic AI which will follow a path around the course and will readjust if it gets knocked or something happens to it.". AI typically implies learning, but no where does it seem that you need your car to learn from past mistakes/"experiences". It sounds like you can use a path-finding algorithm to solve your problem since you have no requirement of the car actually learning from previous interactions with other cars, fields, etc. A super popular algorithm you can look into is A*. You can set up your game to be a graph with edges that have the "boosts" be lower weighted then the common "road". The obstacles or path-finding equivalent term - walls can be represented as high weight edges which would cause your car to avoid them automatically, by nature of A* finding the fastest path to a point.
AStar explanation with pseudo code: https://en.wikipedia.org/wiki/A*_search_algorithm
Great visualizer tool: https://qiao.github.io/PathFinding.js/visual/
Accelerating/Decelerating
As for accelerating/decelerating that can be separate logic like randoms deciding whether to speed up or not.
If it gets knocked or something happens to it
You can re-calculate the A* when the car is hit to ensure that your car gets the new fastest path to get back on course. The actual collision logic is up to you (not part of the A* algo).
Note that if you are planning to have more than just a straight path in which the cars can steer (meaning there is no crazy bends or turns) the A* should not have too much variation from the natural algorithm. If you are planning to support that kind of track you may need to look into slightly different algorithms, because you will need to keep track of the rotated angle of your car.
What you need to implement would be dependent on how complex, of course, your AI needs to be. If all it needs to do is readjust its steering and monitor its speed, a basic AI car could at a given time step...
Accelerate if not at top speed
Decelerate if cooling down from a boost
Steer away from the track boundaries
Decide whether or not to boost
(1) and (2) are easy enough to implement at a given time interval. Something like if(speed < maxSpeed) { accel(); } else if(speed > maxSpeed) { decel(); } where a double maxBoostSpeed exists to limit speed during a boost.
(3) and (4) could be achieved by drawing a trajectory in front of the car with something like [ x + speed*Math.cos(angle), y + speed * Math.sin(angle) ]. Then (3) could be achieved by steering towards the center of the track, and (4) could be from projecting the trajectory into a line and finding the distance before the next track boundary a.k.a. the next turn. If that distance to the trajectory intersection is large, it may be time to boost.

How can i get the Direction where my Object is moving?

I have started to make Pacman and would like to know how can i write in my code the direction where the Ghost is going ? So if the transform.position.y is growing, its obvious Up Direction and so on....
This is for the Direction Change if they're hit the Wall.
Any suggestions?
It depends on how you've got your game set-up. One manual way you could go about it is by saving the position in a frame, and in the next frame you calculate the difference between the two positions (the previous frame and the actual frame), and divide that by the time that has passed (Time.deltaTime).
Another way you could go about it (and I would recommend if possible) is simply getting the Rigidbody component and checking the velocity attribute: https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html
Keep in mind, since this is a beginner's question, that the fact that an object is moving in a certain direction may not come from a ribidbody. As I said, this depends on your exact set-up.

How to add random x, 0, z movement to GameObjects on Terrain?

I'm inexperienced with UnityScript and C#, and a solution I can study would be greatly appreciated.
The behavior I want is for Pickups to move in random directions on a terrain, changing direction if they encounter a rigid body or static object.
I tried the script "Wander.cs" available here:
http://wiki.unity3d.com/index.php/Wander
However, when played, the script turns the game object on end, and I cannot correct this. Also, objects tend to pool in corners instead of heading away.
There are two possibilities as far as I can understand your query.
I didn't try but hope it helps.
1- With help of parametric equation of circle i.e.
x=v.t.cos(theta)
y=v.t.sin(theta)
In you case:
x=v.t.cos(theta) + xDistance
z=v.t.sin(theta) + zDistance
where xDistance and zDistance are simple initial position value of your body. These value will not be changed after starting movement (during movement until collision occur).
In Update() apply these equations to your body with constant v and theta and increase t (t++ or t+= 0.1f) by time. When body collides, just retain the current translate (position) value. And start movement again, this time change the value of xDistance and zDistance with current value but only once.
2- With help of iTween. Its a free animation script available at Asset Store
You can use iTween.MoveTo to move body to any given direction (You can assign a random direction as well.). And stop and restart movement upon collision.

C# bounce/throw physics for items dropping

I thought I'd be able to find this with some searching on the internet but everything I find is just balls bouncing off walls for something like pong or another arbitrary question. I'm making a 2D dungeon crawler game and when I kill enemies and they drop loot I want the item to come flying out as if it had just been thrown in the air and land a random point on the tile the unit was on.
I've been trying to figure this out myself but I can't figure it out, this is probably asked a lot, I'd be really grateful if someone could help me out.
EDIT AS REQUESTED:
Ok well when a monster would be destroyed I would choose a random location within the tile it's in, let's call this location endLoc and the monster's location startLoc. I would then find the center x point between these two locations and decrease the y by 20 ( because that's how many pixels i want the item to go up by), so let's called this variable launchLoc:
launchLoc = new Vector2(startLoc.X + ((endLoc.X - startLoc.X) / 2), startLoc.Y - 20)
I think that produces the right Vector.
So now I would need to launch the item from startLoc, to launchLoc, then have it come back down to endLoc. This is where it gets confusing and I'm not sure how to make a realistic arc for this. The end result would have the item move like it moved along a gaussian, as if it was thrown into the air.
I tried to make it so during each interval, the velocity is increased by 120th, of the X difference, between the startLoc and launchLoc, by an incrementing multiple, but I couldn't get it to work very well. I'm not sure if this was the best way to do. I use 120th because the y value is 20, and the item moves up 1 pixel every interval, so 1 to 20 added up gives 120, this would make the x movement constantly increase, like it was thrown up.
This is in 2D btw, I hope that helps.
You start with an initial velocity vector at time t0 (v(t0)) and position (p(t0)). Gravity can be assumed to produces a constant acceleration (a(t0) = <0, -9.8 m/s2>, though your value may differ) until the object lands. So the general form of the motion for going from one timeslice to the next is:
p(t) = 0.5*a(0)*(t-t0)2 + v(0)*(t-t0) + p(0)
v(t) = a(0)*(t-t0) + v(0)
To figure out when to stop that motion, you need to figure out at what time the object's path will intersect the surface against which it bounces. You'll have to do this for all of the surfaces for which this can reasonably be expected to happen. So for a plane with line equation Ux + Vy + T = 0 you break the position vector into its components, as in:
p(t) = <px(t), py(t)> Then use the quadratic formula to find tc where p(tc) satisfies the line equation:
0.5*(Uax(t0)+Vay(t0))*tc2 + (Uvx(t0)+Vvy(t0))*tc + (Upx(t0)+Vpy(t0)+T) = 0Chose the branch such that tc > t0. From there it's simple to figure out where the object will collide with the surface. You can then update the velocity vector and position vector based on the behavior of the bounce. If the plane is axially aligned (ie, it's a horizontal plane with normal vector parallel to the Z axis), then just flip the sign of the Z component of the velocity vector and multiply the whole velocity vector by some damping factor d, where 0≤d<1 to damp out the velocity. Then repeat until some predetermined time has passed or the velocity reaches some minimal amount (your call on that).
It becomes a bit more difficult with arbitrarily oriented planes. You will need to calculate the angle of incidence of the collision and reflect the velocity vector about the plane normal. I won't go into the details here, as I suspect you're probably not interested in it.

Simple 2D rocket dynamics

I am currently experimenting with some physics toys in XNA using the Farseer Physics library, however my question isn't specific to XNA or Farseer - but to any 2D physics library.
I would like to add "rocket"-like movement (I say rocket-like in the sense that it doesn't have to be a rocket - it could be a plane or a boat on the water or any number of similar situations) for certain objects in my 2D scene. I know how to implement this using a kinematic simulation, but I want to implement it using a dynamic simulation (i.e. applying forces over time). I'm sort of lost on how to implement this.
To simplify things, I don't need the dynamics to rotate the geometry, just to affect the velocity of the body. I'm using a circle geometry that is set to not rotate in Farseer, so I am only concerned with the velocity of the object.
I'm not even sure what the best abstraction should be. Conceptually, I have the direction the body is currently moving (unit vector), a direction I want it to go, and a value representing how fast I want it to change direction, while keeping speed relatively constant (small variations are acceptable).
I could use this abstraction directly, or use something like a "rudder" value which controls how fast the object changes directions (either clockwise or counter clockwise).
What kind of forces should I apply to the body to simulate the movement I'm looking for? Keep in mind that I would also like to be able to adjust the "thrust" of the rocket on the fly.
Edit:
The way I see it, and correct me if I'm wrong, you have two forces (ignoring the main thrust force for now):
1) You have a static "fin" that is always pointed in the same direction as the body. If the body rotates such that the fin is not aligned with the direction of movement, air resistance will apply forces to along the length of the fin, proportional to the angle between the direction of movement and the fin.
2) You have a "rudder", which can rotate freely within a specified range, which is attached some distance from the body's center of mass (in this case we have a circle). Again, when this plane is not parallel to the direction of movement, air resistance causes proportional forces along the length of the rudder.
My question is, differently stated, how do I calculate these proportional forces from air resistance against the fin and rudder?
Edit:
For reference, here is some code I wrote to test the accepted answer:
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
float dc = 0.001f;
float lc = 0.025f;
float angle = MathHelper.ToRadians(45);
Vector2 vel = new Vector2(1, 0);
Vector2 pos = new Vector2(0, 0);
for (int i = 0; i < 200; i++)
{
Vector2 drag = vel * angle * dc;
Vector2 sideForce = angle * lc * vel;
//sideForce = new Vector2(sideForce.Y, -sideForce.X); // rotate 90 degrees CW
sideForce = new Vector2(-sideForce.Y, sideForce.X); // rotate 90 degrees CCW
vel = vel + (-drag) + sideForce;
pos = pos + vel;
if(i % 10 == 0)
System.Console.WriteLine("{0}\t{1}\t{2}", pos.X, pos.Y, vel.Length());
}
}
When you graph the output of this program, you'll see a nice smooth circular curve, which is exactly what I was looking for!
If you already have code to integrate force and mass to acceleration and velocity, then you just need to calculate the individual part of each of the two elements you're talking about.
Keeping it simple, I'd forget about the fin for a moment and just say that anytime the body of your rocket is at an angle to it's velocity, it will generate a linearly increasing side-force and drag. Just play around with the coefficients until it looks and feels how you want.
Drag = angle*drag_coefficient*velocity + base_drag
SideForce = angle*lift_coefficent*velocity
For the rudder, the effect generated is a moment, but unless your game absolutely needs to go into angular dynamics, the simpler thing to do is let the rudder control put in a fixed amount of change to your rocket body angle per time tick in your game.
I suddenly "get" it.
You want to simulate a rocket powered missile flying in air, OK. That's a different problem than the one I have detailed below, and imposes different limits. You need an aerospace geek. Or you could just punt.
To do it "right" (for space):
The simulated body should be provided with a moment of inertia around its center of mass, and must also have a pointing direction and an angular velocity. Then you compute the angular acceleration from the applied impulse and distance from the CoM, and add that to the angular velocity. This allows you to compute the current "pointing" of the craft (if you don't use gyros or paired attitude jets, you also get a (typically very small) linear acceleration).
To generate a turn, you point the craft off the current direction of movement and apply the main drive.
And if you are serious about this you also need to subtract the mass of burned fuel from the total mass and make the appropriate corrections to the moment of inertia at each time increment.
BTW--This may be more trouble than it is worth: maneuvering a rocket in free-fall is tricky (You may recall that the Russians bungled a docking maneuver at the ISS a few years ago; well, that's not because they are stupid.). Unless you tell us your use case we can't really advise you on that.
A little pseudocode to hint at what you're getting into here:
rocket {
float structuralMass;
float fuelMass;
point position;
point velocity;
float heading;
float omega; // Angular velocity
float structuralI; // moment of inertia from craft
float fuelI; // moemnt of inertia from the fuel load
float Mass(){return struturalMass + fuelMass};
float I(){return struturalI + fuelI};
float Thrust(float t);
float AdjustAttitude(float a);
}
The upshot is: maybe you want a "game physics" version.
For reason I won't both to go into here, the most efficient way to run a "real" rocket is generally not to make gradual turns and slow acceleration, but to push hard when ever you want to change direction. In this case you get the angle to thrust by subtracting the desired vector (full vector, not the unit) from the current one. Then you pointing in that direction, and trusting all out until the desired course is reached.
Imagine your in floating in empty space... And you have a big rock in your hand... If you throw the rock, a small impulse will be applied to you in the exact opposite direction you throw the rock. You can model your rocket as something that rapidly converts quantum's of fuel into some amount of force (a vector quantity) that you can add to your direction vector.

Categories