I've made great strides recently in my first serious Unity project. However, I've tried to wrap my head around jumping and I can't for the life of me figure out how to do it. It seems simple in theory, but when it comes time to create it, a lot of problems hit me, like how to control the exact height of the jump, how to determine if your character is still airborne, how to pull a CharacterController down with gravity, how to determine if you've landed on flat ground and not against a wall, etc... it suddenly becomes complicated, and even overwhelming.
I need help with the logistics of how a solid jump should be constructed. A solid jump meaning no infinite jumping and things like that.
My Update function for my movement script is getting massive and cluttered as it is. Should I be doing it in a separate script as well?
Should also mention that I've looked at the script reference but it seems like a very "dirty" jump script (not to mention it uses "isGrounded", which in my experience does not work reliably at all; it only says that the controller is grounded if it's not moving at all, even if it's sliding around the ground but still touching the ground).
In my experience with gameplay programming there is no real easy way to do it.
Depending on how you want your jump to look and act will determine how you go about it because there is tons of ways to accomplish it.
A quick easy way is if you have rigidbody on your player. Just add an upward force. Let gravity take over and to the work to bring you down. If this is not what you are going for you could also try using some quadratic equation.
There are going to be a ton of checks you are going to have to do like checking if the player is grounded, as you mentioned. If Unity does a poor job you could always right a function to check if the player is grounded abased on certain conditions... height, collision, distance from terrain to character, up to you really.
I wish I had done this task specifically for Unity. But my experience with this particular subject is with other engines. I hope the info I provided at least helped.
For anyone else who is curious, the method I used to perform a jump goes as follows (using logical terms):
-Player falls to the ground. A hit normal report of 1.0 on the Y axis confirms he is grounded.
-Player presses a key.
-An empty game object with nothing but a transform named "jumpheightmarker" or something similar is instantiated above the player's current Y value at the maximum jump height (though in retrospect you could also just assign this Y value to a variable).
-Boolean is enabled that tells the player to ascend.
-Player ascends and does not stop until his controller's hit normal reports back -1.0 Y (hit his head on a ceiling) or until his Y value is greater than or equal to the Y value of the jump marker.
-Player descends, not through any fancy scripting, but through his natural gravity.
I also applied a simple one-time check on collision with the ground to resume the idle animation, and an Update check to see if you jumped and haven't yet fallen to the ground, which keeps you crossfaded into a "jumping/falling" type pose.
All I ever do for jumping (since I use rigidbody characters) is Adding Force through ForceMode.VelocityChange a single time. A character's legs are able to force him into the air at a certain power, and gravity pulls him down naturally. It does take a little math to figure out exactly how high the force will take him, but I find it's a good, simple solution.
This way, if you had any low-gravity places, that force will carry your character higher too.