A couple days ago I felt lost. And I still do. I had no idea where to start. Eventually I came up with this code. I`m creating an additional vector that points in the opposite direction of where the obstacle is. If I move using this vector I can make some room between the unit and the obstacle, which then allows me to move a little bit towards the required path node using the initial vector. It works but it appears ugly. The unit doesn`t have a constant speed while going around the obstacle. Also I haven't tried yet but my guess is that the unit will get "confused" if there are several obstacle units next to each other, which I guess is the main problem
if (useInitialVec)
{
float VectorX = NextNodeX - UpixPosX;
float VectorY = NextNodeY - UpixPosY;
float VecLength = sqrt(VectorX * VectorX + VectorY * VectorY);
float SpeedPercent = (0.016 * 100) / VecLength;
float AdvanceX = (VectorX * SpeedPercent) / 100;
float AdvanceY = (VectorY * SpeedPercent) / 100;
float DesiredX = UpixPosX + AdvanceX;
float DesiredY = UpixPosY + AdvanceY;
float DesCDtop = DesiredY - unitsize / 2;
float DesCDbott = DesiredY + unitsize / 2;
float DesCDleft = DesiredX - unitsize / 2;
float DesCDright = DesiredX + unitsize / 2;
bool CDTest = CDCheck(id,&obstacleid, DesCDtop, DesCDbott, DesCDleft, DesCDright);
if (CDTest == false)
{
UpixPosX = DesiredX;
UpixPosY = DesiredY;
}
else
{
useInitialVec = false;
}
}
else
{
useInitialVec = true;
float ObstX;
float ObstY;
GetObstPos(obstacleid, &ObstX, &ObstY);
float VectorX = UpixPosX - ObstX;
float VectorY = UpixPosY - ObstY;
float VecLength = sqrt(VectorX * VectorX + VectorY * VectorY);
float SpeedPercent = (1 * 100) / VecLength;
float AdvanceX = (VectorX * SpeedPercent) / 100;
float AdvanceY = (VectorY * SpeedPercent) / 100;
UpixPosX = UpixPosX + AdvanceX;
UpixPosY = UpixPosY + AdvanceY;
}
Yeah, that's the right kind of thinking.
The first thing i notice in your code is that you use logic where it isn't needed.
Maybe because you are used as a programmer to think in logical if else terms.
But this is not how simulation works.
And it's not what you want either, since logic requires a from of intelligence. Yours actually, but you are not there when the player plays your game, so eventually your predefined decision tree won't work well in dynamic, unpredictable cases.
That's the primary reason why we do simulations. We want to minimize and replace complex logic with simple laws of physics, which feel natural and predictable because they imitate real world laws of physics.
This does not mean you need to read textbook about physics. Physics does pretty much what you have said in your quote. So by just following your intuition, you will arrive at natural laws of physics anyway.
But non the less - physics is useful. It helps to know about it. It increases awareness about things which feel subconsciously natural, but then are not as easy to reproduce with code as thought.
So i'll give a little primer on physics, focusing on which aspects matter to us for what.
To follow real world physics, you would define a unit somehow like this:
(I just get a flashback - did i already gave this tutorial some time ago? Anyway, moving on…)
A unit moves along its velocity vector. (Well, my unit is one dimensional, so there is no vector. It can only move on a global line. But you would use x,y or a vec2 for each variable. The math remains the same otherwise.)
The longer the duration of movement, the larger the displacement, obviously.
Which is simple math:
You do this indirectly.
But you obfuscate the simple math with bad terminology and redundant equations such as (1 * 100) / 100.
Make it easy for your brain to learn! Remove the redundant math, and adopt the same terminology we all use. So you can read and apply our tutorials, learning easier and faster.
Be nice to your brain! ; P
So now we have defined movement like nature does it (accepting some piece wise approximation of nature, so we con turn equations into executable math).
But how does movement change in nature?
If two rocks collide, do their positions change in an instant moment?
No. this would be like teleporting. Star Trek. Nature is not like that.
Do their velocities instantly change?
No, neither. Nothing changes instantly in nature. Any change is smooth, if we look at it close enough. Because it takes time until the energy from a cause can generate some effect.
So what do we do to achieve such smooth change over time?
We apply a force to an object. Force causes acceleration, and acceleration is the change of velocity.
Yes, this is the point where it gets confusing. But it is what it is.
Let's add it:
The math is still simple.
But to understand what happens we need to draw curves on paper, or better: Make a program and observe how it behaves over time.
Nobody can explain it to you, so experimentation is key!
Now, being game devs, we can do what we want. It helps to know laws of physics, but we don't have to respect them if we don't want to.
So we might eventually do things like this:
If a unit collides with a static wall, we might change it's position directly to resolve penetration. (Incorrect, but it might work and do what we want.)
If a unit moves too fast for whatever reason, we might clip its velocity to some given max value. (It's incorrect to change velocity directly, but we don't care.)
If a unit comes too close to another unit, we might apply acceleration to both units to separate them smoothly over time. (Correct! But be warned: Controlling objects with acceleration is much harder than the other 2 options.)
That's no concrete advise on what you should do. I just want to increase your awareness about what it means to affect a system that changes over time in a simulation. What's the options, and what's the difference between them.
You should adopt the equations and related terminology as soon as possible.
Because those equations are already reduced to minimal complexity. It's the best you can get.
Following your own intuition would bring you to the same realization after some time, but till then it's all vague, uncertain, and thus:
Nothing wrong with what you do. But you can take shortcuts. ; )