x


Collision Flags on Character Controller flip between Below and None

I am playing with the Unity Standard Asset Third Person Controller, which utilizes the CharacterController.

I have s separate scripts that is supposed to work while the CharacterController is grounded.

On Update, the character Controller's collision flags seem to jump between CollisionFlags.Below and CollisionFlags.None.

When I walk uphill, the flags stay set to below, but going downhill standing still seems to flit between Below and None every update.

Is this a known behavior? I am almost certain the the third person Controller has not been changed...

more ▼

asked Mar 19 '12 at 05:44 AM

Avaista gravatar image

Avaista
499 8 24 31

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

I don't have time to test right now, but I'd guess it's standard behaviour of the character controller - you're trying to move forwards using your inputs, which constantly puts the character slightly above the ground so he falls slightly down.

What we did in a game where you had to be able to slide down hills was write additional code to modify the character's y position according to the slope of the ground. This forced him to stay grounded.

more ▼

answered Mar 19 '12 at 07:09 AM

davedx gravatar image

davedx
138 1 1 3

(comments are locked)
10|3000 characters needed characters left

So I think I discovered the reason that the collision flags were being flipped.

Unity Standard Asset ThirdPersonCharacterController applies gravity like so:

function ApplyGravity ()
{
    if (isControllable)    // don't move player at all if not controllable.
    {
       // Apply gravity
       var jumpButton = Input.GetButton("Jump");


       // When we reach the apex of the jump we send out a message
       if (jumping && !jumpingReachedApex && verticalSpeed <= 0.0)
       {
         jumpingReachedApex = true;
         SendMessage("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);
       }

       if (IsGrounded ())
         verticalSpeed = 0;
       else
         verticalSpeed -= gravity * Time.deltaTime;
    }
}

Basically gravity is only applied if you are not connected to the ground. Makes sense.

But the collision flags are based off of the movement. When the controller moved with 0 in the y, it did not hit the object beneath it, meaning that the controller was not grounded. On the next Apply gravity, because the object was not grounded from the last move, it applies the gravity, which meant now the controller was grounded, meaning the next time around verticalSpeed was set to 0, and would not hit collider again. This loops.

I can't imagine this is intended behaviors, though I noticed that when I commented out the if else and always applied gravity, the checks were consistent, but the character controller dropped like a brick once you stepped off of a platform, which makes sense(gravity was "accumulating" while on the platform).

I switched it to verticalSpeed = -.001; and it worked well enough, with the flags stating that their was a hit below each frame, while not having the character drop like a brick. Sadly, I found a better way of going about what I was doing(in terms of needed to know if the controller was grounded or not)

@davedx Thank you for your answer!

more ▼

answered Mar 19 '12 at 08:40 AM

Avaista gravatar image

Avaista
499 8 24 31

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x702
x11

asked: Mar 19 '12 at 05:44 AM

Seen: 911 times

Last Updated: Mar 19 '12 at 08:40 AM