Experimental Smooth Crouch

Discuss coding questions, pull requests, and implementation details.
User avatar
MeteoricDragon
Posts: 141
Joined: Mon Feb 12, 2018 8:23 pm

Experimental Smooth Crouch

Post 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;
            }
        }
    }

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Experimental Smooth Crouch

Post 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. :)

ifkopifko
Posts: 195
Joined: Thu Apr 02, 2015 9:03 am

Re: Experimental Smooth Crouch

Post 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.

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Experimental Smooth Crouch

Post 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.

ifkopifko
Posts: 195
Joined: Thu Apr 02, 2015 9:03 am

Re: Experimental Smooth Crouch

Post 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.)

User avatar
MeteoricDragon
Posts: 141
Joined: Mon Feb 12, 2018 8:23 pm

Re: Experimental Smooth Crouch

Post 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.

User avatar
delvisomanda
Posts: 84
Joined: Mon Jan 08, 2018 4:29 pm
Location: Argentina

Re: Experimental Smooth Crouch

Post 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.
Currently translating Daggerfall into Spanish.

User avatar
MeteoricDragon
Posts: 141
Joined: Mon Feb 12, 2018 8:23 pm

Re: Experimental Smooth Crouch

Post 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.

User avatar
MeteoricDragon
Posts: 141
Joined: Mon Feb 12, 2018 8:23 pm

Re: Experimental Smooth Crouch

Post 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.

User avatar
Interkarma
Posts: 7236
Joined: Sun Mar 22, 2015 1:51 am

Re: Experimental Smooth Crouch

Post 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.

Post Reply