Here's how I do it. The method I use might be more complex than you need, but it's also very flexible:
All player characters, enemies and such are in a family called units.
I create an invisible object called base and put it in a family called bases.
All variables given to those objects are done by giving the families variables instead of directly to the sprites. This makes it easier to compare the values of two of the same object interacting with each other.
At the start of the layout, I create an invisible base object at each of their locations. I store the UIDs of the units/bases they're paired with as family variables.
I also create a shadow sprite. It's separate from the base for positioning purposes.
The base objects are the real controlling objects where most of the code happens. Because all the player characters, enemies and NPCs are controlled by the same type of object, it's easy to control them however I want by just changing their variables, like if variable mode = wandering, etc.
The part you're probably most interested in --> The base objects have the variables z and zModifier. The zMod variable is the speed of movement on the z axis (jumping in the air, visually it's the same as the y axis, the z variable is really just the distance between the base location on the ground and the unit in the air), and it is added to the z variable. When in the air, the gravity rate is always subtracted from zMod. When z is lower or equal to 0, the object is on the ground, and depending on the velocity in can be set to bounce.
Every tick, unit locations are set to base.x, base.y-base.z. Because of how construct works, as long as there are the same number of bases and units (destroy any in the layout before creating them for each unit) no for each is needed, and the units are all at the location of the correct base. I place the shadows at unit.BBoxLeft, base.y and set the shadow width to the unit width (the shadow hotspot is on the left).
Another benefit to this method is collision can be checked in 3D by first checking for collisions or distances between bases, then checking if their units are overlapping.
The main downside to this method is it requires a lot of for each loops in situations where construct's auto-picking doesn't work, but I consider the ease of use while coding and versatility to be worth it. If only C2 had containers that could be modified at runtime like CC had with the picker plugin... maybe C3 will have that feature.
I haven't checked your code, so apologies if I just explained most of what you're already doing, I just thought I should make it clear. Even if you don't want to use my method, perhaps the part about the variables will be helpful.
You can see this method in action in the gif in my sig. There are more including some of a flying enemy in the first post of Loot Pursuit's devlog.