Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags
(4 edits) (+5)

(hi zoe here ;P) just to give a little extra technical detail or whatnot, the essential idea is that you slow the player as they approach some sort of central point, so that they approach it kind of asymptotically. it's convenient to place this point at the origin (0,0,0) so we did that in this case.

also, we measured the player's distance from the origin "floorwise" (ignoring height) because we put them on a fixed track on the height axis: at the start of the game we imagine a straight line between the player's starting position and the origin, spin that around into a cone with its tip at the origin, and set the player's height along that cone based on their distance from the origin. this trick allowed Lily to arrange the geometry in a more "choreographed" fashion since it allows you to predict how high up the player will be at any point.

also, as a little final touch, it felt right to me to narrow the player's field of view somewhat as they approach the origin (specifically we had it approach half of its starting value, which we figured out by feel). i reasoned that if you were actually shrinking to a smaller size but otherwise staying the same shape, your eyes would move closer together which i think would slightly narrow your field of view. (of course if you turned into a mouse or something your field of view would actually increase…but that's another topic…)

anyway, here's a step-by-step description of how the whole technique works in this game:

  1. Arrange the 3D space so that the origin (0,0,0) is wherever you want to zoom in furthest. The basic idea is that we'll slow player's movement speed more and more as they approach this point. You can cluster geometry very tightly in that area when you're placing your models because they'll glide through it at a quite leisurely pace.
  2. Pick somewhere you want the player to start. When they start out, we'll have them move at the normal speed, and move faster as they move away from the origin from the start, and slower as they move towards the origin from the start. We'll also set their height based on their starting point and their radial distance from the origin.
  3. We can calculate a few values at scene load time to save work in the main loop. These are:
    1. H₀, the player's starting height, which in Unity is their Y-axis position,
    2. D₀, the player's "floorwise" distance from the origin, which in Unity is the magnitude of the player's XZ position vector,
    3. r = -H₀/D₀,
    4. M₀, the player's starting movement speed, and
    5. F₀, the player's starting field of view.
  4. Each frame, we:
    1. calculate Dᵢ, the player's current "floorwise" distance from the origin, i.e. the current magnitude of the player's XZ position vector,
    2. calculate d = Dᵢ / D₀, the ratio of the player's current distance to their starting distance,
    3. set the player's movement speed to Md,
    4. set the player's height to (Dᵢ - 2D₀)r + H₀, and
    5. set the player's field of view to F(d + 1)/2.

as she alluded to the code Lily posted is messier than this description since it's basically in the state we left it in after playing around it with it for a while and deciding we were happy with it. if you'd like a tighter code sample following this description i don't think it would be much trouble for me to write.

anyway, for other ideas branching off of this, in theory you could have mutiple focal points and set the player's speed based on their distance to all of them; the math would be a little thornier but the basic idea could stay the same. also, regarding range of motion, you could measure the player's distance from the origin on all three axes and let them move noclip style for a more "open world" approach, or you could have them move only on one axis which would make the game into a sort of endless tunnel. i think you could also have an interesting "4D" approach where you transform all the geometry based on the player's rotation around the origin.