#2d character not sticking to slopes

1 messages · Page 1 of 1 (latest)

sinful palm
#

I wanted to make my 2d character stick to the ground. In my movement I get var velocity = _rb2d.velocity, do some stuff with it and then set the rigidbodies velocity to the var.

I got it to work, but adding acceleration somehow broke it. It works fine when working on flat ground fine, but when walking down or up a slope character moves at a snails pace
This is the code for slope forces:

                velocity = velocity.x * -Vector2.Perpendicular(hit.normal);
            else
                velocity = new Vector2((velocity.x * -Vector2.Perpendicular(hit.normal)).x, -2);```

(Move calculation is done right before the code above)
The move calculation which works fine:
```velocity.x = MoveDirection * Speed```
but this doesn't:
```velocity.x = Mathf.MoveTowards(velocity.x,Speed * MoveDirection, acceleration * Time.deltaTime);```

Again on flat ground fine, but not on slopes
celest cedar
#

Can you share the whole thing?

sinful palm
#

oh

#

the entire movement script?

celest cedar
#

Yes

sinful palm
sinful palm
celest cedar
#

What steps did you take to debug the issue?

pseudo canyon
#

@sinful palm Just making sure the issue is clear, the slopes work when you aren’t using MoveTowards() right?

sinful palm
#

I dont use MoveTowards at all, and haven't really tried it (it made for some glitchy behaviour cause im dumb)

celest cedar
#

Btw, I don't see you modifying or setting MoveDirection anywhere. So I'm not sure if you've omitted any code or that's the cause of the issue.

sinful palm
#

Im just setting the velocity directly at the end of each frame

pseudo canyon
sinful palm
#

yes

pseudo canyon
#

So it’s just the acceleration, not the slopes that’s the issue

sinful palm
#

reenabling acceleration makes the player character move extremely slowly up and down slopes

#

I guess so

#

but its fine on flat ground

#

only slopes break it

sinful palm
celest cedar
sinful palm
#

its 10 lines of code

#

I can post them too

celest cedar
#

It's already hard to follow what your code does now(or whether it's doing it correctly)...

sinful palm
#

Im sorry, I can try to explain

#

all the state code looks a bit messy, but it just sets the CurrentState enum

#

it appears to work fine when checking in the inspector

#

IsGrounded uses a box cast to check if the player is on the floor

celest cedar
#

What is CustomInput.HorizontalAxis?
Where is it defined?

sinful palm
#

CanJump is almost the same as IsGrounded but it checks for the state instead of raycast

sinful palm
#

but I can show it just in case

sinful palm
celest cedar
#

Ok, putting aside the fact that you should probably not split the code like that(where MoveDirection doesn't make sense within the base class itself),
you should debug some values and see what happens to them when the issue occurs.

#

Start from debugging the velocity and every other changing variable in it's calculation.

pseudo canyon
# sinful palm https://pastebin.com/VuC8Nr0s
_rb2d.sharedMaterial = CurrentState == CharacterState.IDLE ? Friction : NoFriction;```
I see this, and it makes me wonder if the slipperiness of the slope is canceling the velocity gain from your acceleration. Like:
  • FixedUpdate() // increase velocity by 1
  • InternalPhysicsCalculation() // decrease velocity by .9 because of slippery surface
  • Repeat()```
    Are you slow when moving down slopes or only up?
sinful palm
sinful palm
pseudo canyon
#

Ah ok, that was my only idea, I’ll step back 😅

sinful palm
#

yeah its so weird

#

like why would it make you move slowly downhill?

#

but I have tried debugging values. Everything seems fine, only thing is that the x of the velocity is way lower than it should be, like 9 times lower

celest cedar
sinful palm
#

oh

#

I just noticed something interesting

#

setting gravity to 0 made the slopes work fine with acceleration

celest cedar
sinful palm
#

atleast downhill, uphill is a little slow but I think your theory is correct

sinful palm
celest cedar
sinful palm
#

which values specifically?

celest cedar
#

Everything involved in velocity calculation

sinful palm
#

ok

celest cedar
#
Speed, MoveDirection, acceleration
#

As well as CanJump

#

and CurrentState

#

You should debug it all right before you set your velocity to the rb

sinful palm
#

acceleration is a constant number though

#

it doesnt ever change

#

alr

celest cedar
#

Then don't debug it.

sinful palm
#

ok getting OBS out now

#

wow

#

its such bad fps its a slide show

#

no idea why though

#

im sorry about that

#

also thanks guys for seriously trying to help

#

revelation!!

#

Turning of vsync makes the problem much worse

celest cedar
#

Next time use mp4 format so that we can view it in discord

sinful palm
#

its a deltaTime calculation issue it seems

sinful palm
#

the video is with vsync enabled so it doesnt seem that bad

#

but with vsync off the slow down is much greater

#

the higher the fps the worse it is it seems

celest cedar
#

What are you debugging and where? Share the new code with the debugs.

sinful palm
#

one thing before slope stuff and the rest before setting _rb2d.velocity

celest cedar
#

What is speed set to?

sinful palm
#

9

#

these are values im using for now, some tweaking will be needed later

celest cedar
#

Debug the hit.normal as well before using it in the CanJump if block.

sinful palm
#

it takes 30 seconds to load

#

so skip those

#

fps is set to 60 in obs

#

but its still like 5

#

...

celest cedar
#

Okay

#

So you say the issue doesn't happen when gravity is disabled?

sinful palm
#

yeah

#

atleast it seems like that

#

also why does it take so long to enter play mode, it used to take like 2 seconds

#

oh wait

#

with high fps it still happens

celest cedar
#

Okay, what happens probably, is that you're relying on the velocity of the character on the new frame. But that velocity is affected by gravity.

#

You should cache your desired velocity and use that as the baseline instead.

#

That would make other things more complicated of course. Like relying on the gravity and stuff for falling.

sinful palm
#

so I should do gravity calculation on my own?

celest cedar
#

That's one way to tackle it, yeah

sinful palm
#

what about the fact that fps somehow affects the slope issue?

#

ok so here's what I tried

#

I removed the velocity = _rb2d.velocity at the beginning of update

#

placed velocity outside Update so it doesnt reset every frame

#

and added this before slope stuff:
if (!CanJump) velocity.y -= _rb2d.gravityScale * Time.deltaTime * Mathf.Abs(Physics2D.gravity.y); else velocity.y = 0;

#

the issue is still here

#

its still tied to fps too

celest cedar
#

Hmm

#

Share the updated script

sinful palm
#

the only thign that really changed is that jump doesnt work (but thats to be expected until I somehow fixe it)

#

ok wait

celest cedar
#

Did you make any changes to PlayerMovement?

sinful palm
#

no

celest cedar
#

First of all, to tackle the frame dependence issue, you need to move the code to FixedUpdate

#

in the PlayerMovement as well

sinful palm
#

ok, Ill move both to FixedUpdate

#

and should I use fixedDeltaTime instead?

celest cedar
#

No, deltaTime in fixed updated is equal to fixedDeltaTime

sinful palm
#

so I should keep deltaTime?

#

seems kinda weird

#

but idk so ¯_(ツ)_/¯

celest cedar
sinful palm
#

Nice! You're so smart

celest cedar
#

It's not wierd. Delta time is how much time passed since last frame. In fixed update time passed between frames is always the same and equal to the fixed delta

sinful palm
#

its no logner tied to fps

sinful palm
celest cedar
#

It is mostly used for changing the fixed delta time.

sinful palm
#

I undid the velocity thing and it still works fine

#

one problem now is that the character doesnt respond to jump inputs most of the time

#

I guess I'll just move that part to update

#

Its almost perfect

#

Thank you @celest cedar for helping me come this far

celest cedar
#

Ok, I think I figured it out. It was why I was thinking there's something wrong with your code from the very start.

#

The issue is that you disregard the rotation of your velocity vector and always use it's x component for calculation at the start of the frame.

sinful palm
#

what do you mean

#

OH

#

MY

#

GOSH

#

I fixed it

#

it all works now

celest cedar
#

Damn, I was about to share a diagram I spend 15 minutes on drawing...

sinful palm
#

this is all that was needed

#

ouf, please share it still

sinful palm
#

you really helped UnityChanwow

celest cedar
#

Yeah, I think that's one way to fix it without changing your code. But it only makes it even less readable and thus prone to more issues like that.

basically, the issue is that you treat your velocity as rotated at the start of the frame. You use it's x component as the base to move it towards your ideal forward velocity(parallel to the slope). However, it's x does not represent that velocity. It represents the velocity parallel to the ground(basically disregarding the y component). This way you lose some potential velocity every time you calculate your new x velocity.

#

To put it simply, the issue is that you're doing math separately on different component disregarding vector rotation.
Usually you would not modify x and y of the velocity separately, but use vector operations. That or keep 2 separate variables. One representing the horizontal movement velocity and another the rotated vector based on the ground slope. This way you always calculate horizontal velocity properly and then you can calculate the actual velocity by multiplying the horizontal velocity by the movement direction vector.

sinful palm
#

oh

#

that makes sense

#

but I figured that modifying just the y should be enoigh to make the player stick