Character Controller Crouch With transform.localScale Problem.

I am trying to make my first person character crouch, I first attempted by changing the height value, but it didn’t bring the rest of the objects attached to my character such as the camera, down with it and it caused it to fall through terrain.

Now I am trying to use transform.localScale, after having moved the center of my Character Controller object down to its feet it scales correctly on the y axis in scene view when using the inspector menu.

However when I attempt to use transform.localScale in the actual game view via script, it scales on both ends of the y axis, which is not what I want to happen.

The problem that bugs me the most is, as you can see in the video how my character falls off ledges when “un-crouching”.

I have included a video and my code, if anyone would be able to help I would greatly appreciate it :).

Code using System.Collections;using System.Collections.Generic;using UnityEngine; - Pastebin.com

Video help :) - YouTube

First of all, please post the code here instead of using external resources or screenshots. Use the 101 010 button in the post input field to format the code to get it displayed like this

SomeMethod() {
    Some Code;
}

There’s no guarantee that the code pasted on an external resource will be available in the future, so if someone will google a question similar to yours, they won’t be able to see the actual code snippets if we all use pastbin or anything else to show the code.


Now to the question.
Yeah, when you change a transform y scale it’s center point doesn’t change and the transform is getting scaled on top and bottom simultaneously. That’s just how it works and you can’t change this behavior. And you shouldn’t adjust the center point as you did, because it will produce more problems than it solves in the future.
To fix your problem you could adjust the capsule position manually to keep its bottom point on the floor right after you change the scale.
A bit of simple math:
You have a capsule with height 1 that is standing on the floor.
Now you change the capsule y scale from 1 to 2. And the distance between the capsule’s bottom point and the floor is now equals to halfOfNewHeight - halfOfOriginalHeight = (2 / 2) - (1 / 2) or (newHeight - originalHeight) / 2.
And to keep the capsule on the floor in the next frame when the engine will render it with new scale, you need to change the character’s position by that difference distance from the floor right after you change the scale.
So, do something like this:

float originalScale = transform.localScale.y;
transform.localScale = new Vector3(0.66f, 0.7f, 0.66f);
float difference =
    (transform.localScale - originalScale) / 2f;

This is the distance difference. Note that it might have a negative value when you scale the character down from 1 to 0.7 ( 0.7 - 1) / 2 = -0.15. That’s good, because this allows us to use the same formulas to adjust the character position in both cases: when it scaled down and needs to be moved down, or it scaled up and needs to be moved up.
Now you can use it to put the character’s bottom to the same position as before the scaling:

transform.position += Vector3.up * difference;

This code means: use the Vector3.up which is the world space vector that points up and it’s length is 1 unit, multiply it by the difference we got to get a vector that represents some change in position with the given length/distance along the world up direction. So, if we got 'difference = 0.15then this code will move thetransform.positionup for 0.15 units. And ifdifference = -0.15` then the position will be moved down by 0.15 units.