Why is my character is sliding (when it's not supposed to) and the gravity not working right?

As you see in the video, in some surface/inclines character is sliding, as if it is falling down and just sliding on a buldings surfaces, instead just walking.

The character is rotating here not map, and, everytime the player presses Space key, gravity must be modified via line trace, it simply takes impact normal and that’s it.

So if I understand correctly whatever surface the line trace hit, no matter it’s incline, the character must be able to move along it perfectly normally, but it’s not the case yet.

Thanks for you guys for your helps in advance :slight_smile:

@Mind-Brain @gardian206

Hey @NEYSE_O001!

The gravity “not working right” is because your capsule component is still there with collision on. You need to select it, go to “collision” in the details and set it to “No Collision”.

Then, select your NEW collision (the little box) and set it to collide with what you need (you could just use the “Pawn” preset).

The sliding is in your Character Movement component under acceleration, max speed, and braking. :slight_smile:

2 Likes

if the AboveArrow is attacked to the root component, why are you setting its rotation in addition to setting the gravity, ALL SceneComponents that are attached to the RootComponent will be rotated based on the Gravity.

you are also setting the Relative Rotation of the SceneComponent to be based on a World PoV Normal vector (look at what these changes are actually doing: for the AboveArrow in Rendering→HiddenInGame = false)

  • if the actor currently has its gravity set to the default of -Z, then the AboveArrow will have an orientation pointing exactly Up
  • if the actor then has its gravity set to a <1/sqrt(2),1/sqrt(2),0> ( ~.707) gravity the Up Vector SHOULD be <-1/sqrt(2), -1/sqrt(2), 0>, which is what the world ForwardVector of the AboveArrow would be just before you set its RelativeRotation
  • the new world ForwardVector of the AboveArrow would close to (floating point approximation not withstanding) < -sqrt(2),-sqrt(2),0> (~1.414 ) which would be pointing to the left (because a zero-rotator would be pointing forward, and the windings of a unit circle in trig goes counter clockwise)

the current UpVector of an actor for the purpose of your line trace can be obtained in a couple ways not requiring you to hold an ArrowComponent (keep it for editor visualization but don’t rotate it, and you don’t need to actually reference it, and probably mark it as EditorOnly)

  • Negate(GetGravityDirection()) from MovementComponent
  • GetCapsuleComponent→GetUpVector() // in most cases the CapsuleComponent is the RootComponent, so therefore its transform is the Actor's Transform

keep in mind that the UpVector is defined in World space that is why you don’t need to convert it into world space to do your line trace.

try drawing your vectors using DebugDrawLine. I have a strong feeling that your gravity is pointing in a different direction then you believe

// these do not need to be actual variables, labels are for text.
// this is directly doable in Blueprints
Tick()
{
    VectorA = GetActorLocation() + <100,100,100>
    VectorB = VectorA + (100.0f * GetGravityDirection())
    DrawDebugLine ( VectorA, VectorB, Yellow) 

    VectorC = VectorA + (100.0f * GetCapsuleComponent()→GetUpVector())
    DrawDebugLine ( VectorA, VectorC, Pink)

    //and for sanity sake add this too see actual gravity
    VectorD = VectorA + (100.0f * FVector::DownVector) // <0,0,-1>
    DrawDebugLine(VectorA, VectorD, Green)
}

I have a strong feeling that it looks like it is sliding to the side because your GravityVector is not oriented properly.

are you using the Box2D physics, or are you using the 3D physics system? the Box2D physics system might be overriding your character’s orientation to be alternative to the Gravity based UpVector, and therefore it looks like you are sliding to the side.

2 Likes

capsules components in a gravity frame will only slide if the angle of incline relative to gravity is greater then “inclineMax” which is the behavior of all colliders set to Collide with WorldStatic and WorldDynamic, so even a BoxCollider would slide as well if the angle of the surface relative to Gravity frame is greater then “InclineMax”

1 Like

Ah, I didn’t catch the first part of the video being “Normal” gravity behavior. Yes, it’s almost like it’s sliding against a wall during a jump.

1 Like

Yes, I am using that Arrow Component to set a forvard vector in the name of all components practically.

I am certainly not good at bp math as you are but theoretically does not the current system makes sense? It already, at least as seems works in mostt situations? I am pretty sure there is much better ways to achieve that but in regards of math I don’t see anything wrong. Enlighten me please.

you - the current UpVector of an actor for the purpose of your line trace can be obtained in a couple ways not requiring you to hold an ArrowComponent (keep it for editor visualization but don’t rotate it, and you don’t need to actually reference it, and probably mark it as EditorOnly)

me - I didn’t understand this part. So the resoult in final export project and editor could be different you mean?

The physics it’s not Box2D, it’s standart 3d physics I didn’t use any physics assets, plugins or anything. But also this means your theory (which I am apprechiated for) can’t be completely right.

(edit) the main problem (because there are many problems) could be simplly because the cylinder collision is above the arrow component and not rotating with it, so in some inclines surface hits the beveled area and make the character slide. I certainly have to fix at least this one.

(post deleted by author)

Yes I didn’t calibrate the collisionn properly, so you mean it’s simply, the character is sliding because the surface is hiting the beveled area? Yeah it could be really that simple at least partially.

please… your math doesn’t work, and it is the smaller set when it does. This isn’t “Blueprint Math” this is Trigonometry. Blueprints are meant to make these systems easier to work with, so in order to get your game idea to existence isn’t locked behind multivariate calculus based physics, and 2 years of Programming.

the tick function to validate directions (for the most part if we are on the axis angles I expect to see maybe 2 or 3 lines)

the assignment, and your proposed ArrowComponent→SetRelativeRotation()

for the rotations of the cubes pay attention to the Rotations about Y (the green accented box)

during the play session pay attention to the arrows direction, and the behavior of the sliding.

1 Like

@Mind-Brain I oppened a different post for it already actually but I will ask to you here because it’s releated. I can’t use box collision, it’s allways skiping tru surfaces, the character can’t use any other coollisions here except capsule component. I think there may be some way to fix this via c++, I’ll leave the recomendations to you.

an ACharacter (more specifically UCharacterMovement) has the assumption of a CapsuleComponent (CapsuleCollider) as the rootComponent (this is why you can’t replace the Capsule, and why you are not allowed to swap it), and a SkeletalMesh connected directly to the CapsuleComponent (there is a secondary assumption that the SkeletalMesh is humanoid or at the very least Bipedal) and fits inside the CapsuleComponent.

even a PawnMovement component will have some presumption of a CapsuleComponent, meaning to get around these presumptions you would have to go back to Actor, and build back up everything Pawn and character does (it isn’t worth it)

The Gravity effect of the CharacterMovement is applied directly to the CapsuleComponent in the C++, so the RootComponent that has NoCollsion set as the response is now having gravity being applied to it, which causes the RootComponent to fall, then the BoxComponent that is being blocked by WorldStatic and WorldDynamic by default will be stopped from falling by the “ground”. Then the Camera which is attached to the now Box will attempt to focus on the RootComponent based on its offsets, which is in freefall.

the Type of collider (CapsuleComponent) and its default collision profile is not the issue and never was. your character is being rotated to its new arbitrary gravity, but then being rotated again somewhere else, and that is not the default behavior of CharacterMovement.

1 Like

Man I am really apprechiated for your help and admire your deep understanding of the software but I am too rokie to convert this theoretical knowledge to parctice and implementing.

Can you give me a couple of more hints about how can I get this problems fixed? Anything bossible.

first we need to determine if my hypothesis is valid or not:

  • out of your LineTrace to find the new gravity direction either draw an arrow, or Line showing the direction of the Normal Vector at the Impact point, and draw it for like 2 to 3 seconds.
  • in your tick function draw the character’s Gravity Direction, the CapsuleComponent’s UpVector, and the WorldGravity (<0,0,-1>)
  • for both of these look at post9 in this thread where I do this directly.

now when you do your tests every time you change gravity just compare the lines, what you should see is that the line for your GravityDirection, and your UpVector should always be “opposite” of each other, and that the UpVector should be “the same” direction as LineTrace.NormalVector

to try and figure when the change is actually happening we are going to be spamming the Log a little bit:

  • in your event for changing the gravity right before the gravity assignment put a PrintString
  • for the string that will be output pull out from the pin and select “Append” to save lines we will be putting several things into this, and so we can prune later if we need to go deeper.
  • PLEASE LABEL these, and remember you will need to manually adding spaces and separating punctuation (you can add more lines for the Append with the “Plus icon”)
  • pinA: “Grav change::Hit Location: ” pinB: The HitLocation from the HitResult
  • pinC: “; Current Up: ” pinD: CapsuleComponent→GetUpVector() (because this is before the assignment we see what the current UpVector should be)
  • pinE: “; Hit Normal: ” pinF: the NormalVector for the hitResult (promote this to variable so we can use it in the Tick)
  • pinA, pinC, and pinE are actual strings, and pinB, pinD, pinF are putting those values directly into the pin

now for the really spammy part:

  • in Tick() at the end after drawing the lines, put another PrintString(), and pull out an append
  • pinA: “Last Hit Normal: “ pintB: the StoredHitNormal from the Blocking hit
  • pinC: “; c Up Vector: “ pinD: the CapsuleComponent→GetUpVector()
  • pinE: “; c Gravity Direction: “ pinF: the GetGravityDirection()

you can find your Log file in [ProjectName]/Saved/Logs The first one [ProjectName].Log is the most recent, and these can be opened by any text editor like Notepad, Notepad++, or any text based IDE, and are searchable as these are just raw text files.

and you can post the relevant text of the log into a post here

please remove repeated lines as Tick is per frame, and for “simple” games frame rates might still be rather high

1 Like