Search Unity

Question Any way to achieve a drag effect only horizontally, not vertically?

Discussion in 'Physics' started by dgoyette, Aug 30, 2020.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I use drag on my first person controller to effectively give the player additional friction when on solid surfaces. Without it, even setting friction to max doesn't really provide much resistance to pushing and pulling forces. Drag feels pretty good for this sort of thing. You can imaging the player kind of bracing with their legs to avoid being pushed or pulled.

    The downside to this, however, is that drag is omnidirectional. It doesn't make any physical sense that the player should be able to resist upward forces (such as from an explosion under the player, or something pulling them up). But since drag is omnidirectional, upward force is significantly reduced as well.

    I was wondering if there was some possible way to get drag to work only for the x and z components of the force, but not for the y component. I imagine drag is implemented at a low level, and I can't get in the way of that to override drag to 0 on the y-axis somehow, but maybe someone knows of a clever way to achieve this kind of thing.
     
  2. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    I guess u could just tick Y constraint for the rigid body, have another collider constrained in X and Z, with ignore colliders on for that and your existing one, and just tie that Y to the hidden Y based on whatever happens to the hidden one that you want to propagate (having the chance in between to process whatever, the option to apply it or not etc.)?
     
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Hmm. I'll give that some thought to decide if I can fully make sense of the approach and its side effects. I'm initially hesitant, since in most cases the character should behave like a pretty standard rigidbody, and switching to some kind of dual-body surrogate approach feels like it would just introduce problems. But I'll give it some more thought.
     
    adamgolden likes this.
  4. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    I'd recommend to implement the drag function and apply it to the rigidbody yourself. It could be simply something like dragForce = -coefficent * velocityVector * velocityVector.magnitude (so it's based on the velocity squared in the opposite direction of the velocity). You can then remove the vertical component of the force, so it would be applied horizontally only.
     
    adamgolden and dgoyette like this.
  5. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I'll try that out. I never figured it was an option to create my own drag. For example, if some massive force (like an explosion) hits the player, sending him flying, I would have expected it would be too late to prevent at least one frame of fast movement. But I'll try this and see how it works.
     
    Edy and adamgolden like this.
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Thanks for the idea, @Edy . That simple approach ended up working really well. The call to AddForce uses ForceMode.Velocity, in anyone the future is every looking at doing something similar.

    Anyway, thanks very much. I had never considered it made sense to try to roll my own drag using counter-velocity.
     
    Edy likes this.
  7. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,510
    Cool, good to know :)