Page 1 of 3

Experimental Smooth Crouch

Posted: Wed Apr 11, 2018 8:44 pm
by MeteoricDragon
I've been developing an experimental change for DFU. A smoother crouch. It has problems but it's kind of working.



Has 3 known bugs.
1) it's possible to rapidly crouch and cause yourself to drop through the floor.
2) it's easy to crouch yourself stuck in the doorframe and drop through the level when trying to crouch again.
3) the resulting crouch and stading height are not always precisely the same, but almost never noticeable.

I am really unsure why there is a problem dropping through the level, especially at the door.

I have nothing I can anchor the controller to. The controller height can be clamped between standingHeight and crouchingHeight as set in playerMotor. and a boolean can be set to true when one of those two limits are reached, and then the transform.position can be stopped too at the same time.
Using transform.localposition would be nice, but it does not work right because there is no parent transform for the controller.transform.

Code: Select all

    public enum CrouchToggleAction
    {
        DoNothing,
        DoStanding,
        DoCrouching
    }
    public class Croucher : MonoBehaviour
    {
        private CrouchToggleAction toggleAction;
        public CrouchToggleAction ToggleAction
        {
            get { return toggleAction; }
            set { toggleAction = value; }
        }
        public float toggleActionSpeed;
        private PlayerMotor playerMotor;
        private CharacterController controller;
        private float crouchHeight;
        private float standHeight;

        private void Start()
        {
            playerMotor = GetComponent<PlayerMotor>();
            controller = GetComponent<CharacterController>();
            standHeight = playerMotor.standingHeight;
            crouchHeight = playerMotor.crouchingHeight;
            toggleAction = CrouchToggleAction.DoNothing;
            toggleActionSpeed = 12f;
        }

        // perform whatever action CrouchToggleAction is set to.
        private void Update()
        {
            if (toggleAction == CrouchToggleAction.DoNothing)
                return;

            bool bFinished = false;

            if (toggleAction != CrouchToggleAction.DoNothing)
            {
                float changePerUpdate = toggleActionSpeed * Time.deltaTime;
                if (toggleAction == CrouchToggleAction.DoCrouching)
                    changePerUpdate = -1 * changePerUpdate; // reverse direction

                controller.height = Mathf.Clamp(controller.height + changePerUpdate, crouchHeight, standHeight);

                controller.transform.position += new Vector3(0, changePerUpdate / 2.0f);
                if (toggleAction == CrouchToggleAction.DoCrouching)
                    bFinished = (controller.height <= crouchHeight);
                else
                    bFinished = (controller.height >= standHeight);
            }

            if (bFinished)
            {
                //Debug.Log("Controller.height = " + controller.height);
                Debug.Log("Controller.transform.position.y" + controller.transform.position.y);

                toggleAction = CrouchToggleAction.DoNothing;
            }
        }
    }

Re: Experimental Smooth Crouch

Posted: Thu Apr 12, 2018 4:24 am
by Interkarma
I started with smooth crouch when I first put crouching in a couple of years ago. Encountered similar problems as you're experiencing now and opted for a more stable snap-crouch instead.

I'd rather not introduce movement problems or standing height issue if possible. The player's standing height is very tightly tuned to fit within the world and even then there a few sticky spots (e.g. coming back out of Sentinel throne area). I'd prefer for player's height not be adjusted unpredictably as this might introduce new controller sticking points beyond the ones we already have.

There's a full controller refactor that's been intended for a while now. I plan to tackle this a bit later in the 0.5 lifecycle. There's a few specific things I want to accomplish with this, as taking another look at smooth crouch is one of them.

As much as I appreciate the work, I'd prefer the general stability of the current snap-crouch over possibly introducing more movement problems at this time. :)

Re: Experimental Smooth Crouch

Posted: Thu Apr 12, 2018 6:50 am
by ifkopifko
Hey there, not sure whether it will make sense, but maybe you could add the "smoothness" by moving the camera. The "controller" (whatever that means) could still use the "snap crouch".

Also, to get rid of the variability of resulting crouch and stading height, you might add a line to set the hight accordingly (precisely) after the smoothing movement is finished.

Re: Experimental Smooth Crouch

Posted: Thu Apr 12, 2018 7:08 am
by Interkarma
Those are all good suggestions, thank you. :)

I'll leave it up to Meteoric Dragon if he wants to keep progressing and refining this. As long as there's an option to toggle, and there's no substantial changes to baseline, I'm supportive of the work and would be happy to merge it.

Re: Experimental Smooth Crouch

Posted: Thu Apr 12, 2018 10:25 am
by ifkopifko
Hah, my post was meant for Meteoric Dragon, sorry for not making it clear. I would never dare to lecture you in matters of programming, as I am not a coder myself. :oops: :D (Although I know you are not the kind to get offended easily.)

Re: Experimental Smooth Crouch

Posted: Thu Apr 12, 2018 3:26 pm
by MeteoricDragon
Interkarma wrote: Thu Apr 12, 2018 7:08 am Those are all good suggestions, thank you. :)

I'll leave it up to Meteoric Dragon if he wants to keep progressing and refining this. As long as there's an option to toggle, and there's no substantial changes to baseline, I'm supportive of the work and would be happy to merge it.
Thanks for your feedback and the recounting of your efforts in the past. I think I have a few more ideas before I put this project on hold. If i do get it working i'll make sure to make a setting to toggle it.

Re: Experimental Smooth Crouch

Posted: Thu Apr 12, 2018 3:58 pm
by delvisomanda
This is a off topic answer, but seeing that you know programming, there are other ideas I would like to see in DFU, which I think are not too impossible or too fantastic, but which would improve the game in general.

- Discover places on the city map, while loitering.
- An autorun key
- Funtional torches or candles

To give just a few examples.

Re: Experimental Smooth Crouch

Posted: Sat Apr 14, 2018 1:27 am
by MeteoricDragon
I've got somewhat interesting results to report.

I made a workaround for the bug. It's still possible to get pinned into a door by crouching or standing in a specific spot there. but now I've got it so that the player can press in any direction and rapidly tap crouch and he can "wiggle" out of the spot. I intend to test more and see if I can get better results. If I can't, then oh well. no big deal.

Re: Experimental Smooth Crouch

Posted: Thu Apr 19, 2018 2:31 pm
by MeteoricDragon
Changing the controller.transform.position changes the main camera position too because I guess they are connected somehow. Is there a way in code to disable that connection and then re-enable it? I'd like to move the PlayerController independently of the camera for just a few lines of code.

Re: Experimental Smooth Crouch

Posted: Thu Apr 19, 2018 10:49 pm
by Interkarma
The camera is a child of the controller object, so moving controller will also move camera. But you should be able to transform camera's localPosition like ifkopifko's suggestion then perform snap crouch. Here's the breakdown, but not sure how well this work in practice as other scripts (like headbob) might also be controlling the camera so need to make allowances for that.
  • When player initiates crouch, break this motion into two stages.
  • During first stage, just lerp camera to desired end position. Basically camera eye height is lerped down into the capsule towards player's waist.
  • In the second stage (after smooth camera movement) perform same snap crouch as now and reset camera position back to normal eye height.
  • Reverse process when standing up.
The end result should be a smooth camera movement followed by a snap crouch and camera reset in same frame. With a bit of tuning, it should look pretty good. But keep in mind I haven't actually tried this method, and I'm a bit worried about other scripts controlling camera.

Another small improvement would be to perform a ray check up from top of player's head before standing back up to ensure they have head room. This will prevent them from standing up under low bits of geometry and poking their heads through the geometry. This is more of a general improvement to crouch though, rather than anything to do with smooth crouch.