(click for embiggen, it’s a big pic)

]]>Indie Bubble Buts: What Do We Do Now?

It skips past the increasingly tired question of “INDIE BUBBLE!?” and goes straight to: so what do we do now. Practical advice and discussion starters that hopefully stave off the sense that the sky is falling – because it isn’t. The sky is fine, and so is your indie game, so long as you’re not wearing blinders.

]]>So, here’s what this giant mess does. Let’s say you have a bird moving in a direction. What this does is apply that movement, and then any time it gets bumped, it corrects against the bump and then keeps flying in the same direction. If you bump it IN the direction it wants to go, it uses that to get itself up to speed, but, if you bump it faster than it wants to go? Then it slows down to its target speed, at the same rate it counters against other bumps.

The reason I’m sharing it is because it took ages to debug… and eventually the bug wasn’t even in this code, it was elsewhere in the AI / a really stupid problem related to behavior that didn’t make sense for a flyer. But upside! I went over this code with a fine-tooth come, and it’s SUPER slick now. HOORAY!

`// First, figure out how much additional velocity we're applying, and apply it`

Vector2 additionalVel = moveInput * MoveVelocityPerSecond * deltaTime;

```
```curSideVelocity += additionalVel;

Vector2 preDampeningVel = curSideVelocity;

// Now, we want to dampen out any velocity that isn't in our currently-desired move direction

Vector2 desiredMoveDir = additionalVel;

desiredMoveDir.Normalize();

Vector2 curSideVelocityDir = curSideVelocity;

curSideVelocityDir.Normalize();

// We want the perpendicular vector against which to decompose the curMoveDir into "desired" speed and "not desired" speed

Vector3 desiredMoveDir3D = Vector3.zero;

desiredMoveDir3D.x = desiredMoveDir.x;

desiredMoveDir3D.y = desiredMoveDir.y;

Vector3 curSideVelocityDir3D = Vector3.zero;

curSideVelocityDir3D.x = curSideVelocityDir.x;

curSideVelocityDir3D.y = curSideVelocityDir.y;

Vector3 temp3D = Vector3.Cross(curSideVelocityDir3D, desiredMoveDir3D);

temp3D.Normalize();

temp3D = Vector3.Cross(desiredMoveDir3D, temp3D);

Vector2 notDesiredMoveDir = Vector2.zero;

notDesiredMoveDir.x = temp3D.x;

notDesiredMoveDir.y = temp3D.y;

notDesiredMoveDir.Normalize();

// Now, we just dampen out any velocity along the perpendicular vector, in a time-relative manner

Vector2 notDesiredMoveVec = Vector2.Dot(notDesiredMoveDir, curSideVelocityDir) * curSideVelocity.magnitude * notDesiredMoveDir;

float dampenAmount = FlyingDampeningAirVelocity * deltaTime;

if (IsGrounded())

{

dampenAmount = FlyingDampeningGroundVelocity * deltaTime;

}

// Now, apply the dampening along the perpendicular axis

if (notDesiredMoveVec.magnitude > dampenAmount)

{

curSideVelocity -= dampenAmount * notDesiredMoveDir;

}

else

{

curSideVelocity -= notDesiredMoveVec;

}

// We also want to dampen out the velocity that's perfectly opposite our desired movement

Vector2 backwardMoveVec = Vector2.zero;

if (Vector2.Dot(-desiredMoveDir, curSideVelocityDir) > 0.0f)

{

backwardMoveVec = Vector2.Dot(-desiredMoveDir, curSideVelocityDir) * curSideVelocity.magnitude * -desiredMoveDir;

}

if (backwardMoveVec.magnitude > dampenAmount)

{

curSideVelocity -= dampenAmount * -desiredMoveDir;

}

else

{

curSideVelocity -= backwardMoveVec;

}

// We ALSO need to dampen movement in the forward direction that goes above our speed limit

Vector2 forwardMoveVec = Vector2.zero;

if (Vector2.Dot(desiredMoveDir, curSideVelocityDir) > 0.0f)

{

forwardMoveVec = Vector2.Dot(desiredMoveDir, curSideVelocityDir) * curSideVelocity.magnitude * desiredMoveDir;

}

`if (forwardMoveVec.magnitude > (MaxFlyingSpeed + dampenAmount))`

{

curSideVelocity -= dampenAmount * desiredMoveDir;

}

else if (forwardMoveVec.magnitude > MaxFlyingSpeed)

{

curSideVelocity -= desiredMoveDir * (forwardMoveVec.magnitude - MaxFlyingSpeed);

}